Statistics
| Branch: | Tag: | Revision:

mininet / examples / mobility.py @ e0bf8ece

History | View | Annotate | Download (4.1 KB)

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
from mininet.net import Mininet
23
from mininet.node import OVSSwitch
24
from mininet.topo import LinearTopo
25
from mininet.log import output, warn
26

    
27
from random import randint
28

    
29

    
30
class MobilitySwitch( OVSSwitch ):
31
    "Switch that can reattach and rename interfaces"
32

    
33
    def delIntf( self, intf ):
34
        "Remove (and detach) an interface"
35
        port = self.ports[ intf ]
36
        del self.ports[ intf ]
37
        del self.intfs[ port ]
38
        del self.nameToIntf[ intf.name ]
39

    
40
    def addIntf( self, intf, rename=False, **kwargs ):
41
        "Add (and reparent) an interface"
42
        OVSSwitch.addIntf( self, intf, **kwargs )
43
        intf.node = self
44
        if rename:
45
            self.renameIntf( intf )
46

    
47
    def attach( self, intf ):
48
        "Attach an interface and set its port"
49
        port = self.ports[ intf ]
50
        if port:
51
            if self.isOldOVS():
52
                self.cmd( 'ovs-vsctl add-port', self, intf )
53
            else:
54
                self.cmd( 'ovs-vsctl add-port', self, intf,
55
                          '-- set Interface', intf,
56
                          'ofport_request=%s' % port )
57
            self.validatePort( intf )
58

    
59
    def validatePort( self, intf ):
60
        "Validate intf's OF port number"
61
        ofport = int( self.cmd( 'ovs-vsctl get Interface', intf,
62
                              'ofport' ) )
63
        if ofport != self.ports[ intf ]:
64
            warn( 'WARNING: ofport for', intf, 'is actually', ofport,
65
                  '\n' )
66

    
67
    def renameIntf( self, intf, newname='' ):
68
        "Rename an interface (to its canonical name)"
69
        intf.ifconfig( 'down' )
70
        if not newname:
71
            newname = '%s-eth%d' % ( self.name, self.ports[ intf ] )
72
        intf.cmd( 'ip link set', intf, 'name', newname )
73
        del self.nameToIntf[ intf.name ]
74
        intf.name = newname
75
        self.nameToIntf[ intf.name ] = intf
76
        intf.ifconfig( 'up' )
77

    
78
    def moveIntf( self, intf, switch, port=None, rename=True ):
79
        "Move one of our interfaces to another switch"
80
        self.detach( intf )
81
        self.delIntf( intf )
82
        switch.addIntf( intf, port=port, rename=rename )
83
        switch.attach( intf )
84

    
85

    
86
def printConnections( switches ):
87
    "Compactly print connected nodes to each switch"
88
    for sw in switches:
89
        output( '%s: ' % sw )
90
        for intf in sw.intfList():
91
            link = intf.link
92
            if link:
93
                intf1, intf2 = link.intf1, link.intf2
94
                remote = intf1 if intf1.node != sw else intf2
95
                output( '%s(%s) ' % ( remote.node, sw.ports[ intf ] ) )
96
        output( '\n' )
97

    
98

    
99
def moveHost( host, oldSwitch, newSwitch, newPort=None ):
100
    "Move a host from old switch to new switch"
101
    hintf, sintf = host.connectionsTo( oldSwitch )[ 0 ]
102
    oldSwitch.moveIntf( sintf, newSwitch, port=newPort )
103
    return hintf, sintf
104

    
105

    
106
def mobilityTest():
107
    "A simple test of mobility"
108
    print '* Simple mobility test'
109
    net = Mininet( topo=LinearTopo( 3 ), switch=MobilitySwitch )
110
    print '* Starting network:'
111
    net.start()
112
    printConnections( net.switches )
113
    print '* Testing network'
114
    net.pingAll()
115
    print '* Identifying switch interface for h1'
116
    h1, old = net.get( 'h1', 's1' )
117
    for s in 2, 3, 1:
118
        new = net[ 's%d' % s ]
119
        port = randint( 10, 20 )
120
        print '* Moving', h1, 'from', old, 'to', new, 'port', port
121
        hintf, sintf = moveHost( h1, old, new, newPort=port )
122
        print '*', hintf, 'is now connected to', sintf
123
        print '* Clearing out old flows'
124
        for sw in net.switches:
125
            sw.dpctl( 'del-flows' )
126
        print '* New network:'
127
        printConnections( net.switches )
128
        print '* Testing connectivity:'
129
        net.pingAll()
130
        old = new
131
    net.stop()
132

    
133
if __name__ == '__main__':
134
    mobilityTest()