Rename intfs, and add simple moveHost() function
This commit is contained in:
+55
-32
@@ -4,22 +4,12 @@
|
|||||||
Simple example of Mobility with Mininet
|
Simple example of Mobility with Mininet
|
||||||
(aka enough rope to hang yourself.)
|
(aka enough rope to hang yourself.)
|
||||||
|
|
||||||
We move a host from s1 to s2, s2 to s3,
|
We move a host from s1 to s2, s2 to s3, and then back to s1.
|
||||||
and then back to s1.
|
|
||||||
|
|
||||||
Gotchas:
|
Gotchas:
|
||||||
|
|
||||||
1. The interfaces are not renamed; this
|
The reference controller doesn't support mobility, so we need to
|
||||||
means that s1-eth1 will show up on other
|
manually flush the switch flow tables!
|
||||||
switches.
|
|
||||||
|
|
||||||
2. The reference controller doesn't support
|
|
||||||
mobility, so we need to flush the switch
|
|
||||||
flow tables.
|
|
||||||
|
|
||||||
3. The port numbers reported by the switch
|
|
||||||
may not match the actual OpenFlow port
|
|
||||||
numbers used by OVS.
|
|
||||||
|
|
||||||
Good luck!
|
Good luck!
|
||||||
"""
|
"""
|
||||||
@@ -29,33 +19,71 @@ from mininet.node import OVSSwitch, Controller
|
|||||||
from mininet.topo import LinearTopo
|
from mininet.topo import LinearTopo
|
||||||
from mininet.cli import CLI
|
from mininet.cli import CLI
|
||||||
from mininet.util import dumpNetConnections
|
from mininet.util import dumpNetConnections
|
||||||
|
from mininet.log import output
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
|
||||||
class MobilitySwitch( OVSSwitch ):
|
class MobilitySwitch( OVSSwitch ):
|
||||||
"Switch that can delete interfaces"
|
"Switch that can reattach and rename interfaces"
|
||||||
|
|
||||||
def delIntf( self, intf ):
|
def delIntf( self, intf ):
|
||||||
"Remove an interface"
|
"Remove (and detach) an interface"
|
||||||
port = self.ports[ intf ]
|
port = self.ports[ intf ]
|
||||||
del self.ports[ intf ]
|
del self.ports[ intf ]
|
||||||
del self.intfs[ port ]
|
del self.intfs[ port ]
|
||||||
del self.nameToIntf[ intf.name ]
|
del self.nameToIntf[ intf.name ]
|
||||||
|
|
||||||
|
def addIntf( self, intf, rename=True, **kwargs ):
|
||||||
|
"Add (and reparent) an interface"
|
||||||
|
OVSSwitch.addIntf( self, intf, **kwargs )
|
||||||
|
intf.node = self
|
||||||
|
if rename:
|
||||||
|
self.renameIntf( intf )
|
||||||
|
|
||||||
|
def renameIntf( self, intf, newname='' ):
|
||||||
|
"Rename an interface (to its canonical name)"
|
||||||
|
intf.ifconfig( 'down' )
|
||||||
|
if not newname:
|
||||||
|
newname = '%s-eth%d' % ( self.name, self.ports[ intf ] )
|
||||||
|
intf.cmd( 'ip link set', intf, 'name', newname )
|
||||||
|
del self.nameToIntf[ intf.name ]
|
||||||
|
intf.name = newname
|
||||||
|
self.nameToIntf[ intf.name ] = intf
|
||||||
|
intf.ifconfig( 'up' )
|
||||||
|
|
||||||
|
def validatePort( self, intf ):
|
||||||
|
"Validate intf's OF port number"
|
||||||
|
ofport = int( intf.cmd( 'ovs-vsctl get Interface', intf,
|
||||||
|
'ofport' ) )
|
||||||
|
assert ofport == self.ports[ intf ]
|
||||||
|
|
||||||
|
def moveIntf( self, intf, switch, rename=True ):
|
||||||
|
"Move one of our interfaces to another switch"
|
||||||
self.detach( intf )
|
self.detach( intf )
|
||||||
|
self.delIntf( intf )
|
||||||
|
switch.addIntf( intf, rename=True )
|
||||||
|
switch.attach( intf )
|
||||||
|
switch.validatePort( intf )
|
||||||
|
|
||||||
|
|
||||||
def printConnections( switches ):
|
def printConnections( switches ):
|
||||||
"Compactly print connected nodes to each switch"
|
"Compactly print connected nodes to each switch"
|
||||||
for sw in switches:
|
for sw in switches:
|
||||||
print '%s:' % sw,
|
output( '%s: ' % sw )
|
||||||
for intf in sw.intfList():
|
for intf in sw.intfList():
|
||||||
link = intf.link
|
link = intf.link
|
||||||
if link:
|
if link:
|
||||||
intfs = [ link.intf1, link.intf2 ]
|
intf1, intf2 = link.intf1, link.intf2
|
||||||
if intfs[ 0 ].node != sw:
|
remote = intf1 if intf1.node != sw else intf2
|
||||||
intfs.reverse()
|
output( '%s(%s) ' % ( remote.node, sw.ports[ intf ] ) )
|
||||||
local, remote = intfs
|
output( '\n' )
|
||||||
print remote.node,
|
|
||||||
print
|
|
||||||
|
def moveHost( host, oldSwitch, newSwitch ):
|
||||||
|
"Move a host from old switch to new switch"
|
||||||
|
hintf, sintf = host.connectionsTo( oldSwitch )[ 0 ]
|
||||||
|
oldSwitch.moveIntf( sintf, newSwitch )
|
||||||
|
return hintf, sintf
|
||||||
|
|
||||||
|
|
||||||
def mobilityTest():
|
def mobilityTest():
|
||||||
@@ -67,17 +95,12 @@ def mobilityTest():
|
|||||||
printConnections( net.switches )
|
printConnections( net.switches )
|
||||||
net.pingAll()
|
net.pingAll()
|
||||||
print '* Identifying switch interface for h1'
|
print '* Identifying switch interface for h1'
|
||||||
h1, s1 = net.get( 'h1', 's1' )
|
h1, last = net.get( 'h1', 's1' )
|
||||||
hintf, sintf = h1.connectionsTo( s1 )[ 0 ]
|
|
||||||
last = s1
|
|
||||||
for s in 2, 3, 1:
|
for s in 2, 3, 1:
|
||||||
next = net['s%d' % s ]
|
next = net[ 's%d' % s ]
|
||||||
print '* Moving', sintf, 'from', last, 'to', next
|
print '* Moving', h1, 'from', last, 'to', next
|
||||||
last.detach( sintf )
|
hintf, sintf = moveHost( h1, last, next )
|
||||||
last.delIntf( sintf )
|
print '*', hintf, 'is now connected to', sintf
|
||||||
next.attach( sintf )
|
|
||||||
next.addIntf( sintf )
|
|
||||||
sintf.node = next
|
|
||||||
print '* Clearing out old flows'
|
print '* Clearing out old flows'
|
||||||
for sw in net.switches:
|
for sw in net.switches:
|
||||||
sw.dpctl( 'del-flows' )
|
sw.dpctl( 'del-flows' )
|
||||||
|
|||||||
Reference in New Issue
Block a user