From 212399feaf5b98d012a1ff8636713cb2eb4dc486 Mon Sep 17 00:00:00 2001 From: Bob Lantz <rlantz@cs.stanford.edu> Date: Wed, 16 Oct 2013 18:41:06 -0700 Subject: [PATCH] Allow port selection in addIntf() and moveIntf() --- examples/mobility.py | 77 ++++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/examples/mobility.py b/examples/mobility.py index f59b7ae9..c5659479 100755 --- a/examples/mobility.py +++ b/examples/mobility.py @@ -12,20 +12,32 @@ manually flush the switch flow tables! Good luck! + +to-do: + +- think about wifi/hub behavior +- think about clearing last hop - why doesn't that work? """ from mininet.net import Mininet -from mininet.node import OVSSwitch, Controller +from mininet.node import OVSSwitch from mininet.topo import LinearTopo -from mininet.cli import CLI -from mininet.util import dumpNetConnections -from mininet.log import output -from time import sleep +from mininet.util import quietRun +from mininet.log import output, warn +from random import randint +from re import findall class MobilitySwitch( OVSSwitch ): "Switch that can reattach and rename interfaces" + @classmethod + def setup( cls ): + "Call our parent method and determine OVS version" + OVSSwitch.setup() + info = quietRun( 'ovs-vsctl --version' ) + cls.OVSVersion = float( findall( '\d+\.\d+', info )[ 0 ] ) + def delIntf( self, intf ): "Remove (and detach) an interface" port = self.ports[ intf ] @@ -33,13 +45,33 @@ def delIntf( self, intf ): del self.intfs[ port ] del self.nameToIntf[ intf.name ] - def addIntf( self, intf, rename=True, **kwargs ): + def addIntf( self, intf, rename=False, **kwargs ): "Add (and reparent) an interface" OVSSwitch.addIntf( self, intf, **kwargs ) intf.node = self if rename: self.renameIntf( intf ) + def attach( self, intf ): + "Attach an interface and set its port" + port = self.ports[ intf ] + if port: + if MobilitySwitch.OVSVersion >= 1.10: + self.cmd( 'ovs-vsctl add-port', self, intf, + '-- set Interface', intf, + 'ofport_request=%s' % port ) + else: + self.cmd( 'ovs-vsctl add-port', self, intf ) + self.validatePort( intf ) + + def validatePort( self, intf ): + "Validate intf's OF port number" + ofport = int( self.cmd( 'ovs-vsctl get Interface', intf, + 'ofport' ) ) + if ofport != self.ports[ intf ]: + warn( 'WARNING: ofport for', intf, 'is', ofport, + 'but we wanted', self.ports[ intf ], '\n' ) + def renameIntf( self, intf, newname='' ): "Rename an interface (to its canonical name)" intf.ifconfig( 'down' ) @@ -51,19 +83,12 @@ def renameIntf( self, intf, 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 ): + def moveIntf( self, intf, switch, port=None, rename=True ): "Move one of our interfaces to another switch" self.detach( intf ) self.delIntf( intf ) - switch.addIntf( intf, rename=True ) + switch.addIntf( intf, port=port, rename=True ) switch.attach( intf ) - switch.validatePort( intf ) def printConnections( switches ): @@ -79,10 +104,10 @@ def printConnections( switches ): output( '\n' ) -def moveHost( host, oldSwitch, newSwitch ): +def moveHost( host, oldSwitch, newSwitch, newPort=None ): "Move a host from old switch to new switch" hintf, sintf = host.connectionsTo( oldSwitch )[ 0 ] - oldSwitch.moveIntf( sintf, newSwitch ) + oldSwitch.moveIntf( sintf, newSwitch, port=newPort ) return hintf, sintf @@ -90,16 +115,21 @@ def mobilityTest(): "A simple test of mobility" print '* Simple mobility test' net = Mininet( topo=LinearTopo( 3 ), switch=MobilitySwitch ) - net.start() print '* Starting network:' + net.start() printConnections( net.switches ) + if MobilitySwitch.OVSVersion < 1.10: + print '* WARNING: port selection may not work in OVS', + print MobilitySwitch.OVSVersion + print '* Testing network' net.pingAll() print '* Identifying switch interface for h1' - h1, last = net.get( 'h1', 's1' ) + h1, old = net.get( 'h1', 's1' ) for s in 2, 3, 1: - next = net[ 's%d' % s ] - print '* Moving', h1, 'from', last, 'to', next - hintf, sintf = moveHost( h1, last, next ) + new = net[ 's%d' % s ] + port = randint( 10, 20 ) + print '* Moving', h1, 'from', old, 'to', new, 'port', port + hintf, sintf = moveHost( h1, old, new, newPort=port ) print '*', hintf, 'is now connected to', sintf print '* Clearing out old flows' for sw in net.switches: @@ -108,9 +138,8 @@ def mobilityTest(): printConnections( net.switches ) print '* Testing connectivity:' net.pingAll() - last = next + old = new net.stop() if __name__ == '__main__': mobilityTest() - -- GitLab