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