diff --git a/bin/mn b/bin/mn index 05c9cb8..b702b8e 100755 --- a/bin/mn +++ b/bin/mn @@ -26,12 +26,13 @@ from mininet.log import lg, LEVELS, info, debug, warn, error from mininet.net import Mininet, MininetWithControlNet, VERSION from mininet.node import ( Host, CPULimitedHost, Controller, OVSController, Ryu, NOX, RemoteController, findController, - DefaultController, + DefaultController, NullController, UserSwitch, OVSSwitch, OVSBridge, IVSSwitch ) from mininet.nodelib import LinuxBridge from mininet.link import Link, TCLink, OVSLink -from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo +from mininet.topo import ( SingleSwitchTopo, LinearTopo, + SingleSwitchReversedTopo, MinimalTopo ) from mininet.topolib import TreeTopo, TorusTopo from mininet.util import customClass, specialClass, splitArgs from mininet.util import buildTopo @@ -49,7 +50,7 @@ PLACEMENT = { 'block': SwitchBinPlacer, 'random': RandomPlacer } # built in topologies, created only when run TOPODEF = 'minimal' -TOPOS = { 'minimal': lambda: SingleSwitchTopo( k=2 ), +TOPOS = { 'minimal': MinimalTopo, 'linear': LinearTopo, 'reversed': SingleSwitchReversedTopo, 'single': SingleSwitchTopo, @@ -65,13 +66,6 @@ SWITCHES = { 'user': UserSwitch, 'ivs': IVSSwitch, 'lxbr': LinuxBridge, 'default': OVSSwitch } -SWITCHESHELP = { 'user': 'OpenFlow reference user-space switch.', - 'ovs': 'Open vSwitch OpenFlow-compatible switch.', - 'ovsbr': 'Open vSwitch as an L2 MAC learning switch.', - 'ovsk': 'Same as the ovs type.', - 'ivs': 'Indigo Virtual Switch.', - 'lxbr': 'Linux Bridge.', - 'default': 'Open vSwitch OpenFlow-compatible switch.'} HOSTDEF = 'proc' HOSTS = { 'proc': Host, @@ -79,13 +73,14 @@ HOSTS = { 'proc': Host, 'cfs': specialClass( CPULimitedHost, defaults=dict( sched='cfs' ) ) } CONTROLLERDEF = 'default' + CONTROLLERS = { 'ref': Controller, 'ovsc': OVSController, 'nox': NOX, 'remote': RemoteController, 'ryu': Ryu, 'default': DefaultController, # Note: replaced below - 'none': lambda name: None } + 'none': NullController } LINKDEF = 'default' LINKS = { 'default': Link, @@ -103,20 +98,18 @@ ALTSPELLING = { 'pingall': 'pingAll', 'iperfUDP': 'iperfUdp' } -def addDictOption( opts, choicesDict, default, name, helpDict=None, **kwargs ): - """Convenience function to add choices dicts to OptionParser. - opts: OptionParser instance - choicesDict: dictionary of valid choices, must include default - default: default choice key - name: long option name - helpDict: dictionary describing choices - kwargs: additional arguments to add_option""" +def addDictOption( opts, choicesDict, default, name, **kwargs ): + """Convenience function to add choices dicts to OptionParser. + opts: OptionParser instance + choicesDict: dictionary of valid choices, must include default + default: default choice key + name: long option name + kwargs: additional arguments to add_option""" helpStr = ( '|'.join( sorted( choicesDict.keys() ) ) + '[,param=value...]' ) - if helpDict: - helpList = [ k + "=" + helpDict[k] - for k in sorted( helpDict.keys() ) ] - helpStr += " " + ( ' '.join( helpList ) ) + helpList = [ '%s=%s' % ( k, v.__name__ ) + for k, v in choicesDict.items() ] + helpStr += ' ' + ( ' '.join( helpList ) ) params = dict( type='string', default=default, help=helpStr ) params.update( **kwargs ) opts.add_option( '--' + name, **params ) @@ -202,7 +195,7 @@ class MininetRunner( object ): '(type %prog -h for details)' ) opts = OptionParser( description=desc, usage=usage ) - addDictOption( opts, SWITCHES, SWITCHDEF, 'switch', SWITCHESHELP ) + addDictOption( opts, SWITCHES, SWITCHDEF, 'switch' ) addDictOption( opts, HOSTS, HOSTDEF, 'host' ) addDictOption( opts, CONTROLLERS, [], 'controller', action='append' ) addDictOption( opts, LINKS, LINKDEF, 'link' ) diff --git a/mininet/node.py b/mininet/node.py index 872c061..544fae3 100644 --- a/mininet/node.py +++ b/mininet/node.py @@ -906,7 +906,7 @@ class Switch( Node ): deleteIntfs: delete interfaces? (True)""" if deleteIntfs: self.deleteIntfs() - + def __repr__( self ): "More informative string representation" intfs = ( ','.join( [ '%s:%s' % ( i.name, i.IP() ) @@ -1517,3 +1517,7 @@ def DefaultController( name, controllers=DefaultControllers, **kwargs ): if not controller: raise Exception( 'Could not find a default OpenFlow controller' ) return controller( name, **kwargs ) + +def NullController( *_args, **_kwargs ): + "Nonexistent controller - simply returns None" + return None diff --git a/mininet/topo.py b/mininet/topo.py index aea2b67..55c5b59 100644 --- a/mininet/topo.py +++ b/mininet/topo.py @@ -318,6 +318,12 @@ class SingleSwitchReversedTopo( Topo ): port1=0, port2=( k - h + 1 ) ) +class MinimalTopo( SingleSwitchTopo ): + "Minimal topology with two hosts and one switch" + def build( self ): + return SingleSwitchTopo.build( self, k=2 ) + + class LinearTopo( Topo ): "Linear topology of k switches, with n hosts per switch."