Statistics
| Branch: | Tag: | Revision:

mininet / examples / controlnet.py @ 0fac568a

History | View | Annotate | Download (4.85 KB)

1 32502bbd Bob Lantz
#!/usr/bin/python
2
3
"""
4
controlnet.py: Mininet with a custom control network
5

6
We create two Mininet() networks, a control network
7
and a data network, running four DataControllers on the
8
control network to control the data network.
9

10
Since we're using UserSwitch on the data network,
11
it should correctly fail over to a backup controller.
12

13 e935da46 Brian O'Connor
We also use a Mininet Facade to talk to both the
14
control and data networks from a single CLI.
15 32502bbd Bob Lantz
"""
16
17 cfb6bf95 Brian O'Connor
from functools import partial
18
19 32502bbd Bob Lantz
from mininet.net import Mininet
20
from mininet.node import Controller, UserSwitch
21
from mininet.cli import CLI
22
from mininet.topo import Topo
23
from mininet.topolib import TreeTopo
24
from mininet.log import setLogLevel, info
25
26
# Some minor hacks
27
28
class DataController( Controller ):
29
    """Data Network Controller.
30 9483f637 Bob Lantz
       patched to avoid checkListening error and to delete intfs"""
31 4ac45a39 Bob Lantz
32 32502bbd Bob Lantz
    def checkListening( self ):
33
        "Ignore spurious error"
34
        pass
35
36 9483f637 Bob Lantz
    def stop( self, *args, **kwargs ):
37
        "Make sure intfs are deleted"
38
        kwargs.update( deleteIntfs=True )
39 4ac45a39 Bob Lantz
        super( DataController, self ).stop( *args, **kwargs )
40
41 9483f637 Bob Lantz
42 7c962d2f Brian O'Connor
class MininetFacade( object ):
43 e935da46 Brian O'Connor
    """Mininet object facade that allows a single CLI to
44
       talk to one or more networks"""
45 5a530af1 Bob Lantz
46 7c962d2f Brian O'Connor
    def __init__( self, net, *args, **kwargs ):
47 e935da46 Brian O'Connor
        """Create MininetFacade object.
48
           net: Primary Mininet object
49
           args: unnamed networks passed as arguments
50
           kwargs: named networks passed as arguments"""
51 7c962d2f Brian O'Connor
        self.net = net
52
        self.nets = [ net ] + list( args ) + kwargs.values()
53
        self.nameToNet = kwargs
54
        self.nameToNet['net'] = net
55 15146d90 Brian O'Connor
56
    def __getattr__( self, name ):
57 e935da46 Brian O'Connor
        "returns attribute from Primary Mininet object"
58 7c962d2f Brian O'Connor
        return getattr( self.net, name )
59 15146d90 Brian O'Connor
60
    def __getitem__( self, key ):
61 e935da46 Brian O'Connor
        "returns primary/named networks or node from any net"
62 7c962d2f Brian O'Connor
        #search kwargs for net named key
63
        if key in self.nameToNet:
64
            return self.nameToNet[ key ]
65
        #search each net for node named key
66 15146d90 Brian O'Connor
        for net in self.nets:
67
            if key in net:
68
                return net[ key ]
69
70
    def __iter__( self ):
71 e935da46 Brian O'Connor
        "Iterate through all nodes in all Mininet objects"
72 15146d90 Brian O'Connor
        for net in self.nets:
73
            for node in net:
74
                yield node
75
76
    def __len__( self ):
77 e935da46 Brian O'Connor
        "returns aggregate number of nodes in all nets"
78 15146d90 Brian O'Connor
        count = 0
79
        for net in self.nets:
80
            count += len(net)
81
        return count
82
83
    def __contains__( self, key ):
84 e935da46 Brian O'Connor
        "returns True if node is a member of any net"
85 15146d90 Brian O'Connor
        return key in self.keys()
86
87
    def keys( self ):
88 e935da46 Brian O'Connor
        "returns a list of all node names in all networks"
89 15146d90 Brian O'Connor
        return list( self )
90
91
    def values( self ):
92 e935da46 Brian O'Connor
        "returns a list of all nodes in all networks"
93 15146d90 Brian O'Connor
        return [ self[ key ] for key in self ]
94 32502bbd Bob Lantz
95 15146d90 Brian O'Connor
    def items( self ):
96 e935da46 Brian O'Connor
        "returns (key,value) tuple list for every node in all networks"
97 15146d90 Brian O'Connor
        return zip( self.keys(), self.values() )
98 32502bbd Bob Lantz
99
# A real control network!
100
101
class ControlNetwork( Topo ):
102
    "Control Network Topology"
103
    def __init__( self, n, dataController=DataController, **kwargs ):
104
        """n: number of data network controller nodes
105
           dataController: class for data network controllers"""
106
        Topo.__init__( self, **kwargs )
107
        # Connect everything to a single switch
108
        cs0 = self.addSwitch( 'cs0' )
109
        # Add hosts which will serve as data network controllers
110
        for i in range( 0, n ):
111
            c = self.addHost( 'c%s' % i, cls=dataController,
112
                              inNamespace=True )
113
            self.addLink( c, cs0 )
114
        # Connect switch to root namespace so that data network
115
        # switches will be able to talk to us
116
        root = self.addHost( 'root', inNamespace=False )
117
        self.addLink( root, cs0 )
118
119
120
# Make it Happen!!
121 13554a3d Bob Lantz
122 3a35480c Brian O'Connor
def run():
123 13554a3d Bob Lantz
    "Create control and data networks, and invoke the CLI"
124 5a530af1 Bob Lantz
125 7c962d2f Brian O'Connor
    info( '* Creating Control Network\n' )
126
    ctopo = ControlNetwork( n=4, dataController=DataController )
127
    cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None )
128
    info( '* Adding Control Network Controller\n')
129
    cnet.addController( 'cc0', controller=Controller )
130
    info( '* Starting Control Network\n')
131
    cnet.start()
132
133
    info( '* Creating Data Network\n' )
134
    topo = TreeTopo( depth=2, fanout=2 )
135
    # UserSwitch so we can easily test failover
136 cfb6bf95 Brian O'Connor
    sw = partial( UserSwitch, opts='--inactivity-probe=1 --max-backoff=1' )
137
    net = Mininet( topo=topo, switch=sw, controller=None )
138 7c962d2f Brian O'Connor
    info( '* Adding Controllers to Data Network\n' )
139
    for host in cnet.hosts:
140
        if isinstance(host, Controller):
141
            net.addController( host )
142
    info( '* Starting Data Network\n')
143
    net.start()
144
145
    mn = MininetFacade( net, cnet=cnet )
146
147 3a35480c Brian O'Connor
    CLI( mn )
148 7c962d2f Brian O'Connor
149
    info( '* Stopping Data Network\n' )
150
    net.stop()
151
152
    info( '* Stopping Control Network\n' )
153
    cnet.stop()
154
155 13554a3d Bob Lantz
156 7c962d2f Brian O'Connor
if __name__ == '__main__':
157
    setLogLevel( 'info' )
158 3a35480c Brian O'Connor
    run()