Skip to content
Snippets Groups Projects
Commit 019bff82 authored by Bob Lantz's avatar Bob Lantz
Browse files

Made it possible to create a Mininet() without using a Topo object.

This increases flexibility by allowing a topology to be manually created
in Python, or specified using another format, without having to create
a Topo object first.

However, Topos are useful, and are still the default topology object!
parent 3e021c25
No related branches found
No related tags found
No related merge requests found
bin/mn 100644 → 100755
File mode changed from 100644 to 100755
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
from mininet.log import info, error from mininet.log import info, error
from mininet.node import KernelSwitch, OVSKernelSwitch from mininet.node import KernelSwitch, OVSKernelSwitch
from mininet.util import quietRun, fixLimits from mininet.util import quietRun, fixLimits
from mininet.util import makeIntfPair, moveIntf from mininet.util import makeIntfPair, moveIntf, macColonHex
from mininet.xterm import cleanUpScreens, makeXterms from mininet.xterm import cleanUpScreens, makeXterms
DATAPATHS = [ 'kernel' ] #[ 'user', 'kernel' ] DATAPATHS = [ 'kernel' ] #[ 'user', 'kernel' ]
...@@ -110,92 +110,103 @@ def __init__( self, topo, switch, host, controller, cparams, ...@@ -110,92 +110,103 @@ def __init__( self, topo, switch, host, controller, cparams,
inNamespace=False, inNamespace=False,
autoSetMacs=False, autoStaticArp=False ): autoSetMacs=False, autoStaticArp=False ):
"""Create Mininet object. """Create Mininet object.
topo: Topo object topo: Topo (topology) object or None
switch: Switch class switch: Switch class
host: Host class host: Host class
controller: Controller class controller: Controller class
cparams: ControllerParams object cparams: ControllerParams object
now: build now? now: build now from topo?
xterms: if build now, spawn xterms? xterms: if build now, spawn xterms?
cleanup: if build now, cleanup before creating? cleanup: if build now, cleanup before creating?
inNamespace: spawn switches and controller in net namespaces? inNamespace: spawn switches and controller in net namespaces?
autoSetMacs: set MAC addrs to DPIDs? autoSetMacs: set MAC addrs to DPIDs?
autoStaticArp: set all-pairs static MAC addrs?""" autoStaticArp: set all-pairs static MAC addrs?"""
self.topo = topo
self.switch = switch self.switch = switch
self.host = host self.host = host
self.controller = controller self.controller = controller
self.cparams = cparams self.cparams = cparams
self.nodes = {} # dpid to Node{ Host, Switch } objects self.topo = topo
self.controllers = {} # controller name to Controller objects
self.dps = 0 # number of created kernel datapaths
self.inNamespace = inNamespace self.inNamespace = inNamespace
self.xterms = xterms self.xterms = xterms
self.cleanup = cleanup self.cleanup = cleanup
self.autoSetMacs = autoSetMacs self.autoSetMacs = autoSetMacs
self.autoStaticArp = autoStaticArp self.autoStaticArp = autoStaticArp
self.hosts = []
self.switches = []
self.controllers = []
self.nameToNode = {} # name to Node (Host/Switch) objects
self.idToNode = {} # dpid to Node (Host/Switch) objects
self.dps = 0 # number of created kernel datapaths
self.terms = [] # list of spawned xterm processes self.terms = [] # list of spawned xterm processes
if build: if topo and build:
self.build() self.buildFromTopo( self.topo )
def _addHost( self, dpid ): def addHost( self, name, defaultMac=None, defaultIp=None ):
"""Add host. """Add host.
dpid: DPID of host to add""" name: name of host to add
host = self.host( 'h' + self.topo.name( dpid ) ) defaultMac: default MAC address for intf 0
defaultIp: default IP address for intf 0
returns: added host"""
host = self.host( name )
# for now, assume one interface per host. # for now, assume one interface per host.
host.intfs.append( 'h' + self.topo.name( dpid ) + '-eth0' ) host.intfs.append( name + '-eth0' )
self.nodes[ dpid ] = host self.hosts.append( host )
#info( '%s ' % host.name ) self.nameToNode[ name ] = host
# May wish to add this to actual object
def _addSwitch( self, dpid ): if defaultMac:
host.defaultMac = defaultMac
if defaultIp:
host.defaultIP = defaultIp
return host
def addSwitch( self, name, defaultMac=None ):
"""Add switch. """Add switch.
dpid: DPID of switch to add""" name: name of switch to add
sw = None defaultMac: default MAC address for kernel/OVS switch intf 0
swDpid = None returns: added switch"""
if self.autoSetMacs:
swDpid = dpid
if self.switch is KernelSwitch or self.switch is OVSKernelSwitch: if self.switch is KernelSwitch or self.switch is OVSKernelSwitch:
sw = self.switch( 's_' + self.topo.name( dpid ), dp = self.dps, sw = self.switch( name, dp=self.dps, defaultMac=defaultMac )
dpid = swDpid )
self.dps += 1 self.dps += 1
else: else:
sw = self.switch( 's_' + self.topo.name( dpid ) ) sw = self.switch( name )
self.nodes[ dpid ] = sw self.switches.append( sw )
self.nameToNode[ name ] = sw
return sw
def _addLink( self, src, dst ): def addLink( self, src, srcPort, dst, dstPort ):
"""Add link. """Add link.
src: source DPID src: source Node
dst: destination DPID""" srcPort: source port
srcPort, dstPort = self.topo.port( src, dst ) dst: destination Node
srcNode = self.nodes[ src ] dstPort: destination port"""
dstNode = self.nodes[ dst ] srcIntf = src.intfName( srcPort )
srcIntf = srcNode.intfName( srcPort ) dstIntf = dst.intfName( dstPort )
dstIntf = dstNode.intfName( dstPort )
makeIntfPair( srcIntf, dstIntf ) makeIntfPair( srcIntf, dstIntf )
srcNode.intfs.append( srcIntf ) src.intfs.append( srcIntf )
dstNode.intfs.append( dstIntf ) dst.intfs.append( dstIntf )
srcNode.ports[ srcPort ] = srcIntf src.ports[ srcPort ] = srcIntf
dstNode.ports[ dstPort ] = dstIntf dst.ports[ dstPort ] = dstIntf
#info( '\n' ) #info( '\n' )
#info( 'added intf %s to src node %x\n' % ( srcIntf, src ) ) #info( 'added intf %s to src node %x\n' % ( srcIntf, src ) )
#info( 'added intf %s to dst node %x\n' % ( dstIntf, dst ) ) #info( 'added intf %s to dst node %x\n' % ( dstIntf, dst ) )
if srcNode.inNamespace: if src.inNamespace:
#info( 'moving src w/inNamespace set\n' ) #info( 'moving src w/inNamespace set\n' )
moveIntf( srcIntf, srcNode ) moveIntf( srcIntf, src )
if dstNode.inNamespace: if dst.inNamespace:
#info( 'moving dst w/inNamespace set\n' ) #info( 'moving dst w/inNamespace set\n' )
moveIntf( dstIntf, dstNode ) moveIntf( dstIntf, dst )
srcNode.connection[ srcIntf ] = ( dstNode, dstIntf ) src.connection[ srcIntf ] = ( dst, dstIntf )
dstNode.connection[ dstIntf ] = ( srcNode, srcIntf ) dst.connection[ dstIntf ] = ( src, srcIntf )
def _addController( self, controller ): def addController( self, controller ):
"""Add controller. """Add controller.
controller: Controller class""" controller: Controller class"""
controller = self.controller( 'c0', self.inNamespace ) controller = self.controller( 'c0', self.inNamespace )
if controller: # allow controller-less setups if controller: # allow controller-less setups
self.controllers[ 'c0' ] = controller self.controllers.append( controller )
self.nameToNode[ 'c0' ] = controller
# Control network support: # Control network support:
# #
...@@ -216,7 +227,7 @@ def _addController( self, controller ): ...@@ -216,7 +227,7 @@ def _addController( self, controller ):
# #
# 4. Even if we dispense with this in general, it could still be # 4. Even if we dispense with this in general, it could still be
# useful for people who wish to simulate a separate control # useful for people who wish to simulate a separate control
# network ( since real networks may need one! ) # network (since real networks may need one!)
def _configureControlNetwork( self ): def _configureControlNetwork( self ):
"Configure control network." "Configure control network."
...@@ -229,12 +240,11 @@ def _configureRoutedControlNetwork( self ): ...@@ -229,12 +240,11 @@ def _configureRoutedControlNetwork( self ):
""" """
# params were: controller, switches, ips # params were: controller, switches, ips
controller = self.controllers[ 'c0' ] controller = self.controllers[ 0 ]
info( '%s <-> ' % controller.name ) info( '%s <-> ' % controller.name )
for switchDpid in self.topo.switches(): for switch in self.switches:
switch = self.nodes[ switchDpid ]
info( '%s ' % switch.name ) info( '%s ' % switch.name )
sip = self.topo.ip( switchDpid )#ips.next() sip = switch.defaultIP
sintf = switch.intfs[ 0 ] sintf = switch.intfs[ 0 ]
node, cintf = switch.connection[ sintf ] node, cintf = switch.connection[ sintf ]
if node != controller: if node != controller:
...@@ -253,8 +263,7 @@ def _configureRoutedControlNetwork( self ): ...@@ -253,8 +263,7 @@ def _configureRoutedControlNetwork( self ):
info( '*** Waiting for %s to come up\n', info( '*** Waiting for %s to come up\n',
controller.intfs[ 0 ] ) controller.intfs[ 0 ] )
sleep( 1 ) sleep( 1 )
for switchDpid in self.topo.switches(): for switch in self.switches:
switch = self.nodes[ switchDpid ]
while not switch.intfIsUp( switch.intfs[ 0 ] ): while not switch.intfIsUp( switch.intfs[ 0 ] ):
info( '*** Waiting for %s to come up\n' % info( '*** Waiting for %s to come up\n' %
switch.intfs[ 0 ] ) switch.intfs[ 0 ] )
...@@ -267,10 +276,9 @@ def _configureRoutedControlNetwork( self ): ...@@ -267,10 +276,9 @@ def _configureRoutedControlNetwork( self ):
def _configHosts( self ): def _configHosts( self ):
"Configure a set of hosts." "Configure a set of hosts."
# params were: hosts, ips # params were: hosts, ips
for hostDpid in self.topo.hosts(): for host in self.hosts:
host = self.nodes[ hostDpid ]
hintf = host.intfs[ 0 ] hintf = host.intfs[ 0 ]
host.setIP( hintf, self.topo.ip( hostDpid ), host.setIP( hintf, host.defaultIP,
'/' + str( self.cparams.subnetSize ) ) '/' + str( self.cparams.subnetSize ) )
host.setDefaultRoute( hintf ) host.setDefaultRoute( hintf )
# You're low priority, dude! # You're low priority, dude!
...@@ -278,28 +286,37 @@ def _configHosts( self ): ...@@ -278,28 +286,37 @@ def _configHosts( self ):
info( '%s ', host.name ) info( '%s ', host.name )
info( '\n' ) info( '\n' )
def build( self ): def buildFromTopo( self, topo ):
"""Build mininet. """Build mininet from a topology object
At the end of this function, everything should be connected At the end of this function, everything should be connected
and up.""" and up."""
if self.cleanup: if self.cleanup:
pass # cleanup pass # cleanup
# validate topo? # validate topo?
info( '*** Adding controller\n' ) info( '*** Adding controller\n' )
self._addController( self.controller ) self.addController( self.controller )
info( '*** Creating network\n' ) info( '*** Creating network\n' )
info( '*** Adding hosts:\n' ) info( '*** Adding hosts:\n' )
for host in sorted( self.topo.hosts() ): for hostId in sorted( topo.hosts() ):
self._addHost( host ) name = 'h' + topo.name( hostId )
info( '0x%x ' % host ) mac = macColonHex( hostId ) if self.setMacs else None
ip = topo.ip( hostId )
host = self.addHost( name, defaultIp=ip, defaultMac=mac )
self.idToNode[ hostId ] = host
info( name )
info( '\n*** Adding switches:\n' ) info( '\n*** Adding switches:\n' )
for switch in sorted( self.topo.switches() ): for switchId in sorted( topo.switches() ):
self._addSwitch( switch ) name = 's' + topo.name( switchId )
info( '0x%x ' % switch ) mac = macColonHex( switchId) if self.setMacs else None
switch = self.addSwitch( name, defaultMac=mac )
self.idToNode[ switchId ] = switch
info( name )
info( '\n*** Adding edges:\n' ) info( '\n*** Adding edges:\n' )
for src, dst in sorted( self.topo.edges() ): for srcId, dstId in sorted( topo.edges() ):
self._addLink( src, dst ) src, dst = self.idToNode[ srcId ], self.idToNode[ dstId ]
info( '(0x%x, 0x%x) ' % ( src, dst ) ) srcPort, dstPort = topo.port( srcId, dstId )
self.addLink( src, srcPort, dst, dstPort )
info( '(%s, %s) ' % ( src.name, dst.name ) )
info( '\n' ) info( '\n' )
if self.inNamespace: if self.inNamespace:
...@@ -316,21 +333,13 @@ def build( self ): ...@@ -316,21 +333,13 @@ def build( self ):
if self.autoStaticArp: if self.autoStaticArp:
self.staticArp() self.staticArp()
def switchNodes( self ):
"Return switch nodes."
return [ self.nodes[ dpid ] for dpid in self.topo.switches() ]
def hostNodes( self ):
"Return host nodes."
return [ self.nodes[ dpid ] for dpid in self.topo.hosts() ]
def startXterms( self ): def startXterms( self ):
"Start an xterm for each node in the topo." "Start an xterm for each node."
info( "*** Running xterms on %s\n" % os.environ[ 'DISPLAY' ] ) info( "*** Running xterms on %s\n" % os.environ[ 'DISPLAY' ] )
cleanUpScreens() cleanUpScreens()
self.terms += makeXterms( self.controllers.values(), 'controller' ) self.terms += makeXterms( self.controllers, 'controller' )
self.terms += makeXterms( self.switchNodes(), 'switch' ) self.terms += makeXterms( self.switches, 'switch' )
self.terms += makeXterms( self.hostNodes(), 'host' ) self.terms += makeXterms( self.hosts, 'host' )
def stopXterms( self ): def stopXterms( self ):
"Kill each xterm." "Kill each xterm."
...@@ -342,28 +351,24 @@ def stopXterms( self ): ...@@ -342,28 +351,24 @@ def stopXterms( self ):
def setMacs( self ): def setMacs( self ):
"""Set MAC addrs to correspond to datapath IDs on hosts. """Set MAC addrs to correspond to datapath IDs on hosts.
Assume that the host only has one interface.""" Assume that the host only has one interface."""
for dpid in self.topo.hosts(): for host in self.hosts:
hostNode = self.nodes[ dpid ] host.setMAC( host.intfs[ 0 ], host.defaultMac )
hostNode.setMAC( hostNode.intfs[ 0 ], dpid )
def staticArp( self ): def staticArp( self ):
"Add all-pairs ARP entries to remove the need to handle broadcast." "Add all-pairs ARP entries to remove the need to handle broadcast."
for src in self.topo.hosts(): for src in self.hosts:
srcNode = self.nodes[ src ] for dst in self.hosts:
for dst in self.topo.hosts():
if src != dst: if src != dst:
srcNode.setARP( dst, dst ) src.setARP( ip=dst.IP(), mac=dst.defaultMac )
def start( self ): def start( self ):
"Start controller and switches" "Start controller and switches"
info( '*** Starting controller\n' ) info( '*** Starting controller\n' )
for cnode in self.controllers.values(): for controller in self.controllers:
cnode.start() controller.start()
info( '*** Starting %s switches\n' % len( self.topo.switches() ) ) info( '*** Starting %s switches\n' % len( self.switches ) )
for switchDpid in self.topo.switches(): for switch in self.switches:
switch = self.nodes[ switchDpid ] info( switch.name )
#info( 'switch = %s' % switch )
info( '0x%x ' % switchDpid )
switch.start( self.controllers ) switch.start( self.controllers )
info( '\n' ) info( '\n' )
...@@ -372,21 +377,19 @@ def stop( self ): ...@@ -372,21 +377,19 @@ def stop( self ):
if self.terms: if self.terms:
info( '*** Stopping %i terms\n' % len( self.terms ) ) info( '*** Stopping %i terms\n' % len( self.terms ) )
self.stopXterms() self.stopXterms()
info( '*** Stopping %i hosts\n' % len( self.topo.hosts() ) ) info( '*** Stopping %i hosts\n' % len( self.hosts ) )
for hostDpid in self.topo.hosts(): for host in self.hosts:
host = self.nodes[ hostDpid ]
info( '%s ' % host.name ) info( '%s ' % host.name )
host.terminate() host.terminate()
info( '\n' ) info( '\n' )
info( '*** Stopping %i switches\n' % len( self.topo.switches() ) ) info( '*** Stopping %i switches\n' % len( self.switches ) )
for switchDpid in self.topo.switches(): for switch in self.switches:
switch = self.nodes[ switchDpid ] info( '%s ' % switch.name )
info( '%s' % switch.name )
switch.stop() switch.stop()
info( '\n' ) info( '\n' )
info( '*** Stopping controller\n' ) info( '*** Stopping %i controllers\n' % len( self.controllers ) )
for cnode in self.controllers.values(): for controller in self.controllers:
cnode.stop() controller.stop()
info( '*** Test complete\n' ) info( '*** Test complete\n' )
def run( self, test, **params ): def run( self, test, **params ):
...@@ -411,7 +414,7 @@ def _parsePing( pingOutput ): ...@@ -411,7 +414,7 @@ def _parsePing( pingOutput ):
def ping( self, hosts=None ): def ping( self, hosts=None ):
"""Ping between all specified hosts. """Ping between all specified hosts.
hosts: list of host DPIDs hosts: list of hosts
returns: ploss packet loss percentage""" returns: ploss packet loss percentage"""
#self.start() #self.start()
# check if running - only then, start? # check if running - only then, start?
...@@ -419,13 +422,11 @@ def ping( self, hosts=None ): ...@@ -419,13 +422,11 @@ def ping( self, hosts=None ):
lost = 0 lost = 0
ploss = None ploss = None
if not hosts: if not hosts:
hosts = self.topo.hosts() hosts = self.hosts
info( '*** Ping: testing ping reachability\n' ) info( '*** Ping: testing ping reachability\n' )
for nodeDpid in hosts: for node in hosts:
node = self.nodes[ nodeDpid ]
info( '%s -> ' % node.name ) info( '%s -> ' % node.name )
for destDpid in hosts: for dest in hosts:
dest = self.nodes[ destDpid ]
if node != dest: if node != dest:
result = node.cmd( 'ping -c1 ' + dest.IP() ) result = node.cmd( 'ping -c1 ' + dest.IP() )
sent, received = self._parsePing( result ) sent, received = self._parsePing( result )
...@@ -451,8 +452,7 @@ def pingAll( self ): ...@@ -451,8 +452,7 @@ def pingAll( self ):
def pingPair( self ): def pingPair( self ):
"""Ping between first two hosts, useful for testing. """Ping between first two hosts, useful for testing.
returns: ploss packet loss percentage""" returns: ploss packet loss percentage"""
hostsSorted = sorted( self.topo.hosts() ) hosts = [ self.hosts[ 0 ], self.hosts[ 1 ] ]
hosts = [ hostsSorted[ 0 ], hostsSorted[ 1 ] ]
return self.ping( hosts=hosts ) return self.ping( hosts=hosts )
@staticmethod @staticmethod
...@@ -470,17 +470,15 @@ def _parseIperf( iperfOutput ): ...@@ -470,17 +470,15 @@ def _parseIperf( iperfOutput ):
def iperf( self, hosts=None, l4Type='TCP', udpBw='10M', def iperf( self, hosts=None, l4Type='TCP', udpBw='10M',
verbose=False ): verbose=False ):
"""Run iperf between two hosts. """Run iperf between two hosts.
hosts: list of host DPIDs; if None, uses opposite hosts hosts: list of hosts; if None, uses opposite hosts
l4Type: string, one of [ TCP, UDP ] l4Type: string, one of [ TCP, UDP ]
verbose: verbose printing verbose: verbose printing
returns: results two-element array of server and client speeds""" returns: results two-element array of server and client speeds"""
if not hosts: if not hosts:
hostsSorted = sorted( self.topo.hosts() ) hosts = [ self.hosts[ 0 ], self.hosts[ -1 ] ]
hosts = [ hostsSorted[ 0 ], hostsSorted[ -1 ] ]
else: else:
assert len( hosts ) == 2 assert len( hosts ) == 2
host0 = self.nodes[ hosts[ 0 ] ] host0, host1 = hosts
host1 = self.nodes[ hosts[ 1 ] ]
info( '*** Iperf: testing ' + l4Type + ' bandwidth between ' ) info( '*** Iperf: testing ' + l4Type + ' bandwidth between ' )
info( "%s and %s\n" % ( host0.name, host1.name ) ) info( "%s and %s\n" % ( host0.name, host1.name ) )
host0.cmd( 'killall -9 iperf' ) host0.cmd( 'killall -9 iperf' )
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
import select import select
from mininet.log import info, error from mininet.log import info, error
from mininet.util import quietRun, macColonHex, ipStr from mininet.util import quietRun
class Node( object ): class Node( object ):
...@@ -191,19 +191,16 @@ def newIntf( self ): ...@@ -191,19 +191,16 @@ def newIntf( self ):
def setMAC( self, intf, mac ): def setMAC( self, intf, mac ):
"""Set the MAC address for an interface. """Set the MAC address for an interface.
mac: MAC address as unsigned int""" mac: MAC address as string"""
macStr = macColonHex( mac )
result = self.cmd( [ 'ifconfig', intf, 'down' ] ) result = self.cmd( [ 'ifconfig', intf, 'down' ] )
result += self.cmd( [ 'ifconfig', intf, 'hw', 'ether', macStr ] ) result += self.cmd( [ 'ifconfig', intf, 'hw', 'ether', mac ] )
result += self.cmd( [ 'ifconfig', intf, 'up' ] ) result += self.cmd( [ 'ifconfig', intf, 'up' ] )
return result return result
def setARP( self, ip, mac ): def setARP( self, ip, mac ):
"""Add an ARP entry. """Add an ARP entry.
ip: IP address as unsigned int ip: IP address as string
mac: MAC address as unsigned int""" mac: MAC address as string"""
ip = ipStr( ip )
mac = macColonHex( mac )
result = self.cmd( [ 'arp', '-s', ip, mac ] ) result = self.cmd( [ 'arp', '-s', ip, mac ] )
return result return result
...@@ -286,9 +283,7 @@ def start( self, controllers ): ...@@ -286,9 +283,7 @@ def start( self, controllers ):
"""Start OpenFlow reference user datapath. """Start OpenFlow reference user datapath.
Log to /tmp/sN-{ofd,ofp}.log. Log to /tmp/sN-{ofd,ofp}.log.
controllers: dict of controller names to objects""" controllers: dict of controller names to objects"""
if 'c0' not in controllers: controller = controllers[ 0 ]
raise Exception( 'User datapath start() requires controller c0' )
controller = controllers[ 'c0' ]
ofdlog = '/tmp/' + self.name + '-ofd.log' ofdlog = '/tmp/' + self.name + '-ofd.log'
ofplog = '/tmp/' + self.name + '-ofp.log' ofplog = '/tmp/' + self.name + '-ofp.log'
self.cmd( 'ifconfig lo up' ) self.cmd( 'ifconfig lo up' )
...@@ -311,14 +306,14 @@ class KernelSwitch( Switch ): ...@@ -311,14 +306,14 @@ class KernelSwitch( Switch ):
"""Kernel-space switch. """Kernel-space switch.
Currently only works in the root namespace.""" Currently only works in the root namespace."""
def __init__( self, name, dp=None, dpid=None ): def __init__( self, name, dp=None, defaultMac=None ):
"""Init. """Init.
name: name:
dp: netlink id (0, 1, 2, ...) dp: netlink id (0, 1, 2, ...)
dpid: datapath ID as unsigned int; random value if None""" defaultMac: default MAC as string; random value if None"""
Switch.__init__( self, name, inNamespace=False ) Switch.__init__( self, name, inNamespace=False )
self.dp = dp self.dp = dp
self.dpid = dpid self.defaultMac = defaultMac
def start( self, controllers ): def start( self, controllers ):
"Start up reference kernel datapath." "Start up reference kernel datapath."
...@@ -328,10 +323,9 @@ def start( self, controllers ): ...@@ -328,10 +323,9 @@ def start( self, controllers ):
# then create a new one monitoring the given interfaces # then create a new one monitoring the given interfaces
quietRun( 'dpctl deldp nl:%i' % self.dp ) quietRun( 'dpctl deldp nl:%i' % self.dp )
self.cmdPrint( 'dpctl adddp nl:%i' % self.dp ) self.cmdPrint( 'dpctl adddp nl:%i' % self.dp )
if self.dpid: if self.defaultMac:
intf = 'of%i' % self.dp intf = 'of%i' % self.dp
macStr = macColonHex( self.dpid ) self.cmd( [ 'ifconfig', intf, 'hw', 'ether', self.defaultMac ] )
self.cmd( [ 'ifconfig', intf, 'hw', 'ether', macStr ] )
if len( self.ports ) != max( self.ports.keys() ) + 1: if len( self.ports ) != max( self.ports.keys() ) + 1:
raise Exception( 'only contiguous, zero-indexed port ranges' raise Exception( 'only contiguous, zero-indexed port ranges'
...@@ -340,9 +334,10 @@ def start( self, controllers ): ...@@ -340,9 +334,10 @@ def start( self, controllers ):
self.cmdPrint( 'dpctl addif nl:' + str( self.dp ) + ' ' + self.cmdPrint( 'dpctl addif nl:' + str( self.dp ) + ' ' +
' '.join( intfs ) ) ' '.join( intfs ) )
# Run protocol daemon # Run protocol daemon
controller = controllers[ 0 ]
self.cmdPrint( 'ofprotocol nl:' + str( self.dp ) + ' tcp:' + self.cmdPrint( 'ofprotocol nl:' + str( self.dp ) + ' tcp:' +
controllers[ 'c0' ].IP() + ':' + controller.IP() + ':' +
str( controllers[ 'c0' ].port ) + str( controller.port ) +
' --fail=closed 1> ' + ofplog + ' 2>' + ofplog + ' &' ) ' --fail=closed 1> ' + ofplog + ' 2>' + ofplog + ' &' )
self.execed = False self.execed = False
...@@ -363,14 +358,14 @@ class OVSKernelSwitch( Switch ): ...@@ -363,14 +358,14 @@ class OVSKernelSwitch( Switch ):
"""Open VSwitch kernel-space switch. """Open VSwitch kernel-space switch.
Currently only works in the root namespace.""" Currently only works in the root namespace."""
def __init__( self, name, dp=None, dpid=None ): def __init__( self, name, dp=None, defaultMac=None ):
"""Init. """Init.
name: name:
dp: netlink id (0, 1, 2, ...) dp: netlink id (0, 1, 2, ...)
dpid: datapath ID as unsigned int; random value if None""" dpid: datapath ID as unsigned int; random value if None"""
Switch.__init__( self, name, inNamespace=False ) Switch.__init__( self, name, inNamespace=False )
self.dp = dp self.dp = dp
self.dpid = dpid self.defaultMac = defaultMac
def start( self, controllers ): def start( self, controllers ):
"Start up kernel datapath." "Start up kernel datapath."
...@@ -380,10 +375,10 @@ def start( self, controllers ): ...@@ -380,10 +375,10 @@ def start( self, controllers ):
# then create a new one monitoring the given interfaces # then create a new one monitoring the given interfaces
quietRun( 'ovs-dpctl del-dp dp%i' % self.dp ) quietRun( 'ovs-dpctl del-dp dp%i' % self.dp )
self.cmdPrint( 'ovs-dpctl add-dp dp%i' % self.dp ) self.cmdPrint( 'ovs-dpctl add-dp dp%i' % self.dp )
if self.dpid: if self.defaultMac:
intf = 'dp' % self.dp intf = 'dp' % self.dp
macStr = macColonHex( self.dpid ) mac = self.defaultMac
self.cmd( [ 'ifconfig', intf, 'hw', 'ether', macStr ] ) self.cmd( [ 'ifconfig', intf, 'hw', 'ether', mac ] )
if len( self.ports ) != max( self.ports.keys() ) + 1: if len( self.ports ) != max( self.ports.keys() ) + 1:
raise Exception( 'only contiguous, zero-indexed port ranges' raise Exception( 'only contiguous, zero-indexed port ranges'
...@@ -392,8 +387,9 @@ def start( self, controllers ): ...@@ -392,8 +387,9 @@ def start( self, controllers ):
self.cmdPrint( 'ovs-dpctl add-if dp' + str( self.dp ) + ' ' + self.cmdPrint( 'ovs-dpctl add-if dp' + str( self.dp ) + ' ' +
' '.join( intfs ) ) ' '.join( intfs ) )
# Run protocol daemon # Run protocol daemon
controller = controllers[ 0 ]
self.cmdPrint( 'ovs-openflowd dp' + str( self.dp ) + ' tcp:' + self.cmdPrint( 'ovs-openflowd dp' + str( self.dp ) + ' tcp:' +
controllers[ 'c0' ].IP() + ':' + controller.IP() + ':' +
' --fail=closed 1> ' + ofplog + ' 2>' + ofplog + ' &' ) ' --fail=closed 1> ' + ofplog + ' 2>' + ofplog + ' &' )
self.execed = False self.execed = False
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment