From 08d83d136d26e0c4849b31c31f0fda8091dfa797 Mon Sep 17 00:00:00 2001 From: Bob Lantz <rlantz@cs.stanford.edu> Date: Tue, 15 Oct 2013 17:30:42 -0700 Subject: [PATCH] Rename intfs, and add simple moveHost() function --- examples/mobility.py | 87 ++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/examples/mobility.py b/examples/mobility.py index dda400c0..f59b7ae9 100755 --- a/examples/mobility.py +++ b/examples/mobility.py @@ -4,22 +4,12 @@ Simple example of Mobility with Mininet (aka enough rope to hang yourself.) -We move a host from s1 to s2, s2 to s3, -and then back to s1. +We move a host from s1 to s2, s2 to s3, and then back to s1. Gotchas: -1. The interfaces are not renamed; this - means that s1-eth1 will show up on other - 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. +The reference controller doesn't support mobility, so we need to +manually flush the switch flow tables! Good luck! """ @@ -29,33 +19,71 @@ from mininet.topo import LinearTopo from mininet.cli import CLI from mininet.util import dumpNetConnections +from mininet.log import output from time import sleep + class MobilitySwitch( OVSSwitch ): - "Switch that can delete interfaces" + "Switch that can reattach and rename interfaces" def delIntf( self, intf ): - "Remove an interface" + "Remove (and detach) an interface" port = self.ports[ intf ] del self.ports[ intf ] del self.intfs[ port ] 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.delIntf( intf ) + switch.addIntf( intf, rename=True ) + switch.attach( intf ) + switch.validatePort( intf ) def printConnections( switches ): "Compactly print connected nodes to each switch" for sw in switches: - print '%s:' % sw, + output( '%s: ' % sw ) for intf in sw.intfList(): link = intf.link if link: - intfs = [ link.intf1, link.intf2 ] - if intfs[ 0 ].node != sw: - intfs.reverse() - local, remote = intfs - print remote.node, - print + intf1, intf2 = link.intf1, link.intf2 + remote = intf1 if intf1.node != sw else intf2 + output( '%s(%s) ' % ( remote.node, sw.ports[ intf ] ) ) + output( '\n' ) + + +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(): @@ -67,17 +95,12 @@ def mobilityTest(): printConnections( net.switches ) net.pingAll() print '* Identifying switch interface for h1' - h1, s1 = net.get( 'h1', 's1' ) - hintf, sintf = h1.connectionsTo( s1 )[ 0 ] - last = s1 + h1, last = net.get( 'h1', 's1' ) for s in 2, 3, 1: - next = net['s%d' % s ] - print '* Moving', sintf, 'from', last, 'to', next - last.detach( sintf ) - last.delIntf( sintf ) - next.attach( sintf ) - next.addIntf( sintf ) - sintf.node = next + next = net[ 's%d' % s ] + print '* Moving', h1, 'from', last, 'to', next + hintf, sintf = moveHost( h1, last, next ) + print '*', hintf, 'is now connected to', sintf print '* Clearing out old flows' for sw in net.switches: sw.dpctl( 'del-flows' ) -- GitLab