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