ia64/xen-unstable

view tools/vnet/scripts/vn @ 8813:71b0f00f6344

Update vnets to support UDP encapsulation, multicast forwarding
and optionally running in user-space.

Signed-off-by: Mike Wray <mike.wray@hp.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Feb 09 16:12:11 2006 +0100 (2006-02-09)
parents
children 0e24e9674ded
line source
1 #!/usr/bin/env python2.4
2 # -*- mode: python; -*-
3 #============================================================================
4 # Copyright (C) 2005, 2006 Mike Wray <mike.wray@hp.com>
5 #
6 # This library is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU Lesser General Public License as published by
8 # the Free Software Foundation; either version 2.1 of the License, or
9 # (at your option) any later version.
10 #
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Lesser General Public License for more details.
15 #
16 # You should have received a copy of the GNU Lesser General Public License
17 # along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #============================================================================
21 # Vnet (network virtualization) control utility.
23 import os
24 import os.path
25 import re
26 import socket
27 import sys
28 from getopt import getopt, GetoptError
30 sys.path.append('/usr/lib/python')
31 sys.path.append('/usr/lib64/python')
33 from xen.xend import sxp
34 from xen.xend.PrettyPrint import prettyprint
36 # Path of unix-domain socket to vnetd.
37 VNETD_PATH = "/tmp/vnetd"
39 def vnetd_running():
40 return os.path.exists(VNETD_PATH)
42 def vnetd_open():
43 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
44 sock.connect(VNETD_PATH)
45 fi = sock.makefile('r', 0)
46 fo = sock.makefile('w', 0)
47 return (fi, fo)
49 os.defpath += ':/sbin:/usr/sbin:/usr/local/sbin'
50 CMD_IFCONFIG = 'ifconfig'
51 CMD_BRCTL = 'brctl'
53 opts = None
55 class Opts:
57 def __init__(self, **kwds):
58 for (k, v) in kwds.items():
59 setattr(self, k, v)
61 opts = Opts(verbose=False, dryrun=False)
63 def set_opts(val):
64 global opts
65 opts = val
66 return opts
68 def cmd(prog, *args):
69 """Execute command 'prog' with 'args', optionally printing the command.
70 """
71 global opts
72 command = " ".join([ prog ] + map(str, args))
73 if opts.verbose:
74 print command
75 if not opts.dryrun:
76 os.system(command)
78 def vif_bridge_add(bridge, vif):
79 """Add a network interface to a bridge.
80 """
81 cmd(CMD_BRCTL, 'addif', bridge, vif)
83 def vif_bridge_rem(bridge, vif):
84 """Remove a network interface from a bridge.
85 """
86 cmd(CMD_BRCTL, 'delif', bridge, vif)
88 def bridge_create(bridge, **kwd):
89 """Create a bridge.
90 Defaults hello time to 0, forward delay to 0 and stp off.
91 """
92 cmd(CMD_BRCTL, 'addbr', bridge)
93 if kwd.get('hello', None) is None:
94 kwd['hello'] = 0
95 if kwd.get('fd', None) is None:
96 kwd['fd'] = 0
97 if kwd.get('stp', None) is None:
98 kwd['stp'] = 'off'
99 bridge_set(bridge, **kwd)
100 cmd(CMD_IFCONFIG, bridge, "up")
102 def bridge_set(bridge, hello=None, fd=None, stp=None):
103 """Set bridge parameters.
104 """
105 if hello is not None:
106 cmd(CMD_BRCTL, 'sethello', bridge, hello)
107 if fd is not None:
108 cmd(CMD_BRCTL, 'setfd', bridge, fd)
109 if stp is not None:
110 cmd(CMD_BRCTL, 'stp', bridge, stp)
112 def bridge_del(bridge):
113 """Delete a bridge.
114 """
115 cmd(CMD_IFCONFIG, bridge, 'down')
116 cmd(CMD_BRCTL, 'delbr', bridge)
118 class Bridge:
119 # Network interfaces are at /sys/class/net/*.
120 # A bridge interface has ./bridge dir, ./brif is dir of bridged interfaces
121 # (symlinks to the brport dirs).
122 # If an interface is bridged ./brport is bridged port info,
123 # brport/bridge is a symlink to the bridge.
125 INTERFACE_DIR = "/sys/class/net"
127 def isBridge(klass, dev):
128 """Test if a network interface is a bridge.
129 """
130 devdir = os.path.join(klass.INTERFACE_DIR, dev)
131 brdir = os.path.join(devdir, "bridge")
132 try:
133 os.stat(brdir)
134 return True
135 except:
136 return False
138 isBridge = classmethod(isBridge)
140 def getInterfaces(klass):
141 """Get a list of the network interfaces.
142 """
143 try:
144 v = os.listdir(klass.INTERFACE_DIR)
145 v.sort()
146 return v
147 except:
148 return []
150 getInterfaces = classmethod(getInterfaces)
152 def getInterfaceAddr(klass, intf):
153 intfdir = os.path.join(klass.INTERFACE_DIR, intf)
154 addrfile = os.path.join(intfdir, "address")
155 try:
156 f = file(addrfile, "rb")
157 except Exception, ex:
158 #print ex
159 return None
160 try:
161 return f.readline().strip()
162 finally:
163 f.close()
165 getInterfaceAddr = classmethod(getInterfaceAddr)
167 def getBridges(klass):
168 """Get a list of the bridges.
169 """
170 return [ dev for dev in klass.getInterfaces() if klass.isBridge(dev) ]
172 getBridges = classmethod(getBridges)
174 def getBridgeInterfaces(klass, dev):
175 """Get a list of the interfaces attached to a bridge.
176 """
177 devdir = os.path.join(klass.INTERFACE_DIR, dev)
178 intfdir = os.path.join(devdir, "brif")
179 try:
180 v = os.listdir(intfdir)
181 v.sort()
182 return v
183 except:
184 return []
186 getBridgeInterfaces = classmethod(getBridgeInterfaces)
188 def getBridge(klass, dev):
189 """Get the bridge an interface is attached to (if any).
190 """
191 devdir = os.path.join(klass.INTERFACE_DIR, dev)
192 brfile = os.path.join(devdir, "brport/bridge")
193 try:
194 brpath = os.readlink(brfile)
195 return os.path.basename(brpath)
196 except:
197 return None
199 getBridge = classmethod(getBridge)
201 def vnet_cmd(expr):
202 """Send a command expression to the vnet implementation.
203 """
204 if vnetd_running():
205 (fi, fo) = vnetd_open()
206 else:
207 fi = None
208 fo = file("/proc/vnet/policy", "wb")
209 try:
210 sxp.show(expr, fo)
211 fo.flush()
212 finally:
213 if fi: fi.close()
214 if fo: fo.close()
216 def varp_flush():
217 """Flush the varp cache.
218 """
219 expr = ['varp.flush']
220 return vnet_cmd(expr)
222 def vif_add(vnetid, vmac):
223 """Tell the vnet implementation to add a vif to a vnet.
224 """
225 expr = ['vif.add', ['vnet', vnetid], ['vmac', vmac]]
226 return vnet_cmd(expr)
228 def vif_del(vnetid, vmac):
229 """Tell the vnet implementation to delete a vif from a vnet.
230 """
231 expr = ['vif.del', ['vnet', vnetid], ['vmac', vmac]]
232 return vnet_cmd(expr)
234 def vnet_add(vnetid, vnetif=None, security=None):
235 """Tell the vnet implementation to add a vnet.
236 """
237 expr = ['vnet.add', ['id', vnetid]]
238 if vnetif:
239 expr.append(['vnetif', vnetif])
240 if security:
241 expr.append(['security', security])
242 return vnet_cmd(expr)
244 def peer_add(addr, port=None):
245 expr = ['peer.add', ['addr', addr]]
246 if port:
247 expr.append(['port', port])
248 return vnet_cmd(expr)
250 def peer_del(addr, port=None):
251 expr = ['peer.del', ['addr', addr]]
252 return vnet_cmd(expr)
254 def vnet_del(vnetid):
255 """Tell the vnet implementation to delete a vnet.
256 """
257 expr = ['vnet.del', ['id', vnetid]]
258 return vnet_cmd(expr)
260 def vnet_create(vnetid, vnetif=None, bridge=None, security=None):
261 """Tell the vnet implementation to add a vnet.
262 If 'bridge' is non-null, create the bridge and add the vnet interface
263 to it.
264 """
265 vnet_add(vnetid, vnetif=vnetif, security=security)
266 val = vnet_lookup(vnetid)
267 if not vnetif:
268 vnetif = sxp.child_value(val, "vnetif")
269 vmac = get_mac(vnetif)
270 emac = get_mac("eth0") or get_mac("eth1") or get_mac("eth2")
271 if emac and vmac != emac:
272 set_mac(vnetif, emac)
273 cmd(CMD_IFCONFIG, vnetif, 'up')
274 if bridge:
275 bridge_create(bridge)
276 vif_bridge_add(bridge, vnetif)
277 return val
279 def vnet_delete(vnet, delbridge=False):
280 """Tell the vnet implementation to delete a vnet.
281 If the vnet interface is attached to a bridge,
282 remove it from the bridge, and if delbridge is true
283 delete the bridge.
284 """
285 v = vnet_lookup(vnet)
286 if not v:
287 raise GetoptError("vnet not found: %s" % vnet)
288 vnetid = sxp.child_value(v, "id")
289 vnetif = sxp.child_value(v, "vnetif")
290 bridge = Bridge.getBridge(vnetif)
291 if bridge:
292 vif_bridge_rem(bridge, vnetif)
293 if delbridge:
294 bridge_del(bridge)
295 return vnet_del(vnetid)
297 def get_mac(intf):
298 """Get the mac address of an interface.
299 """
300 try:
301 return Bridge.getInterfaceAddr(intf)
302 except:
303 pass
305 hwre = re.compile(".*\s+HWaddr\s+(?P<mac>\S*)\s+.*")
306 fin = os.popen("%s %s" % (CMD_IFCONFIG, intf), 'r')
307 try:
308 for x in fin:
309 m = hwre.match(x)
310 if not m:
311 continue
312 info = m.groupdict()
313 return info['mac']
314 return None
315 finally:
316 fin.close()
318 def set_mac(intf, mac):
319 cmd(CMD_IFCONFIG, intf, 'down')
320 cmd(CMD_IFCONFIG, intf, 'hw', 'ether', mac)
321 cmd(CMD_IFCONFIG, intf, 'up')
323 def get_addr(host):
324 return socket.gethostbyname(host)
326 def get_port(srv):
327 return srv
329 def vnetidof(v):
330 """Normalise a vnet id. Adds leading 0 fields to make up 8 if
331 there aren't enough. Pads all fields to 4 hex digits.
332 """
333 try:
334 l = v.split(":")
335 l = [ int(x or 0, 16) for x in l ]
336 l = [ 0 ] * (8 - len(l)) + l
337 return ":".join([ "%04x" % x for x in l ])
338 except:
339 return None
341 def vnet_lookup(vnet, vnets=None):
342 """Find the vnet with the given vnet id or vnet interface.
344 @param vnet id or interface
345 @param vnets list of vnet info to use (get from implementation if None)
346 @return vnet info or None if not found
347 """
348 vnetid = vnetidof(vnet)
349 if vnets is None:
350 vnets = vnet_list()
351 for v in vnets:
352 vid = sxp.child_value(v, "id")
353 if vid == vnet or vid == vnetid:
354 return v
355 if sxp.child_value(v, "vnetif") == vnet:
356 return v
357 return None
359 def get_vnetid(vnet):
360 """Get the normalised vnet id of the given vnet id or vnet interface.
361 Raises an error if the vnet cannot be found.
362 """
363 v = vnet_lookup(vnet)
364 if not v:
365 raise GetoptError("vnet not found: %s" % vnet)
366 vnetid = sxp.child_value(v, "id")
367 return vnetid
369 def vif_list():
370 """Get the list of vif info from the vnet implementation.
371 """
372 if vnetd_running():
373 (fi, fo) = vnetd_open()
374 sxp.show(['vif.list'], fo)
375 fo.flush()
376 else:
377 fi = file("/proc/vnet/vifs")
378 fo = None
379 try:
380 return sxp.parse(fi) or []
381 finally:
382 if fi: fi.close()
383 if fo: fo.close()
385 def vnets_filter(vnetlist, vnets):
386 """Filter a list of vnet info by a list of vnet ids or interfaces.
387 """
388 if vnets is None:
389 val = vnetlist
390 else:
391 val = []
392 for x in vnets:
393 v = vnet_lookup(x, vnets=vnetlist)
394 if not v:
395 continue
396 val.append(v)
397 return val
399 def vnet_list(vnets=None):
400 """Get the list of vnet info from the vnet implementation,
401 sorted by vnet id.
403 @param vnets list of vnet ids or interfaces to filter the results by
404 """
405 if vnetd_running():
406 (fi, fo) = vnetd_open()
407 sxp.show(['vnet.list'], fo)
408 fo.flush()
409 else:
410 fi = file("/proc/vnet/vnets")
411 fo = None
412 try:
413 val = vnets_filter(sxp.parse(fi) or [], vnets)
414 val.sort(lambda x, y:
415 cmp(sxp.child_value(x, "id"),
416 sxp.child_value(y, "id")))
417 return val
418 finally:
419 if fi: fi.close()
420 if fo: fo.close()
422 def vnif_list(vnets=None):
423 """Get the list of vnet interface names from the vnet implementation.
425 @param vnets list of vnet ids or interfaces to filter the results by
426 """
427 vnifs = []
428 for v in vnet_list(vnets=vnets):
429 vnetif = sxp.child_value(v, "vnetif")
430 if vnetif:
431 vnifs.append(vnetif)
432 return vnifs
434 def varp_list():
435 """Get the list of varp info from the vnet implementation.
436 """
437 if vnetd_running():
438 (fi, fo) = vnetd_open()
439 sxp.show(['varp.list'], fo)
440 fo.flush()
441 else:
442 fi = file("/proc/vnet/varp")
443 fo = None
444 try:
445 return sxp.parse(fi) or []
446 finally:
447 if fi: fi.close()
448 if fo: fo.close()
450 def peer_list():
451 if vnetd_running():
452 (fi, fo) = vnetd_open()
453 sxp.show(['peer.list'], fo)
454 fo.flush()
455 else:
456 fi = file("/proc/vnet/peers")
457 fo = None
458 try:
459 return sxp.parse(fi) or []
460 finally:
461 if fi: fi.close()
462 if fo: fo.close()
464 class Opt:
465 """Declares command-line options for a command.
466 """
468 def getopt(klass, argv, opts, args):
469 """Get options and args from argv.
470 The value opts in the return value has an attribute for
471 eacho option or arg. The value args in the return value
472 is the remaining arguments.
474 @param argv arguments
475 @param opts option specifiers (list of Opt objects)
476 @param args arg specififiers (list of Arg objects)
477 @return (opts, args)
478 """
479 shortopts = "".join([ x.optShort() for x in opts ])
480 longopts = [ x.optLong() for x in opts ]
481 (ovals, oargs) = getopt(argv[1:], shortopts, longopts)
482 odir = Opts()
483 for x in opts:
484 x.setDefault(odir)
485 for (k, v) in ovals:
486 for x in opts:
487 x.setOpt(k, v, odir)
488 argc = len(oargs)
489 if len(oargs) < len(args):
490 raise GetoptError("insufficient arguments for %s" % argv[0])
491 for (x, v) in zip(args, oargs):
492 x.setArg(v, odir)
493 return (odir, oargs[len(args): ])
495 getopt = classmethod(getopt)
497 def gethelp(klass, opts, args):
498 l = []
499 for x in opts:
500 l.append(x.help())
501 for x in args:
502 l.append(x.help())
503 return " ".join(l)
505 gethelp = classmethod(gethelp)
507 """A command=-line option.
509 @param name option name (this attribute is set to value in opts)
510 @param short short option flag (single-character string)
511 @param long long option name (defaults to option name, pass "" to suppress)
512 @param arg argument name (option has no arg if not specified)
513 """
514 def __init__(self, name, short=None, long=None, arg=False):
515 self.name = name
516 self.short = short
517 if long is None:
518 long = name
519 elif not long:
520 long = None
521 self.long = long
522 self.arg = arg
524 def help(self):
525 s = self.keyShort()
526 l = self.keyLong()
527 if s and l:
528 return "[%s | %s]" % (s, l)
529 else:
530 return s or l
532 def keyShort(self):
533 if self.short:
534 return "-%s" % self.short
535 else:
536 return None
538 def keyLong(self):
539 if self.long:
540 return "--%s" % self.long
541 else:
542 return None
544 def optLong(self):
545 if not self.long:
546 return None
547 if self.arg:
548 return "%s=" % self.long
549 else:
550 return self.long
552 def optShort(self):
553 if not self.short:
554 return None
555 if self.arg:
556 return "%s:" % self.short
557 else:
558 return self.short
560 def setDefault(self, vals):
561 if self.arg:
562 setattr(vals, self.name, None)
563 else:
564 setattr(vals, self.name, False)
566 def setOpt(self, k, v, vals):
567 if k in [ self.keyShort(), self.keyLong() ]:
568 if self.arg:
569 setattr(vals, self.name, v)
570 else:
571 if v not in [ None, '' ]:
572 raise GetoptError("option %s does not take an argument" % k)
573 setattr(vals, self.name, True)
575 class Arg:
577 """A command-line parameter. Args get their values from arguments
578 left over after option processing and are assigned in order.
579 The value is accessible as the attribute called 'name' in opts.
581 @param name argument name
582 """
583 def __init__(self, name):
584 self.name = name
586 def setArg(self, v, vals):
587 setattr(vals, self.name, v)
589 def help(self):
590 return "<%s>" % self.name
592 class VnMain:
594 """Methods beginning with this prefix are commands.
595 They must all have arguments like this:
597 op_foo(self, argv, args, opts)
599 argv: original command-line arguments
600 args: arguments left after option processing
601 opts: option and arg values (accessible as attributes)
603 Method options are specified by setting attribute
604 .opts on the method to a list of Option objects.
605 For args set .args to a list of Arg objects.
606 Use .use for short usage string, .help for long help.
608 Each option or arg defines an attribute in opts. For example
609 an option with name 'foo' is accessible as 'opts.foo'.
610 """
611 opPrefix = "op_"
613 def __init__(self, argv):
614 if argv:
615 self.name = argv[0]
616 else:
617 self.name = "vn"
618 self.argv = argv
619 self.argc = len(argv)
621 def error(self, v):
622 print >>sys.stderr, "%s: %s" % (self.name, v)
623 sys.exit(1)
625 def getFunction(self, opname):
626 key = self.opPrefix + opname.replace("-", "_")
627 fn = getattr(self, key, None)
628 if not fn:
629 raise ValueError("unknown command: %s" % opname)
630 return fn
632 def main(self):
633 if self.argc < 2:
634 args = ["help"]
635 else:
636 args = self.argv[1:]
637 try:
638 fn = self.getFunction(args[0])
639 except ValueError, ex:
640 self.error(ex)
641 try:
642 fnopts = self.getOpts(fn)
643 fnargs = self.getArgs(fn)
644 (opts, parms) = Opt.getopt(args, fnopts, fnargs)
645 return fn(args, parms, opts)
646 except GetoptError, ex:
647 self.error(ex)
648 except ValueError, ex:
649 self.error(ex)
650 except Exception, ex:
651 import traceback; traceback.print_exc()
652 self.error(ex)
654 def getOpts(self, meth):
655 return getattr(meth, "opts", [])
657 def getArgs(self, meth):
658 return getattr(meth, "args", [])
660 def getUse(self, meth):
661 return getattr(meth, "use", "")
663 def getHelp(self, meth):
664 return getattr(meth, "help", "") or self.getUse(meth)
666 def fnHelp(self, meth):
667 return Opt.gethelp(self.getOpts(meth), self.getArgs(meth))
669 def printHelp(self, fn, opt_long):
670 meth = getattr(self, fn)
671 opname = fn[len(self.opPrefix):].replace("_", "-")
672 if opt_long:
673 help = self.getHelp(meth)
674 print "\n %s" % opname
675 if help:
676 print "%s" % help
677 else:
678 use = self.getUse(meth)
679 print " %s %s" % (opname, self.fnHelp(meth))
680 if use:
681 print "\t\t%s" % use
683 def show_vnif(self, dev):
684 cmd(CMD_IFCONFIG, dev)
685 bridge = Bridge.getBridge(dev)
686 if bridge:
687 print " Bridge:", bridge
688 interfaces = Bridge.getBridgeInterfaces(bridge)
689 if dev in interfaces:
690 interfaces.remove(dev)
691 if interfaces:
692 print " Interfaces:", ", ".join(interfaces)
693 print
695 def op_help(self, argv, args, opts):
696 if opts.long:
697 print '%s <command> <options>' % self.name
698 print self.long_help
699 else:
700 print '%s:' % self.name
701 l = dir(self)
702 l.sort()
703 for fn in l:
704 if fn.startswith(self.opPrefix):
705 self.printHelp(fn, opts.long)
706 print
708 op_help.opts = [ Opt('long', short='l') ]
710 def op_vnets(self, argv, args, opts):
711 vnets = vnet_list(vnets=args or None)
712 for v in vnets:
713 prettyprint(v, width=50)
714 print
715 if not opts.long:
716 continue
717 vnif = sxp.child_value(v, "vnetif")
718 if not vnif:
719 continue
720 self.show_vnif(vnif)
721 if opts.all:
722 vnetids = {}
723 for v in vnets:
724 vnetids[sxp.child_value(v, "id")] = v
725 for v in vif_list():
726 vnet = sxp.child_value(v, "vnet")
727 if vnet not in vnetids:
728 continue
729 prettyprint(v)
730 print
731 for v in varp_list():
732 prettyprint(v)
733 print
735 op_vnets.opts = [ Opt('all', short='a'), Opt('long', short='l') ]
737 def op_vnifs(self, argv, args, opts):
738 vnifs = vnif_list(vnets=args or None)
739 for vnif in vnifs:
740 self.show_vnif(vnif)
742 def op_vifs(self, argv, args, opts):
743 for v in vif_list():
744 prettyprint(v)
745 print
747 def op_varp(self, argv, args, opts):
748 for v in varp_list():
749 prettyprint(v)
750 print
752 def op_varp_flush(self, argv, args, opts):
753 varp_flush()
755 def op_vnet_create(self, argv, args, opts):
756 return vnet_create(opts.vnet,
757 vnetif=opts.vnetif,
758 bridge=opts.bridge,
759 security=opts.security)
761 op_vnet_create.args = [ Arg('vnet') ]
762 op_vnet_create.opts = [ Opt('security', short='s', arg="SECURITY"),
763 Opt('bridge', short='b', arg="BRIDGE"),
764 Opt('vnetif', short='v', arg="VNETIF") ]
766 def op_vnet_delete(self, argv, args, opts):
767 vnetid = get_vnetid(opts.vnet)
768 return vnet_delete(vnetid, delbridge=opts.bridge)
770 op_vnet_delete.args = [ Arg('vnet') ]
771 op_vnet_delete.opts = [ Opt('bridge', short='b') ]
773 def op_vif_add(self, argv, args, opts):
774 vnetid = get_vnetid(opts.vnet)
775 if opts.interface:
776 vmac = get_mac(opts.vmac)
777 if not vmac:
778 raise ValueError("interface not found: %s" % opts.vmac)
779 else:
780 vmac = opts.vmac
781 return vif_add(vnetid, vmac)
783 op_vif_add.args = [ Arg('vnet'), Arg('vmac') ]
784 op_vif_add.opts = [ Opt('interface', short='i') ]
786 def op_vif_delete(self, argv, args, opts):
787 vnetid = get_vnetid(opts.vnet)
788 if opts.interface:
789 vmac = get_mac(opts.vmac)
790 else:
791 vmac = opts.vmac
792 return vif_del(vnetid, vmac)
794 op_vif_delete.args = [ Arg('vnet'), Arg('vmac') ]
795 op_vif_delete.opts = [ Opt('interface', short='i') ]
797 def op_peer_add(self, argv, args, opts):
798 addr = get_addr(opts.addr)
799 if(opts.port):
800 port = get_port(opts.port)
801 else:
802 port = None
803 return peer_add(addr, port)
805 op_peer_add.args = [ Arg('addr') ]
806 op_peer_add.opts = [ Opt('port', short='p') ]
808 def op_peer_delete(self, argv, args, opts):
809 addr = get_addr(opts.addr)
810 return peer_del(addr)
812 op_peer_delete.args = [ Arg('addr') ]
814 def op_peers(self, argv, args, opts):
815 for v in peer_list():
816 prettyprint(v)
817 print
819 def op_bridges(self, argv, args, opts):
820 if opts.long:
821 for bridge in Bridge.getBridges():
822 cmd(CMD_IFCONFIG, bridge)
823 interfaces = Bridge.getBridgeInterfaces(bridge)
824 if interfaces:
825 print " Interfaces:", ", ".join(interfaces)
826 print
827 else:
828 for bridge in Bridge.getBridges():
829 print bridge,
830 interfaces = Bridge.getBridgeInterfaces(bridge)
831 if interfaces:
832 print ":", ", ".join(interfaces)
833 else:
834 print
836 op_bridges.opts = [ Opt('long', short='l') ]
838 def op_insmod(self, argv, args, opts):
839 """Insert the vnet kernel module."""
840 cmd("/etc/xen/scripts/vnet-insert", *args)
842 long_help = """Control utility for vnets (virtual networking).
843 Report bugs to Mike Wray <mike.wray@hp.com>.
844 """
846 op_help.use = "Print help."
847 op_help.help = "Print help, long help if the option -l or --long is given."
849 op_vnets.use = """Print vnets."""
850 op_vnets.help = """Print vnet information, where options are:
851 -a, -all Print vnets, vifs and varp info.
852 -l, --long Print ifconfigs for vnet interfaces."""
854 op_vifs.use = "Print vifs."
856 op_vnifs.use = "Print ifconfigs for vnet network interfaces."
858 op_varp.use = "Print varp info and entries in the varp cache."
860 op_varp_flush.use = "Flush the varp cache."
862 op_vnet_create.use = "Create a vnet."
864 op_vnet_delete.use = "Delete a vnet."
865 op_vnet_delete.help = """Delete a vnet.
866 -b, --bridge Delete the bridge the vnet interface is attached to.
867 """
869 op_vif_add.use = "Add a vif to a vnet."
870 op_vif_add.help = """Add a vif to a vnet. Not usually needed as vifs
871 are added automatically.
872 -i, --interface The vmac is the name of an interface to get the mac from."""
874 op_vif_delete.use = "Delete a vif from a vnet."
875 op_vif_delete.help = """Delete a vif from a vnet. Not usually needed as vifs
876 are removed periodically.
877 -i, --interface The vmac is the name of an interface to get the mac from."""
879 op_peer_add.use = "Add a peer."
880 op_peer_add.help = """Add a peer: <addr> <port>
881 Vnets use multicast to discover interfaces, but networks are often configured
882 not to forward multicast. Vnets forward multicasts to peers using UDP.
883 Only add peers if multicasts are not working, check with
885 ping -b 224.10.0.1
887 Only add peers at one machine in a subnet, otherwise you may cause forwarding
888 loops.
889 """
891 op_peer_delete.use = "Delete a peer."
892 op_peer_delete.help= "Delete a peer: <addr>"
894 op_peers.use = "List peers."
895 op_peers.help = "List peers."
897 op_bridges.use = "Print bridges."
899 op_insmod.use = "Insert the vnet kernel module, optionally with parameters."
901 if __name__ == "__main__":
902 vn = VnMain(sys.argv)
903 vn.main()