Carmelo Cascone | b34d8e1 | 2020-09-28 16:16:59 -0700 | [diff] [blame^] | 1 | #!/usr/bin/python3 |
Bob Lantz | 894eab5 | 2016-08-29 18:24:39 -0700 | [diff] [blame] | 2 | """ |
| 3 | multicluster.py: multiple ONOS clusters example |
| 4 | |
| 5 | We create two ONOSClusters, "east" and "west", and |
| 6 | a LinearTopo data network where the first and second halves |
| 7 | of the network are connected to each ONOSCluster, |
| 8 | respectively. |
| 9 | |
| 10 | The size of the ONOSCluster is determined by its |
| 11 | topology. In this example the topology is a |
| 12 | SingleSwitchTopo of size 1, so the "Cluster" is |
| 13 | actually a single node (for performance and |
| 14 | resource usage reasons.) However, it is possible |
| 15 | to use larger cluster sizes in a large (!) Mininet VM, |
| 16 | (e.g. 12 GB of RAM for two 3-node ONOS clusters.) |
| 17 | |
| 18 | The MultiSwitch class is a customized version of |
| 19 | ONOSOVSSwitch that has a "controller" instance variable |
| 20 | (and parameter) |
| 21 | """ |
| 22 | |
| 23 | from mininet.net import Mininet |
| 24 | from mininet.topo import LinearTopo, SingleSwitchTopo |
| 25 | from mininet.log import setLogLevel |
| 26 | from mininet.topolib import TreeTopo |
| 27 | from mininet.clean import cleanup |
| 28 | |
| 29 | from onos import ONOSCluster, ONOSOVSSwitch, ONOSCLI, RenamedTopo |
| 30 | |
| 31 | |
| 32 | class MultiSwitch( ONOSOVSSwitch ): |
| 33 | "Custom OVSSwitch() subclass that connects to different clusters" |
| 34 | |
| 35 | def __init__( self, *args, **kwargs ): |
| 36 | "controller: controller/ONOSCluster to connect to" |
| 37 | self.controller = kwargs.pop( 'controller', None ) |
| 38 | ONOSOVSSwitch.__init__( self, *args, **kwargs ) |
| 39 | |
| 40 | def start( self, controllers ): |
| 41 | "Start and connect to our previously specified controller" |
| 42 | return ONOSOVSSwitch.start( self, [ self.controller ] ) |
| 43 | |
| 44 | |
| 45 | def run(): |
| 46 | "Test a multiple ONOS cluster network" |
| 47 | setLogLevel( 'info' ) |
| 48 | # East and west control network topologies (using RenamedTopo) |
| 49 | # We specify switch and host prefixes to avoid name collisions |
| 50 | # East control switch prefix: 'east_cs', ONOS node prefix: 'east_onos' |
| 51 | # Each network is a renamed SingleSwitchTopo of size clusterSize |
| 52 | # It's also possible to specify your own control network topology |
| 53 | clusterSize = 1 |
| 54 | etopo = RenamedTopo( SingleSwitchTopo, clusterSize, |
| 55 | snew='east_cs', hnew='east_onos' ) |
| 56 | wtopo = RenamedTopo( SingleSwitchTopo, clusterSize, |
| 57 | snew='west_cs', hnew='west_onos' ) |
| 58 | # east and west ONOS clusters |
| 59 | # Note that we specify the NAT node names to avoid name collisions |
| 60 | east = ONOSCluster( 'east', topo=etopo, ipBase='192.168.123.0/24', |
| 61 | nat='enat0' ) |
| 62 | west = ONOSCluster( 'west', topo=wtopo, ipBase='192.168.124.0/24', |
| 63 | nat='wnat0' ) |
| 64 | # Data network topology |
| 65 | topo = LinearTopo( 10 ) |
| 66 | # Create network |
| 67 | net = Mininet( topo=topo, switch=MultiSwitch, controller=[ east, west ] ) |
| 68 | # Assign switches to controllers |
| 69 | count = len( net.switches ) |
| 70 | for i, switch in enumerate( net.switches ): |
| 71 | switch.controller = east if i < count/2 else west |
| 72 | # Start up network |
| 73 | net.start() |
| 74 | ONOSCLI( net ) # run our special unified Mininet/ONOS CLI |
| 75 | net.stop() |
| 76 | |
| 77 | # Add a "controllers" command to ONOSCLI |
| 78 | |
| 79 | def do_controllers( self, line ): |
| 80 | "List controllers assigned to switches" |
| 81 | cmap = {} |
| 82 | for s in self.mn.switches: |
| 83 | c = getattr( s, 'controller', None ).name |
| 84 | cmap.setdefault( c, [] ).append( s.name ) |
| 85 | for c in sorted( cmap.keys() ): |
| 86 | switches = ' '.join( cmap[ c ] ) |
Carmelo Cascone | b34d8e1 | 2020-09-28 16:16:59 -0700 | [diff] [blame^] | 87 | print('%s: %s' % ( c, switches )) |
Bob Lantz | 894eab5 | 2016-08-29 18:24:39 -0700 | [diff] [blame] | 88 | |
| 89 | ONOSCLI.do_controllers = do_controllers |
| 90 | |
| 91 | |
| 92 | if __name__ == '__main__': |
| 93 | run() |