diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/xen/Makefile | 2 | ||||
-rw-r--r-- | tools/xen/lib/util/Brctl.py (renamed from tools/xen/lib/xend/XendBridge.py) | 50 | ||||
-rw-r--r-- | tools/xen/lib/xend/Vifctl.py | 28 | ||||
-rw-r--r-- | tools/xen/lib/xend/XendDomainInfo.py | 4 | ||||
-rw-r--r-- | tools/xen/lib/xend/server/SrvServer.py | 5 | ||||
-rwxr-xr-x | tools/xen/lib/xend/server/netif.py | 30 | ||||
-rw-r--r-- | tools/xen/vifctl | 148 |
7 files changed, 211 insertions, 56 deletions
diff --git a/tools/xen/Makefile b/tools/xen/Makefile index 642cd2273e..8732a30932 100644 --- a/tools/xen/Makefile +++ b/tools/xen/Makefile @@ -14,6 +14,8 @@ install: all install -m0755 xend $(prefix)/usr/sbin install -m0755 netfix $(prefix)/usr/sbin install -m0755 xm $(prefix)/usr/sbin + mkdir -p $(prefix)/etc/xen/xend + install -m0755 vifctl $(prefix)/etc/xen/xend clean: rm -rf build *.pyc *.pyo *.o *.a *~ diff --git a/tools/xen/lib/xend/XendBridge.py b/tools/xen/lib/util/Brctl.py index f1584552de..32dd16bf81 100644 --- a/tools/xen/lib/xend/XendBridge.py +++ b/tools/xen/lib/util/Brctl.py @@ -5,18 +5,12 @@ import os.path import re import sys -from xen.xend import XendRoot -xroot = XendRoot.instance() - os.defpath = os.defpath + ':/sbin:/usr/sbin:/usr/local/sbin' CMD_IFCONFIG = 'ifconfig' CMD_ROUTE = 'route' CMD_BRCTL = 'brctl' CMD_IPTABLES = "iptables" -DEFAULT_BRIDGE = 'nbe-br' -DEFAULT_INTERFACE = 'eth0' - opts = None class Opts: @@ -35,35 +29,19 @@ def cmd(p, s): if not opts.dryrun: os.system(c) -def default_bridge(): - return xroot.get_config_value('bridge', DEFAULT_BRIDGE) - -def default_interface(): - return xroot.get_config_value('interface', DEFAULT_INTERFACE) - -def vif_dev(dom, vif): - """Return the name of the network interface for vif on domain dom. - """ - return "vif%d.%d" % (dom, vif) - -def vif_bridge_add(dom, vif, bridge=None): +def vif_bridge_add(params): """Add the network interface for vif on dom to a bridge. """ - if not bridge: bridge = default_bridge() - d = { 'bridge': bridge, 'vif': vif_dev(dom, vif) } - cmd(CMD_BRCTL, 'addif %(bridge)s %(vif)s' % d) + cmd(CMD_BRCTL, 'addif %(bridge)s %(vif)s' % params) return bridge -def vif_bridge_rem(dom, vif, bridge=None): +def vif_bridge_rem(params): """Remove the network interface for vif on dom from a bridge. """ - if not bridge: bridge = default_bridge() - print 'vif_bridge_rem>', dom, vif, bridge - d = { 'bridge': bridge, 'vif': vif_dev(dom, vif) } - cmd(CMD_BRCTL, 'delif %(bridge)s %(vif)s' % d) + cmd(CMD_BRCTL, 'delif %(bridge)s %(vif)s' % params) -def vif_restrict_addr(dom, vif, addr, delete=0): - d = { 'vif': vif_dev(dom, vif), 'addr': addr} +def vif_restrict_addr(vif, addr, delete=0): + d = { 'vif': vif, 'addr': addr} if delete: d['flag'] = '-D' else: @@ -72,11 +50,10 @@ def vif_restrict_addr(dom, vif, addr, delete=0): cmd(CMD_IPTABLES, '%(flag)s FORWARD -m physdev --physdev-in %(vif)s -s %(addr)s -j ACCEPT' % d) cmd(CMD_IPTABLES, '%(flag)s FORWARD -m physdev --physdev-out %(vif)s -d %(addr)s -j ACCEPT' % d) -def bridge_create(bridge=None, **kwd): +def bridge_create(bridge, **kwd): """Create a bridge. Defaults hello time to 0, forward delay to 0 and stp off. """ - if not bridge: bridge = default_bridge() cmd(CMD_BRCTL, 'addbr %s' % bridge) if kwd.get('hello', None) is None: kwd['hello'] = 0 @@ -96,10 +73,9 @@ def bridge_set(bridge, hello=None, fd=None, stp=None): if stp is not None: cmd(CMD_BRCTL, 'stp %s %s' % (bridge, stp)) -def bridge_del(bridge=None): +def bridge_del(bridge): """Delete a bridge. """ - if not bridge: bridge = default_bridge() cmd(CMD_BRCTL, 'delbr %s' % bridge) def routes(): @@ -137,22 +113,17 @@ def ifconfig(interface): break return info -def reconfigure(interface=None, bridge=None): +def reconfigure(interface, bridge): """Reconfigure an interface to be attached to a bridge, and give the bridge the IP address etc. from interface. Move the default route to the interface to the bridge. - If opts.create is true, creates the bridge. """ global opts - if not interface: interface = default_interface() - if not bridge: bridge = default_bridge() intf_info = ifconfig(interface) if not intf_info: print 'Interface not found:', interface return - if opts.create: - bridge_create(bridge) #bridge_info = ifconfig(bridge) #if not bridge_info: # print 'Bridge not found:', bridge @@ -178,11 +149,8 @@ def reconfigure(interface=None, bridge=None): cmd(CMD_IFCONFIG, '%(interface)s 0.0.0.0' % intf_info) defaults = { - 'interface': default_interface(), - 'bridge' : default_bridge(), 'verbose' : 1, 'dryrun' : 0, - 'create' : 0, } opts = Opts(defaults) diff --git a/tools/xen/lib/xend/Vifctl.py b/tools/xen/lib/xend/Vifctl.py new file mode 100644 index 0000000000..49df8f6bd0 --- /dev/null +++ b/tools/xen/lib/xend/Vifctl.py @@ -0,0 +1,28 @@ +import os +import os.path +import sys + +VIFCTL = '/etc/xen/xend/vifctl' + +def init(): + os.system(VIFCTL + ' init ') + +def up(vif, mac=None, bridge=None, ipaddr=[]): + args = ['vif=%s' % vif] + if mac: + args.append('mac=%s' % mac) + if bridge: + args.append('bridge=%s' % bridge) + if ipaddr: + args.append('ipaddr=%s' % ','.join(ipaddr)) + os.system(VIFCTL + ' up ' + ' '.join(args)) + +def down(vif, mac=None, bridge=None, ipaddr=[]): + args = ['vif=%s' % vif] + if mac: + args.append('mac=%s' % mac) + if bridge: + args.append('bridge=%s' % bridge) + if ipaddr: + args.append('ipaddr=%s' % ','.join(ipaddr)) + os.system(VIFCTL + ' down ' + ' '.join(args)) diff --git a/tools/xen/lib/xend/XendDomainInfo.py b/tools/xen/lib/xend/XendDomainInfo.py index c17109c85a..50fcf26fe2 100644 --- a/tools/xen/lib/xend/XendDomainInfo.py +++ b/tools/xen/lib/xend/XendDomainInfo.py @@ -24,8 +24,6 @@ import sxp import XendConsole xendConsole = XendConsole.instance() -import XendBridge - import server.SrvDaemon xend = server.SrvDaemon.instance() @@ -765,7 +763,7 @@ def vm_dev_vif(vm, val, index): if devid: dev.setprop('id', devid) bridge = sxp.child_value(val, "bridge") - dev.bridge_add(bridge) + dev.up(bridge) vm.add_device('vif', dev) print 'vm_dev_vif> created', dev return id diff --git a/tools/xen/lib/xend/server/SrvServer.py b/tools/xen/lib/xend/server/SrvServer.py index 6535ad3f37..ac201dd10d 100644 --- a/tools/xen/lib/xend/server/SrvServer.py +++ b/tools/xen/lib/xend/server/SrvServer.py @@ -32,7 +32,7 @@ from twisted.internet import reactor from xen.xend import XendRoot xroot = XendRoot.instance() -from xen.xend import XendBridge +from xen.xend import Vifctl from SrvRoot import SrvRoot @@ -48,8 +48,7 @@ def create(port=None, interface=None, bridge=0): reactor.listenTCP(port, site, interface=interface) def init_bridge(): - XendBridge.bridge_create() - XendBridge.reconfigure() + Vifctl.init() def main(port=None, interface=None): create(port, interface) diff --git a/tools/xen/lib/xend/server/netif.py b/tools/xen/lib/xend/server/netif.py index 01391f7b5f..2b01805be6 100755 --- a/tools/xen/lib/xend/server/netif.py +++ b/tools/xen/lib/xend/server/netif.py @@ -4,7 +4,7 @@ from twisted.internet import defer from xen.xend import sxp from xen.xend import PrettyPrint -from xen.xend import XendBridge +from xen.xend import Vifctl import channel import controller @@ -115,10 +115,11 @@ class NetDev(controller.Dev): self.mac = mac self.evtchn = None self.bridge = None + self.ipaddr = [] def sxpr(self): vif = str(self.vif) - mac = ':'.join(map(lambda x: "%x" % x, self.mac)) + mac = self.get_mac() val = ['netdev', ['vif', vif], ['mac', mac]] if self.bridge: val.append(['bridge', self.bridge]) @@ -128,20 +129,31 @@ class NetDev(controller.Dev): self.evtchn['port2']]) return val - def bridge_add(self, bridge): - self.bridge = XendBridge.vif_bridge_add(self.controller.dom, self.vif, bridge) + def get_vifname(self): + return "vif%d.%d" % (self.controller.dom, self.vif) - def bridge_rem(self): - if not self.bridge: return - XendBridge.vif_bridge_rem(self.controller.dom, self.vif, self.bridge) - self.bridge = None + def get_mac(self): + return ':'.join(map(lambda x: "%x" % x, self.mac)) + + def vifctl_params(self): + return { 'mac' : self.get_mac(), + 'bridge': self.bridge, + 'ipaddr': self.ipaddr } + + def up(self, bridge=None, ipaddr=[]): + self.bridge = bridge + self.ipaddr = ipaddr + Vifctl.up(self.get_vifname(), **self.vifctl_params()) + + def down(self): + Vifctl.down(self.get_vifname(), **self.vifctl_params()) def destroy(self): def cb_destroy(val): self.controller.send_be_destroy(self.vif) print 'NetDev>destroy>', 'vif=', self.vif PrettyPrint.prettyprint(self.sxpr()) - self.bridge_rem() + self.down() d = self.controller.factory.addDeferred() d.addCallback(cb_destroy) self.controller.send_be_disconnect(self.vif) diff --git a/tools/xen/vifctl b/tools/xen/vifctl new file mode 100644 index 0000000000..095dc987f4 --- /dev/null +++ b/tools/xen/vifctl @@ -0,0 +1,148 @@ +#!/usr/bin/python +# -*- mode: python; -*- +#============================================================================ +# Xen vif control script. +# +# vifctl init [bridge=<bridge>] [interface=<interface>] +# +# Called when xend starts up. Default behaviour is to create <bridge> +# and add <interface> to it, moving its IP address to <bridge> and adjusting routes. +# +# vifctl (up|down) vif=<vif> mac=<mac> [bridge=<bridge>] (ipaddr=<ipaddr>)* +# +# Called when a vif is brought up or down. Default behaviour is to add +# the vif to <bridge> on up and remove it from the bridge on down. +# If ipaddr is specified, iptables rules for the ip addresses are +# added on up and removed on down. The bridge a vif is added to can +# be set in the vm config. +# +# The default bridge is nbe-br. +# The default interface is eth0. +# +#============================================================================ + +import sys +import types + +from xen.util import Brctl + +from xen.xend import XendRoot +xroot = XendRoot.instance() + +class VifControl: + + prefix = 'vifctl_' + + DEFAULT_BRIDGE = 'nbe-br' + DEFAULT_INTERFACE = 'eth0' + + def __init__(self): + self.name = 'vifctl' + + def main(self, args): + if len(args) < 2: + usage(args) + self.name = args[0] + cmd = self.prefix + args[1] + meth = getattr(self, cmd, self.unknown) + meth(args[1:]) + + def usage(self, args, out=sys.stderr): + print >>out, 'Missing command, try \n%s help' % self.name + + def unknown(self, args, out=sys.stderr): + print >>out, 'Unknown command:', args[1] + self.help(out=out) + sys.exit(1) + + def help(self, out=sys.stdout): + print >>out, 'Commands are:', + for x in vars(self): + if x.startswith(prefix): + cmd = x[len(prefix):] + print >>out, cmd, + print >>out + + def getparams(self, d, args, req=[]): + """Parse args of the form 'key=val'. Valid keys are the ones + in the dict 'd' passed in. If entries in 'd' have list values the + values of the keys are appended. + + If 'req' is specified it is a list of required keys. + """ + for x in args: + (k, v) = x.split('=') + k = k.strip() + v = v.strip() + if k not in d: + print >>sys.stderr, 'Invalid parameter: ', k + sys.exit(1) + vold = d[k] + if isinstance(vold , types.ListType): + d[k] = vold + v + else: + d[k] = v + for x in req: + if not d[x]: + print >>sys.stderr, 'Missing parameter:', x + sys.exit(1) + return d + + def vifctl_help(self, args): + self.help() + + def default_bridge(self): + return xroot.get_config_value('bridge', self.DEFAULT_BRIDGE) + + def default_interface(self): + return xroot.get_config_value('interface', self.DEFAULT_INTERFACE) + + def vifctl_init(self, args): + """Entry point for 'vifctl init'. + """ + d = { 'bridge' : self.default_bridge(), + 'interface': self.default_interface() } + params = self.getparams(d, args[1:]) + interface = params['interface'] + bridge = params['bridge'] + # Create bridge 'bridge'. + Brctl.bridge_create(bridge) + # Reconfigure so that 'interface' is added to 'bridge', + # and 'bridge' has the IP address from 'interface'. + Brctl.reconfigure(interface, bridge) + + def vifparams(self, args): + d = { 'vif' : None, + 'mac' : None, + 'bridge': self.default_bridge(), + 'ipaddr': [] } + d = self.getparams(d, args, req=['vif', 'mac']) + return d + + def vifctl_up(self, args): + """Entry point for 'vifctl up'. + """ + params = self.vifparams(args[1:]) + # Add the vif to its bridge. + Brctl.vif_bridge_add(params) + if params['ipaddr']: + # Add iptables rules for the ip addresses. + vif = params['vif'] + for ipaddr in params['ipaddr']: + Brctl.vif_restrict_addr(vif, ipaddr) + + def vifctl_down(self, args): + """Entry point for 'vifctl down'. + """ + params = self.vifparams(args[1:]) + # Remove the vif from its bridge. + Brctl.vif_bridge_rem(params) + if params['ip']: + # Remove iptables rules for the ip addresses. + vif = params['vif'] + for ip in params['ip']: + Brctl.vif_restrict_addr(vif, ip, delete=1) + + +if __name__ == "__main__": + VifControl().main(sys.argv) |