Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | |
| 3 | import os |
| 4 | from optparse import OptionParser |
| 5 | |
| 6 | from mininet.net import Mininet |
| 7 | from mininet.topo import Topo |
| 8 | from mininet.node import RemoteController, UserSwitch, Host |
| 9 | from mininet.link import TCLink |
| 10 | from mininet.log import setLogLevel |
| 11 | from mininet.cli import CLI |
| 12 | |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 13 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 14 | # Parse command line options and dump results |
| 15 | def parseOptions( ): |
| 16 | """Parse command line options""" |
| 17 | parser = OptionParser( ) |
| 18 | parser.add_option( '--spine', dest='spine', type='int', default=2, |
| 19 | help='number of spine switches, default=2' ) |
| 20 | parser.add_option( '--leaf', dest='leaf', type='int', default=2, |
| 21 | help='number of leaf switches, default=2' ) |
| 22 | parser.add_option( '--fanout', dest='fanout', type='int', default=2, |
| 23 | help='number of hosts per leaf switch, default=2' ) |
| 24 | parser.add_option( '--onos', dest='onos', type='int', default=0, |
| 25 | help='number of ONOS Instances, default=0, 0 means localhost, 1 will use OC1 and so on' ) |
| 26 | |
| 27 | (options, args) = parser.parse_args( ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 28 | return options, args |
| 29 | |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 30 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 31 | opts, args = parseOptions( ) |
| 32 | |
| 33 | |
| 34 | class LeafAndSpine( Topo ): |
| 35 | def __init__( self, spine=2, leaf=2, fanout=2, **opts ): |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 36 | "Create Leaf and Spine Topo." |
| 37 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 38 | Topo.__init__( self, **opts ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 39 | |
| 40 | # Add spine switches |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 41 | spines = { } |
| 42 | for s in range( spine ): |
| 43 | spines[ s ] = self.addSwitch( 'spine10%s' % (s + 1), |
| 44 | dpid="00000000010%s" % (s + 1) ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 45 | # Set link speeds to 100Mb/s |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 46 | linkopts = dict( bw=100 ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 47 | |
| 48 | # Add Leaf switches |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 49 | for ls in range( leaf ): |
| 50 | leafSwitch = self.addSwitch( 'leaf%s' % (ls + 1), |
| 51 | dpid="00000000000%s" % (1 + ls) ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 52 | # Connect leaf to all spines |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 53 | for s in range( spine ): |
| 54 | switch = spines[ s ] |
| 55 | self.addLink( leafSwitch, switch, **linkopts ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 56 | # Add hosts under a leaf, fanout hosts per leaf switch |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 57 | for f in range( fanout ): |
| 58 | host = self.addHost( 'h%s' % (ls * fanout + f + 1), |
| 59 | cls=IpHost, |
| 60 | ip='10.0.%s.%s/24' % ((ls + 1), (f + 1)), |
| 61 | gateway='10.0.%s.254' % (ls + 1) ) |
| 62 | self.addLink( host, leafSwitch, **linkopts ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 63 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 64 | |
| 65 | class IpHost( Host ): |
| 66 | def __init__( self, name, gateway, *args, **kwargs ): |
| 67 | super( IpHost, self ).__init__( name, *args, **kwargs ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 68 | self.gateway = gateway |
| 69 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 70 | def config( self, **kwargs ): |
| 71 | Host.config( self, **kwargs ) |
| 72 | mtu = "ifconfig " + self.name + "-eth0 mtu 1490" |
| 73 | self.cmd( mtu ) |
| 74 | self.cmd( 'ip route add default via %s' % self.gateway ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 75 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 76 | |
| 77 | def config( opts ): |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 78 | spine = opts.spine |
| 79 | leaf = opts.leaf |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 80 | fanout = opts.fanout |
| 81 | controllers = [ os.environ[ 'OC%s' % i ] for i in |
| 82 | range( 1, opts.onos + 1 ) ] if (opts.onos) else [ |
| 83 | '127.0.0.1' ] |
| 84 | topo = LeafAndSpine( spine=spine, leaf=leaf, fanout=fanout ) |
| 85 | net = Mininet( topo=topo, link=TCLink, build=False, |
| 86 | switch=UserSwitch, |
| 87 | controller=None, |
| 88 | autoSetMacs=True ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 89 | i = 0 |
| 90 | for ip in controllers: |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 91 | net.addController( "c%s" % (i), controller=RemoteController, ip=ip ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 92 | i += 1; |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 93 | net.build( ) |
| 94 | net.start( ) |
| 95 | CLI( net ) |
| 96 | net.stop( ) |
| 97 | |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 98 | |
| 99 | if __name__ == '__main__': |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 100 | setLogLevel( 'info' ) |
| 101 | config( opts ) |
| 102 | os.system( 'sudo mn -c' ) |