ia64/xen-unstable

view tools/python/xen/xend/server/netif.py @ 17578:94c6501c4ffe

xend: Refactor security.on() call

I am refactoring the security.on() call to return the actual type of
the security module that is found to be enabled rather than just
returning True or False.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue May 06 10:05:52 2008 +0100 (2008-05-06)
parents 09d8b6eb3131
children 5b133625223a
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 XendOptions
28 from xen.xend.server.DevController import DevController
29 from xen.xend.XendError import VmError
30 from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
31 import xen.util.xsm.xsm as security
32 from xen.util import xsconstants
34 from xen.xend.XendLogging import log
36 xoptions = XendOptions.instance()
38 def randomMAC():
39 """Generate a random MAC address.
41 Uses OUI (Organizationally Unique Identifier) 00-16-3E, allocated to
42 Xensource, Inc. The OUI list is available at
43 http://standards.ieee.org/regauth/oui/oui.txt.
45 The remaining 3 fields are random, with the first bit of the first
46 random field set 0.
48 @return: MAC address string
49 """
50 mac = [ 0x00, 0x16, 0x3e,
51 random.randint(0x00, 0x7f),
52 random.randint(0x00, 0xff),
53 random.randint(0x00, 0xff) ]
54 return ':'.join(map(lambda x: "%02x" % x, mac))
56 rate_re = re.compile("^([0-9]+)([GMK]?)([Bb])/s(@([0-9]+)([mu]?)s)?$")
58 def parseRate(ratestr):
59 """if parsing fails this will return default of unlimited rate"""
60 bytes_per_interval = 0xffffffffL # 0xffffffff # big default
61 interval_usecs = 0L # disabled
63 m = rate_re.match(ratestr)
64 if m:
65 bytes_per_sec = long(m.group(1))
67 if m.group(2) == 'G':
68 bytes_per_sec *= 1000 * 1000 * 1000
69 elif m.group(2) == 'M':
70 bytes_per_sec *= 1000 * 1000
71 elif m.group(2) == 'K':
72 bytes_per_sec *= 1000
74 if m.group(3) == 'b':
75 bytes_per_sec /= 8
77 if m.group(5) is None:
78 interval_usecs = 50000L # 50ms default
79 else:
80 interval_usecs = long(m.group(5))
81 if m.group(6) == '':
82 interval_usecs *= 1000 * 1000
83 elif m.group(6) == 'm':
84 interval_usecs *= 1000
86 bytes_per_interval = (bytes_per_sec * interval_usecs) / 1000000L
88 # overflow / underflow checking: default to unlimited rate
89 if bytes_per_interval == 0 or bytes_per_interval > 0xffffffffL or \
90 interval_usecs == 0 or interval_usecs > 0xffffffffL:
91 bytes_per_interval = 0xffffffffL
92 interval_usecs = 0L
94 return "%lu,%lu" % (bytes_per_interval, interval_usecs)
97 class NetifController(DevController):
98 """Network interface controller. Handles all network devices for a domain.
99 """
101 def __init__(self, vm):
102 DevController.__init__(self, vm)
104 def getDeviceDetails(self, config):
105 """@see DevController.getDeviceDetails"""
107 script = config.get('script', xoptions.get_vif_script())
108 typ = config.get('type')
109 bridge = config.get('bridge')
110 mac = config.get('mac')
111 vifname = config.get('vifname')
112 rate = config.get('rate')
113 uuid = config.get('uuid')
114 ipaddr = config.get('ip')
115 model = config.get('model')
116 accel = config.get('accel')
117 sec_lab = config.get('security_label')
119 if not mac:
120 raise VmError("MAC address not specified or generated.")
122 devid = self.allocateDeviceID()
124 back = { 'script' : script,
125 'mac' : mac }
126 if typ:
127 back['type'] = typ
128 if ipaddr:
129 back['ip'] = ipaddr
130 if bridge:
131 back['bridge'] = bridge
132 if vifname:
133 back['vifname'] = vifname
134 if rate:
135 back['rate'] = rate
136 if uuid:
137 back['uuid'] = uuid
138 if model:
139 back['model'] = model
140 if accel:
141 back['accel'] = accel
142 if sec_lab:
143 back['security_label'] = sec_lab
145 config_path = "device/%s/%d/" % (self.deviceClass, devid)
146 for x in back:
147 self.vm._writeVm(config_path + x, back[x])
149 back['handle'] = "%i" % devid
150 back['script'] = os.path.join(xoptions.network_script_dir, script)
151 if rate:
152 back['rate'] = parseRate(rate)
154 front = {}
155 if typ != 'ioemu':
156 front = { 'handle' : "%i" % devid,
157 'mac' : mac }
159 if security.on() == xsconstants.XS_POLICY_ACM:
160 self.do_access_control(config)
162 return (devid, back, front)
165 def do_access_control(self, config):
166 """ do access control checking. Throws a VMError if access is denied """
167 domain_label = self.vm.get_security_label()
168 stes = XSPolicyAdminInstance().get_stes_of_vmlabel(domain_label)
169 res_label = config.get('security_label')
170 if len(stes) > 1 or res_label:
171 if not res_label:
172 raise VmError("'VIF' must be labeled")
173 (label, ssidref, policy) = \
174 security.security_label_to_details(res_label)
175 if domain_label:
176 rc = security.res_security_check_xapi(label, ssidref,
177 policy,
178 domain_label)
179 if rc == 0:
180 raise VmError("VM's access to network device denied. "
181 "Check labeling")
182 else:
183 raise VmError("VM must have a security label to access "
184 "network device")
187 def getDeviceConfiguration(self, devid, transaction = None):
188 """@see DevController.configuration"""
190 result = DevController.getDeviceConfiguration(self, devid, transaction)
192 config_path = "device/%s/%d/" % (self.deviceClass, devid)
193 devinfo = ()
194 for x in ( 'script', 'ip', 'bridge', 'mac',
195 'type', 'vifname', 'rate', 'uuid', 'model', 'accel',
196 'security_label'):
197 if transaction is None:
198 y = self.vm._readVm(config_path + x)
199 else:
200 y = self.vm._readVmTxn(transaction, config_path + x)
201 devinfo += (y,)
202 (script, ip, bridge, mac, typ, vifname, rate, uuid,
203 model, accel, security_label) = devinfo
205 if script:
206 result['script'] = script
207 if ip:
208 result['ip'] = ip
209 if bridge:
210 result['bridge'] = bridge
211 if mac:
212 result['mac'] = mac
213 if typ:
214 result['type'] = typ
215 if vifname:
216 result['vifname'] = vifname
217 if rate:
218 result['rate'] = rate
219 if uuid:
220 result['uuid'] = uuid
221 if model:
222 result['model'] = model
223 if accel:
224 result['accel'] = accel
225 if security_label:
226 result['security_label'] = security_label
228 return result