blob: 4f52689fbcaecacd305d775f3be0a9f0a753670f [file] [log] [blame]
Flavio Castrocc38a542016-03-03 13:15:46 -08001#!/usr/bin/python
2
3import os
4from optparse import OptionParser
5
6from mininet.net import Mininet
7from mininet.topo import Topo
Flavio Castroe168f7f2016-06-24 15:53:12 -07008from mininet.node import RemoteController, UserSwitch, Host, OVSBridge
Flavio Castrocc38a542016-03-03 13:15:46 -08009from mininet.link import TCLink
10from mininet.log import setLogLevel
11from mininet.cli import CLI
12
Flavio Castrocc38a542016-03-03 13:15:46 -080013
Flavio Castro5608a392016-06-22 17:02:35 -070014# Parse command line options and dump results
15def 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' )
Flavio Castro5608a392016-06-22 17:02:35 -070026 (options, args) = parser.parse_args( )
Flavio Castrocc38a542016-03-03 13:15:46 -080027 return options, args
28
Flavio Castrocc38a542016-03-03 13:15:46 -080029
Flavio Castro5608a392016-06-22 17:02:35 -070030opts, args = parseOptions( )
31
32
33class LeafAndSpine( Topo ):
34 def __init__( self, spine=2, leaf=2, fanout=2, **opts ):
Flavio Castrocc38a542016-03-03 13:15:46 -080035 "Create Leaf and Spine Topo."
Flavio Castro5608a392016-06-22 17:02:35 -070036 Topo.__init__( self, **opts )
Flavio Castrocc38a542016-03-03 13:15:46 -080037 # Add spine switches
Flavio Castro5608a392016-06-22 17:02:35 -070038 spines = { }
Flavio Castroe168f7f2016-06-24 15:53:12 -070039 leafs = { }
Flavio Castro5608a392016-06-22 17:02:35 -070040 for s in range( spine ):
41 spines[ s ] = self.addSwitch( 'spine10%s' % (s + 1),
42 dpid="00000000010%s" % (s + 1) )
Flavio Castrocc38a542016-03-03 13:15:46 -080043 # Set link speeds to 100Mb/s
Flavio Castro5608a392016-06-22 17:02:35 -070044 linkopts = dict( bw=100 )
Flavio Castrocc38a542016-03-03 13:15:46 -080045 # Add Leaf switches
Flavio Castro5608a392016-06-22 17:02:35 -070046 for ls in range( leaf ):
Flavio Castroe168f7f2016-06-24 15:53:12 -070047 leafs[ ls ] = self.addSwitch( 'leaf%s' % (ls + 1),
48 dpid="00000000000%s" % (1 + ls) )
Flavio Castrocc38a542016-03-03 13:15:46 -080049 # Connect leaf to all spines
Flavio Castro5608a392016-06-22 17:02:35 -070050 for s in range( spine ):
51 switch = spines[ s ]
Flavio Castroe168f7f2016-06-24 15:53:12 -070052 self.addLink( leafs[ ls ], switch, **linkopts )
Flavio Castrocc38a542016-03-03 13:15:46 -080053 # Add hosts under a leaf, fanout hosts per leaf switch
Flavio Castro5608a392016-06-22 17:02:35 -070054 for f in range( fanout ):
55 host = self.addHost( 'h%s' % (ls * fanout + f + 1),
56 cls=IpHost,
57 ip='10.0.%s.%s/24' % ((ls + 1), (f + 1)),
58 gateway='10.0.%s.254' % (ls + 1) )
Flavio Castroe168f7f2016-06-24 15:53:12 -070059 self.addLink( host, leafs[ ls ], **linkopts )
60 # Add Xconnect simulation
61 br1 = self.addSwitch( 'br1', cls=OVSBridge )
62 self.addLink( br1, leafs[ 0 ], **linkopts )
63 for vid in [ 5, 10 ]:
64 olt = self.addHost( 'olt%s' % vid, cls=VLANHost, vlan=vid,
65 ip="10.%s.0.1/24" % vid
66 , mac="00:00:%02d:00:00:01" % vid )
67 vsg = self.addHost( 'vsg%s' % vid, cls=VLANHost, vlan=vid,
68 ip="10.%s.0.2/24" % vid
69 , mac="00:00:%02d:00:00:02" % vid )
70 self.addLink( olt, leafs[ 0 ], **linkopts )
71 self.addLink( vsg, br1, **linkopts )
Flavio Castrocc38a542016-03-03 13:15:46 -080072
Flavio Castro5608a392016-06-22 17:02:35 -070073
74class IpHost( Host ):
75 def __init__( self, name, gateway, *args, **kwargs ):
76 super( IpHost, self ).__init__( name, *args, **kwargs )
Flavio Castrocc38a542016-03-03 13:15:46 -080077 self.gateway = gateway
78
Flavio Castro5608a392016-06-22 17:02:35 -070079 def config( self, **kwargs ):
80 Host.config( self, **kwargs )
81 mtu = "ifconfig " + self.name + "-eth0 mtu 1490"
82 self.cmd( mtu )
83 self.cmd( 'ip route add default via %s' % self.gateway )
Flavio Castrocc38a542016-03-03 13:15:46 -080084
Flavio Castro5608a392016-06-22 17:02:35 -070085
Flavio Castroe168f7f2016-06-24 15:53:12 -070086class VLANHost( Host ):
87 "Host connected to VLAN interface"
88
89 def config( self, vlan=100, **params ):
90 """Configure VLANHost according to (optional) parameters:
91 vlan: VLAN ID for default interface"""
92 r = super( VLANHost, self ).config( **params )
93 intf = self.defaultIntf( )
94 # remove IP from default, "physical" interface
95 self.cmd( 'ifconfig %s inet 0' % intf )
96 intf = self.defaultIntf( )
97 # create VLAN interface
98 self.cmd( 'vconfig add %s %d' % (intf, vlan) )
99 self.cmd( 'ifconfig %s.%d %s' % (intf, vlan, params[ 'ip' ]) )
100 # update the intf name and host's intf map
101 self.cmd( 'ifconfig %s.%d mtu 1480' % (intf, vlan) )
102 newName = '%s.%d' % (intf, vlan)
103 # update the (Mininet) interface to refer to VLAN interface name
104 intf.name = newName
105 # add VLAN interface to host's name to intf map
106 self.nameToIntf[ newName ] = intf
107
108
Flavio Castro5608a392016-06-22 17:02:35 -0700109def config( opts ):
Flavio Castrocc38a542016-03-03 13:15:46 -0800110 spine = opts.spine
111 leaf = opts.leaf
Flavio Castro5608a392016-06-22 17:02:35 -0700112 fanout = opts.fanout
113 controllers = [ os.environ[ 'OC%s' % i ] for i in
114 range( 1, opts.onos + 1 ) ] if (opts.onos) else [
115 '127.0.0.1' ]
116 topo = LeafAndSpine( spine=spine, leaf=leaf, fanout=fanout )
117 net = Mininet( topo=topo, link=TCLink, build=False,
Flavio Castroe168f7f2016-06-24 15:53:12 -0700118 switch=UserSwitch, controller=None, autoSetMacs=True )
Flavio Castrocc38a542016-03-03 13:15:46 -0800119 i = 0
120 for ip in controllers:
Flavio Castro5608a392016-06-22 17:02:35 -0700121 net.addController( "c%s" % (i), controller=RemoteController, ip=ip )
Flavio Castrocc38a542016-03-03 13:15:46 -0800122 i += 1;
Flavio Castro5608a392016-06-22 17:02:35 -0700123 net.build( )
124 net.start( )
125 CLI( net )
126 net.stop( )
127
Flavio Castrocc38a542016-03-03 13:15:46 -0800128
129if __name__ == '__main__':
Flavio Castro5608a392016-06-22 17:02:35 -0700130 setLogLevel( 'info' )
131 config( opts )
132 os.system( 'sudo mn -c' )