diff --git a/bin/mn b/bin/mn index 6433dbeaab3f9ee6ec93a01c01cf24f487c8137c..4eaf98100291a29d98841ea1beda09fd3ee0b9a3 100755 --- a/bin/mn +++ b/bin/mn @@ -25,8 +25,8 @@ from mininet.cli import CLI 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, DefaultController, - UserSwitch, OVSSwitch, + RYU, NOX, RemoteController, findController, DefaultController, + UserSwitch, OVSSwitch, OVSBridge, OVSLegacyKernelSwitch, IVSSwitch ) from mininet.nodelib import LinuxBridge from mininet.link import Link, TCLink @@ -54,14 +54,16 @@ TOPOS = { 'minimal': lambda: SingleSwitchTopo( k=2 ), 'tree': TreeTopo, 'torus': TorusTopo } -SWITCHDEF = 'ovsk' +SWITCHDEF = 'default' SWITCHES = { 'user': UserSwitch, 'ovs': OVSSwitch, + 'ovsbr' : OVSBridge, # Keep ovsk for compatibility with 2.0 'ovsk': OVSSwitch, 'ovsl': OVSLegacyKernelSwitch, 'ivs': IVSSwitch, - 'lxbr': LinuxBridge } + 'lxbr': LinuxBridge, + 'default': OVSSwitch } HOSTDEF = 'proc' HOSTS = { 'proc': Host, @@ -73,8 +75,8 @@ CONTROLLERS = { 'ref': Controller, 'ovsc': OVSController, 'nox': NOX, 'remote': RemoteController, - 'default': DefaultController, 'ryu': RYU, + 'default': DefaultController, # Note: replaced below 'none': lambda name: None } LINKDEF = 'default' @@ -252,6 +254,22 @@ class MininetRunner( object ): start = time.time() + if self.options.controller == 'default': + # Update default based on available controllers + CONTROLLERS[ 'default' ] = findController() + if CONTROLLERS[ 'default' ] is None: + if self.options.switch == 'default': + # Fall back to OVS Bridge, which does not use an OF controller + info( '*** No default OpenFlow controller found for default switch!\n' ) + info( '*** Falling back to OVS Bridge\n' ) + self.options.switch = 'ovsbr' + self.options.controller = 'none' + elif self.options.switch in ( 'ovsbr', 'lxbr' ): + self.options.controller = 'none' + else: + raise Exception( "Could not find a default controller for switch %s" % + self.options.switch ) + topo = buildTopo( TOPOS, self.options.topo ) switch = customConstructor( SWITCHES, self.options.switch ) host = customConstructor( HOSTS, self.options.host ) diff --git a/mininet/node.py b/mininet/node.py index 73fe83070efc49ad238b9632351a4e23bbc0a701..df8bb8a3277acc68d812b30c95d44c5b79a35456 100644 --- a/mininet/node.py +++ b/mininet/node.py @@ -1188,9 +1188,21 @@ def stop( self ): self.cmd( 'ip link del', self ) self.deleteIntfs() + OVSKernelSwitch = OVSSwitch +class OVSBridge( OVSSwitch ): + "OVSBridge is an OVSSwitch in standalone/bridge mode" + + def __init__( self, args, **kwargs ): + kwargs.update( failMode='standalone' ) + OVSSwitch.__init__( self, args, **kwargs ) + + def start( self, controllers ): + OVSSwitch.start( self, controllers=[] ) + + class IVSSwitch(Switch): """IVS virtual switch""" @@ -1413,8 +1425,19 @@ def checkListening( self ): warn( "Unable to contact the remote controller" " at %s:%d\n" % ( self.ip, self.port ) ) -def DefaultController( name, order=[ Controller, OVSController ], **kwargs ): - "find any controller that is available and run it" - for controller in order: + +DefaultControllers = [ Controller, OVSController ] + +def findController( controllers=DefaultControllers ): + "Return first available controller from list, if any" + for controller in controllers: if controller.isAvailable(): - return controller( name, **kwargs ) + return controller + +def DefaultController( name, controllers=DefaultControllers, **kwargs ): + "Find a controller that is available and instantiate it" + controller = findController( controllers ) + if not controller: + raise Exception( 'Could not find a default OpenFlow controller' ) + return controller( name, **kwargs ) +