4 Simple example of Mobility with Mininet
5 (aka enough rope to hang yourself.)
7 We move a host from s1 to s2, s2 to s3, and then back to s1.
11 The reference controller doesn't support mobility, so we need to
12 manually flush the switch flow tables!
18 - think about wifi/hub behavior
19 - think about clearing last hop - why doesn't that work?
23 from mininet.net import Mininet
24 from mininet.node import OVSSwitch
25 from mininet.topo import LinearTopo
26 from mininet.log import info, output, warn, setLogLevel
28 from random import randint
31 class MobilitySwitch( OVSSwitch ):
32 "Switch that can reattach and rename interfaces"
34 def delIntf( self, intf ):
35 "Remove (and detach) an interface"
36 port = self.ports[ intf ]
37 del self.ports[ intf ]
38 del self.intfs[ port ]
39 del self.nameToIntf[ intf.name ]
41 def addIntf( self, intf, rename=False, **kwargs ):
42 "Add (and reparent) an interface"
43 OVSSwitch.addIntf( self, intf, **kwargs )
46 self.renameIntf( intf )
48 def attach( self, intf ):
49 "Attach an interface and set its port"
50 port = self.ports[ intf ]
53 self.cmd( 'ovs-vsctl add-port', self, intf )
55 self.cmd( 'ovs-vsctl add-port', self, intf,
56 '-- set Interface', intf,
57 'ofport_request=%s' % port )
58 self.validatePort( intf )
60 def validatePort( self, intf ):
61 "Validate intf's OF port number"
62 ofport = int( self.cmd( 'ovs-vsctl get Interface', intf,
64 if ofport != self.ports[ intf ]:
65 warn( 'WARNING: ofport for', intf, 'is actually', ofport,
68 def renameIntf( self, intf, newname='' ):
69 "Rename an interface (to its canonical name)"
70 intf.ifconfig( 'down' )
72 newname = '%s-eth%d' % ( self.name, self.ports[ intf ] )
73 intf.cmd( 'ip link set', intf, 'name', newname )
74 del self.nameToIntf[ intf.name ]
76 self.nameToIntf[ intf.name ] = intf
79 def moveIntf( self, intf, switch, port=None, rename=True ):
80 "Move one of our interfaces to another switch"
83 switch.addIntf( intf, port=port, rename=rename )
87 def printConnections( switches ):
88 "Compactly print connected nodes to each switch"
91 for intf in sw.intfList():
94 intf1, intf2 = link.intf1, link.intf2
95 remote = intf1 if intf1.node != sw else intf2
96 output( '%s(%s) ' % ( remote.node, sw.ports[ intf ] ) )
100 def moveHost( host, oldSwitch, newSwitch, newPort=None ):
101 "Move a host from old switch to new switch"
102 hintf, sintf = host.connectionsTo( oldSwitch )[ 0 ]
103 oldSwitch.moveIntf( sintf, newSwitch, port=newPort )
108 "A simple test of mobility"
109 info( '* Simple mobility test\n' )
110 net = Mininet( topo=LinearTopo( 3 ), switch=MobilitySwitch )
111 info( '* Starting network:\n' )
113 printConnections( net.switches )
114 info( '* Testing network\n' )
116 info( '* Identifying switch interface for h1\n' )
117 h1, old = net.get( 'h1', 's1' )
119 new = net[ 's%d' % s ]
120 port = randint( 10, 20 )
121 info( '* Moving', h1, 'from', old, 'to', new, 'port', port, '\n' )
122 hintf, sintf = moveHost( h1, old, new, newPort=port )
123 info( '*', hintf, 'is now connected to', sintf, '\n' )
124 info( '* Clearing out old flows\n' )
125 for sw in net.switches:
126 sw.dpctl( 'del-flows' )
127 info( '* New network:\n' )
128 printConnections( net.switches )
129 info( '* Testing connectivity:\n' )
134 if __name__ == '__main__':
135 setLogLevel( 'info' )