New XendNetwork and XendPIF classes, for implementing the Xen-API network and

PIF classes.

By Alastair Tse <atse@xensource.com>.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
This commit is contained in:
Ewan Mellor committed 2006-12-25 14:47:36 +00:00
1 parent 3e9ef3ef0a
commit d9510a25ab
2 files changed
+276

No files matched your search

+119
View File
@@ -0,0 +1,119 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (c) 2006 Xensource Inc.
#============================================================================
import os
import commands
import re
import struct
import socket
from xen.xend.XendRoot import instance as xendroot
IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)'
def linux_get_default_network():
"""Returns the network details of the host."""
ip_cmd = '/sbin/ip route'
rc, output = commands.getstatusoutput(ip_cmd)
default_route = None
default_dev = None
default_netmask = None
if rc == 0:
# find default route/device
for line in output.split('\n'):
is_default = re.search(IP_ROUTE_RE, line)
if is_default:
default_route = is_default.group(1)
default_dev = is_default.group(2)
# find network address and network mask
if default_dev:
dev_re = r'^([\d\.]+)/(\d+) dev %s' % default_dev
for line in output.split('\n'):
is_dev = re.search(dev_re, line)
if is_dev:
# convert integer netmask to string representation
netmask = 0xffffffff ^ (2**(32-int(is_dev.group(2))) - 1)
packed = struct.pack('!I', netmask)
default_netmask = socket.inet_ntoa(packed)
return (default_route, default_netmask)
class XendNetwork:
def __init__(self, uuid, name, description, gateway, netmask):
self.uuid = uuid
self.name_label = name
self.name_description = description
self.default_gateway = gateway
self.default_netmask = netmask
self.vifs = {}
self.pifs = {}
def get_name_label(self):
return self.name_label
def set_name_label(self, new_name):
self.name_label = new_name
def get_name_description(self):
return self.name_description
def set_name_description(self, new_desc):
self.name_description = new_desc
def get_default_gateway(self):
return self.default_gateway
def set_default_gateway(self, new_gateway):
if re.search('^\d+\.\d+\.\d+\.\d+$', new_gateway):
self.default_gateway = new_gateway
def get_default_netmask(self):
return self.default_netmask
def set_default_netmask(self, new_netmask):
if re.search('^\d+\.\d+\.\d+\.\d+$', new_netmask):
self.default_netmask = new_netmask
def add_pif(self, pif):
self.pifs[pif.get_uuid()] = pif
def remove_pif(self, pif_uuid):
if pif_uuid in self.pifs:
del self.pifs[pif_uuid]
def add_vif(self, vif):
self.vifs[vif.get_uuid()] = vif
def remove_vif(self, vif_uuid):
if vif_uuid in self.vifs:
del self.vifs[vif_uuid]
def get_record(self):
return {
'uuid': self.uuid,
'name_label': self.name_label,
'name_description': self.name_description,
'default_gateway': self.default_gateway,
'default_netmask': self.default_netmask,
'VIFs': self.vifs.keys(),
'PIFs': self.pifs.keys()
}
+157
View File
@@ -0,0 +1,157 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (c) 2006 Xensource Inc.
#============================================================================
import os
import commands
import re
import socket
from xen.xend.XendRoot import instance as xendroot
from xen.xend.XendLogging import log
MAC_RE = ':'.join(['[0-9a-f]{2}'] * 6)
IP_IFACE_RE = r'^\d+: (\w+):.*mtu (\d+) .* link/\w+ ([0-9a-f:]+)'
def linux_phy_to_virt(pif_name):
return 'eth' + re.sub(r'^[a-z]+', '', pif_name)
def linux_get_phy_ifaces():
"""Returns a list of physical interfaces.
Identifies PIFs as those that have a interface name starting with 'p'
and have the fake 'fe:ff:ff:ff:ff:ff' MAC address.
See /etc/xen/scripts/network-bridge for how the devices are renamed.
@rtype: array of 3-element tuple (name, mtu, mac)
"""
ip_cmd = '/sbin/ip -o link show'
rc, output = commands.getstatusoutput(ip_cmd)
ifaces = {}
phy_ifaces = []
if rc == 0:
# parse all interfaces into (name, mtu, mac)
for line in output.split('\n'):
has_if = re.search(IP_IFACE_RE, line)
if has_if:
ifaces[has_if.group(1)] = has_if.groups()
# resolve pifs' mac addresses
for name, mtu, mac in ifaces.values():
if name[0] == 'p' and mac == 'fe:ff:ff:ff:ff:ff':
bridged_ifname = linux_phy_to_virt(name)
bridged_if = ifaces.get(bridged_ifname)
if bridged_if:
bridged_mac = bridged_if[2]
phy_ifaces.append((name, int(mtu), bridged_mac))
return phy_ifaces
def linux_set_mac(iface, mac):
if not re.search(MAC_RE, mac):
return False
ip_mac_cmd = '/sbin/ip link set %s addr %s' % \
(linux_phy_to_virt(iface), mac)
rc, output = commands.getstatusoutput(ip_mac_cmd)
if rc == 0:
return True
return False
def linux_set_mtu(iface, mtu):
try:
ip_mtu_cmd = '/sbin/ip link set %s mtu %d' % \
(linux_phy_to_virt(iface), int(mtu))
rc, output = commands.getstatusoutput(ip_mtu_cmd)
if rc == 0:
return True
return False
except ValueError:
return False
def same_dir_rename(old_path, new_path):
"""Ensure that the old_path and new_path refer to files in the same
directory."""
old_abs = os.path.normpath(old_path)
new_abs = os.path.normpath(new_path)
if os.path.dirname(old_abs) == os.path.dirname(new_abs):
os.rename(old_abs, new_abs)
else:
log.warning("Unable to ensure name is new name is safe: %s" % new_abs)
class XendPIF:
"""Representation of a Physical Network Interface."""
def __init__(self, uuid, name, mtu, mac):
self.uuid = uuid
self.name = name
self.mac = mac
self.mtu = mtu
self.vlan = ''
self.network = None
def set_name(self, new_name):
self.name = new_name
def get_name(self):
return self.name
def get_uuid(self):
return self.uuid
def get_mac(self):
return self.mac
def get_vlan(self):
return self.vlan
def set_mac(self, new_mac):
success = linux_set_mac(new_mac)
if success:
self.mac = new_mac
return success
def set_mtu(self, new_mtu):
success = linux_set_mtu(new_mtu)
if success:
self.mtu = new_mtu
return success
def get_io_read_kbs(self):
return 0.0
def get_io_write_kbs(self):
return 0.0
def get_record(self):
if self.network:
network_uuid = self.network.get_uuid()
else:
network_uuid = None
return {'name': self.name,
'MAC': self.mac,
'MTU': self.mtu,
'VLAN': self.vlan,
'network': network_uuid,
'io_read_kbs': self.get_io_read_kbs(),
'io_write_kbs': self.get_io_write_kbs()}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.