ia64/xen-unstable
changeset 13182:362233086f66
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>
PIF classes.
By Alastair Tse <atse@xensource.com>.
Signed-off-by: Ewan Mellor <ewan@xensource.com>
author | Ewan Mellor <ewan@xensource.com> |
---|---|
date | Mon Dec 25 14:47:36 2006 +0000 (2006-12-25) |
parents | ae3f3dd40df4 |
children | 4fbefd9cb85e |
files | tools/python/xen/xend/XendNetwork.py tools/python/xen/xend/XendPIF.py |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/python/xen/xend/XendNetwork.py Mon Dec 25 14:47:36 2006 +0000 1.3 @@ -0,0 +1,119 @@ 1.4 +#============================================================================ 1.5 +# This library is free software; you can redistribute it and/or 1.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public 1.7 +# License as published by the Free Software Foundation. 1.8 +# 1.9 +# This library is distributed in the hope that it will be useful, 1.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 1.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.12 +# Lesser General Public License for more details. 1.13 +# 1.14 +# You should have received a copy of the GNU Lesser General Public 1.15 +# License along with this library; if not, write to the Free Software 1.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1.17 +#============================================================================ 1.18 +# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> 1.19 +# Copyright (c) 2006 Xensource Inc. 1.20 +#============================================================================ 1.21 + 1.22 +import os 1.23 +import commands 1.24 +import re 1.25 +import struct 1.26 +import socket 1.27 + 1.28 +from xen.xend.XendRoot import instance as xendroot 1.29 + 1.30 +IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)' 1.31 + 1.32 +def linux_get_default_network(): 1.33 + """Returns the network details of the host.""" 1.34 + 1.35 + ip_cmd = '/sbin/ip route' 1.36 + rc, output = commands.getstatusoutput(ip_cmd) 1.37 + default_route = None 1.38 + default_dev = None 1.39 + default_netmask = None 1.40 + if rc == 0: 1.41 + # find default route/device 1.42 + for line in output.split('\n'): 1.43 + is_default = re.search(IP_ROUTE_RE, line) 1.44 + if is_default: 1.45 + default_route = is_default.group(1) 1.46 + default_dev = is_default.group(2) 1.47 + 1.48 + # find network address and network mask 1.49 + if default_dev: 1.50 + dev_re = r'^([\d\.]+)/(\d+) dev %s' % default_dev 1.51 + for line in output.split('\n'): 1.52 + is_dev = re.search(dev_re, line) 1.53 + if is_dev: 1.54 + # convert integer netmask to string representation 1.55 + netmask = 0xffffffff ^ (2**(32-int(is_dev.group(2))) - 1) 1.56 + packed = struct.pack('!I', netmask) 1.57 + default_netmask = socket.inet_ntoa(packed) 1.58 + 1.59 + return (default_route, default_netmask) 1.60 + 1.61 + 1.62 +class XendNetwork: 1.63 + def __init__(self, uuid, name, description, gateway, netmask): 1.64 + self.uuid = uuid 1.65 + self.name_label = name 1.66 + self.name_description = description 1.67 + self.default_gateway = gateway 1.68 + self.default_netmask = netmask 1.69 + self.vifs = {} 1.70 + self.pifs = {} 1.71 + 1.72 + def get_name_label(self): 1.73 + return self.name_label 1.74 + 1.75 + def set_name_label(self, new_name): 1.76 + self.name_label = new_name 1.77 + 1.78 + def get_name_description(self): 1.79 + return self.name_description 1.80 + 1.81 + def set_name_description(self, new_desc): 1.82 + self.name_description = new_desc 1.83 + 1.84 + def get_default_gateway(self): 1.85 + return self.default_gateway 1.86 + 1.87 + def set_default_gateway(self, new_gateway): 1.88 + if re.search('^\d+\.\d+\.\d+\.\d+$', new_gateway): 1.89 + self.default_gateway = new_gateway 1.90 + 1.91 + def get_default_netmask(self): 1.92 + return self.default_netmask 1.93 + 1.94 + def set_default_netmask(self, new_netmask): 1.95 + if re.search('^\d+\.\d+\.\d+\.\d+$', new_netmask): 1.96 + self.default_netmask = new_netmask 1.97 + 1.98 + def add_pif(self, pif): 1.99 + self.pifs[pif.get_uuid()] = pif 1.100 + 1.101 + def remove_pif(self, pif_uuid): 1.102 + if pif_uuid in self.pifs: 1.103 + del self.pifs[pif_uuid] 1.104 + 1.105 + def add_vif(self, vif): 1.106 + self.vifs[vif.get_uuid()] = vif 1.107 + 1.108 + def remove_vif(self, vif_uuid): 1.109 + if vif_uuid in self.vifs: 1.110 + del self.vifs[vif_uuid] 1.111 + 1.112 + def get_record(self): 1.113 + return { 1.114 + 'uuid': self.uuid, 1.115 + 'name_label': self.name_label, 1.116 + 'name_description': self.name_description, 1.117 + 'default_gateway': self.default_gateway, 1.118 + 'default_netmask': self.default_netmask, 1.119 + 'VIFs': self.vifs.keys(), 1.120 + 'PIFs': self.pifs.keys() 1.121 + } 1.122 +
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/tools/python/xen/xend/XendPIF.py Mon Dec 25 14:47:36 2006 +0000 2.3 @@ -0,0 +1,157 @@ 2.4 +#============================================================================ 2.5 +# This library is free software; you can redistribute it and/or 2.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public 2.7 +# License as published by the Free Software Foundation. 2.8 +# 2.9 +# This library is distributed in the hope that it will be useful, 2.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 2.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 2.12 +# Lesser General Public License for more details. 2.13 +# 2.14 +# You should have received a copy of the GNU Lesser General Public 2.15 +# License along with this library; if not, write to the Free Software 2.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2.17 +#============================================================================ 2.18 +# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> 2.19 +# Copyright (c) 2006 Xensource Inc. 2.20 +#============================================================================ 2.21 + 2.22 +import os 2.23 +import commands 2.24 +import re 2.25 +import socket 2.26 + 2.27 +from xen.xend.XendRoot import instance as xendroot 2.28 +from xen.xend.XendLogging import log 2.29 + 2.30 +MAC_RE = ':'.join(['[0-9a-f]{2}'] * 6) 2.31 +IP_IFACE_RE = r'^\d+: (\w+):.*mtu (\d+) .* link/\w+ ([0-9a-f:]+)' 2.32 + 2.33 +def linux_phy_to_virt(pif_name): 2.34 + return 'eth' + re.sub(r'^[a-z]+', '', pif_name) 2.35 + 2.36 +def linux_get_phy_ifaces(): 2.37 + """Returns a list of physical interfaces. 2.38 + 2.39 + Identifies PIFs as those that have a interface name starting with 'p' 2.40 + and have the fake 'fe:ff:ff:ff:ff:ff' MAC address. 2.41 + 2.42 + See /etc/xen/scripts/network-bridge for how the devices are renamed. 2.43 + 2.44 + @rtype: array of 3-element tuple (name, mtu, mac) 2.45 + """ 2.46 + 2.47 + ip_cmd = '/sbin/ip -o link show' 2.48 + rc, output = commands.getstatusoutput(ip_cmd) 2.49 + ifaces = {} 2.50 + phy_ifaces = [] 2.51 + if rc == 0: 2.52 + # parse all interfaces into (name, mtu, mac) 2.53 + for line in output.split('\n'): 2.54 + has_if = re.search(IP_IFACE_RE, line) 2.55 + if has_if: 2.56 + ifaces[has_if.group(1)] = has_if.groups() 2.57 + 2.58 + # resolve pifs' mac addresses 2.59 + for name, mtu, mac in ifaces.values(): 2.60 + if name[0] == 'p' and mac == 'fe:ff:ff:ff:ff:ff': 2.61 + bridged_ifname = linux_phy_to_virt(name) 2.62 + bridged_if = ifaces.get(bridged_ifname) 2.63 + if bridged_if: 2.64 + bridged_mac = bridged_if[2] 2.65 + phy_ifaces.append((name, int(mtu), bridged_mac)) 2.66 + 2.67 + return phy_ifaces 2.68 + 2.69 +def linux_set_mac(iface, mac): 2.70 + if not re.search(MAC_RE, mac): 2.71 + return False 2.72 + 2.73 + ip_mac_cmd = '/sbin/ip link set %s addr %s' % \ 2.74 + (linux_phy_to_virt(iface), mac) 2.75 + rc, output = commands.getstatusoutput(ip_mac_cmd) 2.76 + if rc == 0: 2.77 + return True 2.78 + 2.79 + return False 2.80 + 2.81 +def linux_set_mtu(iface, mtu): 2.82 + try: 2.83 + ip_mtu_cmd = '/sbin/ip link set %s mtu %d' % \ 2.84 + (linux_phy_to_virt(iface), int(mtu)) 2.85 + rc, output = commands.getstatusoutput(ip_mtu_cmd) 2.86 + if rc == 0: 2.87 + return True 2.88 + return False 2.89 + except ValueError: 2.90 + return False 2.91 + 2.92 +def same_dir_rename(old_path, new_path): 2.93 + """Ensure that the old_path and new_path refer to files in the same 2.94 + directory.""" 2.95 + old_abs = os.path.normpath(old_path) 2.96 + new_abs = os.path.normpath(new_path) 2.97 + if os.path.dirname(old_abs) == os.path.dirname(new_abs): 2.98 + os.rename(old_abs, new_abs) 2.99 + else: 2.100 + log.warning("Unable to ensure name is new name is safe: %s" % new_abs) 2.101 + 2.102 + 2.103 +class XendPIF: 2.104 + """Representation of a Physical Network Interface.""" 2.105 + 2.106 + def __init__(self, uuid, name, mtu, mac): 2.107 + self.uuid = uuid 2.108 + self.name = name 2.109 + self.mac = mac 2.110 + self.mtu = mtu 2.111 + self.vlan = '' 2.112 + self.network = None 2.113 + 2.114 + def set_name(self, new_name): 2.115 + self.name = new_name 2.116 + 2.117 + def get_name(self): 2.118 + return self.name 2.119 + 2.120 + def get_uuid(self): 2.121 + return self.uuid 2.122 + 2.123 + def get_mac(self): 2.124 + return self.mac 2.125 + 2.126 + def get_vlan(self): 2.127 + return self.vlan 2.128 + 2.129 + def set_mac(self, new_mac): 2.130 + success = linux_set_mac(new_mac) 2.131 + if success: 2.132 + self.mac = new_mac 2.133 + return success 2.134 + 2.135 + def set_mtu(self, new_mtu): 2.136 + success = linux_set_mtu(new_mtu) 2.137 + if success: 2.138 + self.mtu = new_mtu 2.139 + return success 2.140 + 2.141 + def get_io_read_kbs(self): 2.142 + return 0.0 2.143 + 2.144 + def get_io_write_kbs(self): 2.145 + return 0.0 2.146 + 2.147 + def get_record(self): 2.148 + if self.network: 2.149 + network_uuid = self.network.get_uuid() 2.150 + else: 2.151 + network_uuid = None 2.152 + 2.153 + return {'name': self.name, 2.154 + 'MAC': self.mac, 2.155 + 'MTU': self.mtu, 2.156 + 'VLAN': self.vlan, 2.157 + 'network': network_uuid, 2.158 + 'io_read_kbs': self.get_io_read_kbs(), 2.159 + 'io_write_kbs': self.get_io_write_kbs()} 2.160 +