Files
xen/tools/examples/vifctl
T
2004-06-29 18:10:39 +00:00

150 lines
4.6 KiB
Python

#!/usr/bin/python
# -*- mode: python; -*-
#============================================================================
# Xen vif control script. Lives in /etc/xen/xend.
#
# 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):
#print self.name, 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)