Statistics
| Branch: | Tag: | Revision:

mininet / examples / controlnet.py @ 13554a3d

History | View | Annotate | Download (4.56 KB)

1
#!/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
We also use a Mininet Facade to talk to both the
14
control and data networks from a single CLI.
15
"""
16

    
17
from mininet.net import Mininet
18
from mininet.node import Controller, UserSwitch
19
from mininet.cli import CLI
20
from mininet.topo import Topo
21
from mininet.topolib import TreeTopo
22
from mininet.log import setLogLevel, info
23

    
24
# Some minor hacks
25

    
26
class DataController( Controller ):
27
    """Data Network Controller.
28
       patched to avoid checkListening error"""
29
    def checkListening( self ):
30
        "Ignore spurious error"
31
        pass
32

    
33
class MininetFacade( object ):
34
    """Mininet object facade that allows a single CLI to
35
       talk to one or more networks"""
36
    
37
    def __init__( self, net, *args, **kwargs ):
38
        """Create MininetFacade object.
39
           net: Primary Mininet object
40
           args: unnamed networks passed as arguments
41
           kwargs: named networks passed as arguments"""
42
        self.net = net
43
        self.nets = [ net ] + list( args ) + kwargs.values()
44
        self.nameToNet = kwargs
45
        self.nameToNet['net'] = net
46

    
47
    def __getattr__( self, name ):
48
        "returns attribute from Primary Mininet object"
49
        return getattr( self.net, name )
50

    
51
    def __getitem__( self, key ):
52
        "returns primary/named networks or node from any net"
53
        #search kwargs for net named key
54
        if key in self.nameToNet:
55
            return self.nameToNet[ key ]
56
        #search each net for node named key
57
        for net in self.nets:
58
            if key in net:
59
                return net[ key ]
60

    
61
    def __iter__( self ):
62
        "Iterate through all nodes in all Mininet objects"
63
        for net in self.nets:
64
            for node in net:
65
                yield node
66

    
67
    def __len__( self ):
68
        "returns aggregate number of nodes in all nets"
69
        count = 0
70
        for net in self.nets:
71
            count += len(net)
72
        return count
73

    
74
    def __contains__( self, key ):
75
        "returns True if node is a member of any net"
76
        return key in self.keys()
77

    
78
    def keys( self ):
79
        "returns a list of all node names in all networks"
80
        return list( self )
81

    
82
    def values( self ):
83
        "returns a list of all nodes in all networks"
84
        return [ self[ key ] for key in self ]
85

    
86
    def items( self ):
87
        "returns (key,value) tuple list for every node in all networks"
88
        return zip( self.keys(), self.values() )
89

    
90
# A real control network!
91

    
92
class ControlNetwork( Topo ):
93
    "Control Network Topology"
94
    def __init__( self, n, dataController=DataController, **kwargs ):
95
        """n: number of data network controller nodes
96
           dataController: class for data network controllers"""
97
        Topo.__init__( self, **kwargs )
98
        # Connect everything to a single switch
99
        cs0 = self.addSwitch( 'cs0' )
100
        # Add hosts which will serve as data network controllers
101
        for i in range( 0, n ):
102
            c = self.addHost( 'c%s' % i, cls=dataController,
103
                              inNamespace=True )
104
            self.addLink( c, cs0 )
105
        # Connect switch to root namespace so that data network
106
        # switches will be able to talk to us
107
        root = self.addHost( 'root', inNamespace=False )
108
        self.addLink( root, cs0 )
109

    
110

    
111
# Make it Happen!!
112

    
113
def run():
114
    "Create control and data networks, and invoke the CLI"
115
    
116
    info( '* Creating Control Network\n' )
117
    ctopo = ControlNetwork( n=4, dataController=DataController )
118
    cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None )
119
    info( '* Adding Control Network Controller\n')
120
    cnet.addController( 'cc0', controller=Controller )
121
    info( '* Starting Control Network\n')
122
    cnet.start()
123

    
124
    info( '* Creating Data Network\n' )
125
    topo = TreeTopo( depth=2, fanout=2 )
126
    # UserSwitch so we can easily test failover
127
    net = Mininet( topo=topo, switch=UserSwitch, controller=None )
128
    info( '* Adding Controllers to Data Network\n' )
129
    for host in cnet.hosts:
130
        if isinstance(host, Controller):
131
            net.addController( host )
132
    info( '* Starting Data Network\n')
133
    net.start()
134

    
135
    mn = MininetFacade( net, cnet=cnet )
136

    
137
    CLI( mn )
138

    
139
    info( '* Stopping Data Network\n' )
140
    net.stop()
141

    
142
    info( '* Stopping Control Network\n' )
143
    cnet.stop()
144

    
145

    
146
if __name__ == '__main__':
147
    setLogLevel( 'info' )
148
    run()