Update and rename MantenerFIFO to MantenerFIFO.md
[vsorcdistro/.git] / mininet / examples / mobility.py
1 #!/usr/bin/python
2
3 """
4 Simple example of Mobility with Mininet
5 (aka enough rope to hang yourself.)
6
7 We move a host from s1 to s2, s2 to s3, and then back to s1.
8
9 Gotchas:
10
11 The reference controller doesn't support mobility, so we need to
12 manually flush the switch flow tables!
13
14 Good luck!
15
16 to-do:
17
18 - think about wifi/hub behavior
19 - think about clearing last hop - why doesn't that work?
20 """
21
22
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
27
28 from random import randint
29
30
31 class MobilitySwitch( OVSSwitch ):
32     "Switch that can reattach and rename interfaces"
33
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 ]
40
41     def addIntf( self, intf, rename=False, **kwargs ):
42         "Add (and reparent) an interface"
43         OVSSwitch.addIntf( self, intf, **kwargs )
44         intf.node = self
45         if rename:
46             self.renameIntf( intf )
47
48     def attach( self, intf ):
49         "Attach an interface and set its port"
50         port = self.ports[ intf ]
51         if port:
52             if self.isOldOVS():
53                 self.cmd( 'ovs-vsctl add-port', self, intf )
54             else:
55                 self.cmd( 'ovs-vsctl add-port', self, intf,
56                           '-- set Interface', intf,
57                           'ofport_request=%s' % port )
58             self.validatePort( intf )
59
60     def validatePort( self, intf ):
61         "Validate intf's OF port number"
62         ofport = int( self.cmd( 'ovs-vsctl get Interface', intf,
63                                 'ofport' ) )
64         if ofport != self.ports[ intf ]:
65             warn( 'WARNING: ofport for', intf, 'is actually', ofport,
66                   '\n' )
67
68     def renameIntf( self, intf, newname='' ):
69         "Rename an interface (to its canonical name)"
70         intf.ifconfig( 'down' )
71         if not newname:
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 ]
75         intf.name = newname
76         self.nameToIntf[ intf.name ] = intf
77         intf.ifconfig( 'up' )
78
79     def moveIntf( self, intf, switch, port=None, rename=True ):
80         "Move one of our interfaces to another switch"
81         self.detach( intf )
82         self.delIntf( intf )
83         switch.addIntf( intf, port=port, rename=rename )
84         switch.attach( intf )
85
86
87 def printConnections( switches ):
88     "Compactly print connected nodes to each switch"
89     for sw in switches:
90         output( '%s: ' % sw )
91         for intf in sw.intfList():
92             link = intf.link
93             if link:
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 ] ) )
97         output( '\n' )
98
99
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 )
104     return hintf, sintf
105
106
107 def mobilityTest():
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' )
112     net.start()
113     printConnections( net.switches )
114     info( '* Testing network\n' )
115     net.pingAll()
116     info( '* Identifying switch interface for h1\n' )
117     h1, old = net.get( 'h1', 's1' )
118     for s in 2, 3, 1:
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' )
130         net.pingAll()
131         old = new
132     net.stop()
133
134 if __name__ == '__main__':
135     setLogLevel( 'info' )
136     mobilityTest()