Statistics
| Branch: | Tag: | Revision:

mininet / examples / controlnet.py @ 9bfc7c77

History | View | Annotate | Download (4.54 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
def run():
113
    info( '* Creating Control Network\n' )
114
    ctopo = ControlNetwork( n=4, dataController=DataController )
115
    cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None )
116
    info( '* Adding Control Network Controller\n')
117
    cnet.addController( 'cc0', controller=Controller )
118
    info( '* Starting Control Network\n')
119
    cnet.start()
120

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

    
132
    mn = MininetFacade( net, cnet=cnet )
133

    
134
    # run the function passed as an argument
135
    CLI( mn )
136

    
137
    info( '* Stopping Data Network\n' )
138
    net.stop()
139

    
140
    info( '* Stopping Control Network\n' )
141
    cnet.stop()
142

    
143
if __name__ == '__main__':
144
    setLogLevel( 'info' )
145

    
146
    run()