blob: 4f52689fbcaecacd305d775f3be0a9f0a753670f [file] [log] [blame]
#!/usr/bin/python
import os
from optparse import OptionParser
from mininet.net import Mininet
from mininet.topo import Topo
from mininet.node import RemoteController, UserSwitch, Host, OVSBridge
from mininet.link import TCLink
from mininet.log import setLogLevel
from mininet.cli import CLI
# Parse command line options and dump results
def parseOptions( ):
"""Parse command line options"""
parser = OptionParser( )
parser.add_option( '--spine', dest='spine', type='int', default=2,
help='number of spine switches, default=2' )
parser.add_option( '--leaf', dest='leaf', type='int', default=2,
help='number of leaf switches, default=2' )
parser.add_option( '--fanout', dest='fanout', type='int', default=2,
help='number of hosts per leaf switch, default=2' )
parser.add_option( '--onos', dest='onos', type='int', default=0,
help='number of ONOS Instances, default=0, 0 means localhost, 1 will use OC1 and so on' )
(options, args) = parser.parse_args( )
return options, args
opts, args = parseOptions( )
class LeafAndSpine( Topo ):
def __init__( self, spine=2, leaf=2, fanout=2, **opts ):
"Create Leaf and Spine Topo."
Topo.__init__( self, **opts )
# Add spine switches
spines = { }
leafs = { }
for s in range( spine ):
spines[ s ] = self.addSwitch( 'spine10%s' % (s + 1),
dpid="00000000010%s" % (s + 1) )
# Set link speeds to 100Mb/s
linkopts = dict( bw=100 )
# Add Leaf switches
for ls in range( leaf ):
leafs[ ls ] = self.addSwitch( 'leaf%s' % (ls + 1),
dpid="00000000000%s" % (1 + ls) )
# Connect leaf to all spines
for s in range( spine ):
switch = spines[ s ]
self.addLink( leafs[ ls ], switch, **linkopts )
# Add hosts under a leaf, fanout hosts per leaf switch
for f in range( fanout ):
host = self.addHost( 'h%s' % (ls * fanout + f + 1),
cls=IpHost,
ip='10.0.%s.%s/24' % ((ls + 1), (f + 1)),
gateway='10.0.%s.254' % (ls + 1) )
self.addLink( host, leafs[ ls ], **linkopts )
# Add Xconnect simulation
br1 = self.addSwitch( 'br1', cls=OVSBridge )
self.addLink( br1, leafs[ 0 ], **linkopts )
for vid in [ 5, 10 ]:
olt = self.addHost( 'olt%s' % vid, cls=VLANHost, vlan=vid,
ip="10.%s.0.1/24" % vid
, mac="00:00:%02d:00:00:01" % vid )
vsg = self.addHost( 'vsg%s' % vid, cls=VLANHost, vlan=vid,
ip="10.%s.0.2/24" % vid
, mac="00:00:%02d:00:00:02" % vid )
self.addLink( olt, leafs[ 0 ], **linkopts )
self.addLink( vsg, br1, **linkopts )
class IpHost( Host ):
def __init__( self, name, gateway, *args, **kwargs ):
super( IpHost, self ).__init__( name, *args, **kwargs )
self.gateway = gateway
def config( self, **kwargs ):
Host.config( self, **kwargs )
mtu = "ifconfig " + self.name + "-eth0 mtu 1490"
self.cmd( mtu )
self.cmd( 'ip route add default via %s' % self.gateway )
class VLANHost( Host ):
"Host connected to VLAN interface"
def config( self, vlan=100, **params ):
"""Configure VLANHost according to (optional) parameters:
vlan: VLAN ID for default interface"""
r = super( VLANHost, self ).config( **params )
intf = self.defaultIntf( )
# remove IP from default, "physical" interface
self.cmd( 'ifconfig %s inet 0' % intf )
intf = self.defaultIntf( )
# create VLAN interface
self.cmd( 'vconfig add %s %d' % (intf, vlan) )
self.cmd( 'ifconfig %s.%d %s' % (intf, vlan, params[ 'ip' ]) )
# update the intf name and host's intf map
self.cmd( 'ifconfig %s.%d mtu 1480' % (intf, vlan) )
newName = '%s.%d' % (intf, vlan)
# update the (Mininet) interface to refer to VLAN interface name
intf.name = newName
# add VLAN interface to host's name to intf map
self.nameToIntf[ newName ] = intf
def config( opts ):
spine = opts.spine
leaf = opts.leaf
fanout = opts.fanout
controllers = [ os.environ[ 'OC%s' % i ] for i in
range( 1, opts.onos + 1 ) ] if (opts.onos) else [
'127.0.0.1' ]
topo = LeafAndSpine( spine=spine, leaf=leaf, fanout=fanout )
net = Mininet( topo=topo, link=TCLink, build=False,
switch=UserSwitch, controller=None, autoSetMacs=True )
i = 0
for ip in controllers:
net.addController( "c%s" % (i), controller=RemoteController, ip=ip )
i += 1;
net.build( )
net.start( )
CLI( net )
net.stop( )
if __name__ == '__main__':
setLogLevel( 'info' )
config( opts )
os.system( 'sudo mn -c' )