ia64/xen-unstable

view tools/python/xen/xend/server/netif.py @ 12888:a4d1f99e5a53

[XEND] Keep vif IP addresses as space separated string.

They were inconsistently represented as strings or lists making it
difficult to know the type of the IP parameter for vifs. Since both xm
and DevController represents these as space separated strings, that is
what it will be stored as.

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Fri Dec 08 13:31:21 2006 +0000 (2006-12-08)
parents 5bed7bc05c8a
children c700f2346f9c
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16 # Copyright (C) 2005 XenSource Ltd
17 #============================================================================
20 """Support for virtual network interfaces.
21 """
23 import os
24 import random
25 import re
27 from xen.xend import XendRoot
28 from xen.xend.server.DevController import DevController
30 xroot = XendRoot.instance()
32 def randomMAC():
33 """Generate a random MAC address.
35 Uses OUI (Organizationally Unique Identifier) 00-16-3E, allocated to
36 Xensource, Inc. The OUI list is available at
37 http://standards.ieee.org/regauth/oui/oui.txt.
39 The remaining 3 fields are random, with the first bit of the first
40 random field set 0.
42 @return: MAC address string
43 """
44 mac = [ 0x00, 0x16, 0x3e,
45 random.randint(0x00, 0x7f),
46 random.randint(0x00, 0xff),
47 random.randint(0x00, 0xff) ]
48 return ':'.join(map(lambda x: "%02x" % x, mac))
50 rate_re = re.compile("^([0-9]+)([GMK]?)([Bb])/s(@([0-9]+)([mu]?)s)?$")
52 def parseRate(ratestr):
53 """if parsing fails this will return default of unlimited rate"""
54 bytes_per_interval = 0xffffffffL # 0xffffffff # big default
55 interval_usecs = 0L # disabled
57 m = rate_re.match(ratestr)
58 if m:
59 bytes_per_sec = long(m.group(1))
61 if m.group(2) == 'G':
62 bytes_per_sec *= 1000 * 1000 * 1000
63 elif m.group(2) == 'M':
64 bytes_per_sec *= 1000 * 1000
65 elif m.group(2) == 'K':
66 bytes_per_sec *= 1000
68 if m.group(3) == 'b':
69 bytes_per_sec /= 8
71 if m.group(5) is None:
72 interval_usecs = 50000L # 50ms default
73 else:
74 interval_usecs = long(m.group(5))
75 if m.group(6) == '':
76 interval_usecs *= 1000 * 1000
77 elif m.group(6) == 'm':
78 interval_usecs *= 1000
80 bytes_per_interval = (bytes_per_sec * interval_usecs) / 1000000L
82 # overflow / underflow checking: default to unlimited rate
83 if bytes_per_interval == 0 or bytes_per_interval > 0xffffffffL or \
84 interval_usecs == 0 or interval_usecs > 0xffffffffL:
85 bytes_per_interval = 0xffffffffL
86 interval_usecs = 0L
88 return "%lu,%lu" % (bytes_per_interval, interval_usecs)
91 write_rate_G_re = re.compile('^([0-9]+)000000000(B/s@[0-9]+us)$')
92 write_rate_M_re = re.compile('^([0-9]+)000000(B/s@[0-9]+us)$')
93 write_rate_K_re = re.compile('^([0-9]+)000(B/s@[0-9]+us)$')
94 write_rate_s_re = re.compile('^([0-9]+[GMK]?B/s@[0-9]+)000000us$')
95 write_rate_m_re = re.compile('^([0-9]+[GMK]?B/s@[0-9]+)000us$')
97 def formatRate(rate):
98 (bytes_per_interval, interval_usecs) = map(long, rate.split(','))
100 if interval_usecs != 0:
101 bytes_per_second = (bytes_per_interval * 1000 * 1000) / interval_usecs
102 else:
103 bytes_per_second = 0xffffffffL
105 ratestr = "%uB/s@%uus" % (bytes_per_second, interval_usecs)
107 # look for '000's
108 m = write_rate_G_re.match(ratestr)
109 if m:
110 ratestr = m.group(1) + "G" + m.group(2)
111 else:
112 m = write_rate_M_re.match(ratestr)
113 if m:
114 ratestr = m.group(1) + "M" + m.group(2)
115 else:
116 m = write_rate_K_re.match(ratestr)
117 if m:
118 ratestr = m.group(1) + "K" + m.group(2)
120 m = write_rate_s_re.match(ratestr)
121 if m:
122 ratestr = m.group(1) + "s"
123 else:
124 m = write_rate_m_re.match(ratestr)
125 if m:
126 ratestr = m.group(1) + "ms"
128 return ratestr
131 class NetifController(DevController):
132 """Network interface controller. Handles all network devices for a domain.
133 """
135 def __init__(self, vm):
136 DevController.__init__(self, vm)
138 def getDeviceDetails(self, config):
139 """@see DevController.getDeviceDetails"""
141 script = os.path.join(xroot.network_script_dir,
142 config.get('script', xroot.get_vif_script()))
143 typ = config.get('type')
144 bridge = config.get('bridge')
145 mac = config.get('mac')
146 vifname = config.get('vifname')
147 rate = config.get('rate')
148 uuid = config.get('uuid')
149 ipaddr = config.get('ip')
151 devid = self.allocateDeviceID()
153 if not mac:
154 mac = randomMAC()
156 back = { 'script' : script,
157 'mac' : mac,
158 'handle' : "%i" % devid }
160 if typ == 'ioemu':
161 front = {}
162 back['type'] = 'ioemu'
163 else:
164 front = { 'handle' : "%i" % devid,
165 'mac' : mac }
166 if ipaddr:
167 back['ip'] = ipaddr
168 if bridge:
169 back['bridge'] = bridge
170 if vifname:
171 back['vifname'] = vifname
172 if rate:
173 back['rate'] = parseRate(rate)
174 if uuid:
175 back['uuid'] = uuid
177 return (devid, back, front)
180 def getDeviceConfiguration(self, devid):
181 """@see DevController.configuration"""
183 result = DevController.getDeviceConfiguration(self, devid)
184 devinfo = self.readBackend(devid, 'script', 'ip', 'bridge',
185 'mac', 'type', 'vifname', 'rate', 'uuid')
186 (script, ip, bridge, mac, typ, vifname, rate, uuid) = devinfo
188 if script:
189 network_script_dir = xroot.network_script_dir + os.sep
190 result['script'] = script.replace(network_script_dir, "")
191 if ip:
192 result['ip'] = ip
193 if bridge:
194 result['bridge'] = bridge
195 if mac:
196 result['mac'] = mac
197 if typ:
198 result['type'] = typ
199 if vifname:
200 result['vifname'] = vifname
201 if rate:
202 result['rate'] = formatRate(rate)
203 if uuid:
204 result['uuid'] = uuid
206 return result