blob: e08e5a6993eabc4c99caae482688ec4d330142db [file] [log] [blame]
#!/usr/bin/python
import os
import re
from optparse import OptionParser
from ipaddress import ip_network
from mininet.node import RemoteController, OVSBridge, Host
from mininet.link import TCLink
from mininet.log import setLogLevel
from mininet.net import Mininet
from mininet.topo import Topo
from mininet.nodelib import NAT
from mininet.cli import CLI
from routinglib import BgpRouter, RoutedHost
from trellislib import DhcpServer, TaggedRoutedHost, DualHomedRoutedHost, DualHomedTaggedRoutedHost, DhcpClient, Dhcp6Client, DhcpServer, Dhcp6Server, TrellisHost
# Parse command line options and dump results
def parseOptions():
"Parse command line options"
parser = OptionParser()
parser.add_option( '--dhcp', dest='dhcp', type='int', default=0,
help='Configure hosts with dhcp or not' )
parser.add_option( '--routers', dest='routers', type='int', default=0,
help='Configure external routers or not in the topology' )
parser.add_option( '--ipv6', dest='ipv6', type='int', default=0,
help='Configure hosts with ipv6 or not' )
parser.add_option( '--ipv4', dest='ipv4', type='int', default=1,
help='Configure hosts with ipv4 or not' )
parser.add_option( '--onos-ip', dest='onosIp', type='str', default='',
help='IP address list of ONOS instances, separated by comma(,). Overrides --onos option' )
( options, args ) = parser.parse_args()
return options, args
opts, args = parseOptions()
class ComcastLeafSpineFabric(Topo):
spines = dict()
leafs = dict()
hosts_dict = dict()
def createIpv4Hosts(self, dhcp):
h1 = self.addHost('h1v4', cls=TrellisHost,
mac='00:aa:00:00:00:01', ips=['10.1.0.1/24'],
gateway='10.1.0.254', dhcpClient=dhcp)
self.addLink(h1, self.leafs[0])
self.hosts_dict['h1v4'] = h1
h2 = self.addHost('h2v4', cls=TrellisHost,
mac='00:aa:00:00:01:01', ips=['10.1.10.1/24'],
gateway='10.1.10.254', dhcpClient=dhcp)
self.addLink(h2, self.leafs[0])
self.hosts_dict['h2v4'] = h2
h3 = self.addHost('h3v4', cls=TrellisHost,
mac='00:aa:00:00:00:02', ips=['10.2.0.1/24'],
gateway='10.2.0.254', dhcpClient=dhcp)
self.addLink(h3, self.leafs[1])
self.hosts_dict['h3v4'] = h3
h4 = self.addHost('h4v4', cls=TrellisHost,
mac='00:aa:00:00:00:03', ips=['10.2.30.1/24'],
gateway='10.2.30.254', dhcpClient=dhcp,
dualHomed=True)
self.addLink(h4, self.leafs[1])
self.addLink(h4, self.leafs[2])
self.hosts_dict['h4v4'] = h4
h5 = self.addHost('h5v4', cls=TrellisHost,
mac='00:aa:00:00:00:04', ips=['10.2.20.1/24'],
gateway='10.2.20.254', dhcpClient=dhcp, vlan=30,
dualHomed=True)
self.addLink(h5, self.leafs[1])
self.addLink(h5, self.leafs[2])
self.hosts_dict['h5v4'] = h5
h6 = self.addHost('h6v4', cls=TrellisHost,
mac='00:aa:00:00:00:05', ips=['10.2.10.1/24'],
gateway='10.2.10.254', dhcpClient=dhcp, vlan=20)
self.addLink(h6, self.leafs[2])
self.hosts_dict['h6v4'] = h6
h7 = self.addHost('h7v4', cls=TrellisHost,
mac='00:aa:00:00:01:05', ips=['10.2.40.1/24'],
gateway='10.2.40.254', dhcpClient=dhcp, vlan=40)
self.addLink(h7, self.leafs[2])
self.hosts_dict['h7v4'] = h7
h8 = self.addHost('h8v4', cls=TrellisHost,
mac='00:aa:00:00:00:06', ips=['10.3.0.1/24'],
gateway='10.3.0.254', dhcpClient=dhcp, vlan=30)
self.addLink(h8, self.leafs[3])
self.hosts_dict['h8v4'] = h8
h9 = self.addHost('h9v4', cls=TrellisHost,
mac='00:aa:00:00:00:07', ips=['10.3.10.1/24'],
gateway='10.3.10.254', dhcpClient=dhcp, vlan=40,
dualHomed=True)
self.addLink(h9, self.leafs[3])
self.addLink(h9, self.leafs[4])
self.hosts_dict['h9v4'] = h9
h10 = self.addHost('h10v4', cls=TrellisHost,
mac='00:aa:00:00:00:08', ips=['10.3.30.1/24'],
gateway='10.3.30.254', dhcpClient=dhcp, vlan=40,
dualHomed=True)
self.addLink(h10, self.leafs[3])
self.addLink(h10, self.leafs[4])
self.hosts_dict['h10v4'] = h10
h11 = self.addHost('h11v4', cls=TrellisHost,
mac='00:aa:00:00:00:0a', ips=['10.3.20.1/24'],
gateway='10.3.20.254', dhcpClient=dhcp, vlan=40)
self.addLink(h11, self.leafs[4])
self.hosts_dict['h11v4'] = h11
return
def createIpv6Hosts(self, dhcp):
h1 = self.addHost('h1v6', cls=TrellisHost,
mac='00:aa:00:00:00:01', ips=["1000::3fe/120"],
gateway='1000::3ff', dhcpClient=dhcp)
self.addLink(h1, self.leafs[0])
self.hosts_dict['h1v6'] = h1
h2 = self.addHost('h2v6', cls=TrellisHost,
mac='00:aa:00:00:01:01', ips=['1001::3fe/120'],
gateway='1001::3ff', dhcpClient=dhcp)
self.addLink(h2, self.leafs[0])
self.hosts_dict['h2v6'] = h2
h3 = self.addHost('h3v6', cls=TrellisHost,
mac='00:aa:00:00:00:02', ips=['1002::3fe/120'],
gateway='1002::3ff', dhcpClient=dhcp)
self.addLink(h3, self.leafs[1])
self.hosts_dict['h3v6'] = h3
h4 = self.addHost('h4v6', cls=TrellisHost,
mac='00:aa:00:00:00:03', ips=['1003::3fe/120'],
gateway='1003::3ff', dhcpClient=dhcp,
dualHomed=True)
self.addLink(h4, self.leafs[1])
self.addLink(h4, self.leafs[2])
self.hosts_dict['h4v6'] = h4
h5 = self.addHost('h5v6', cls=TrellisHost,
mac='00:aa:00:00:00:04', ips=['1004::3fe/120'],
gateway='1004::3ff', dhcpClient=dhcp, vlan=30,
dualHomed=True)
self.addLink(h5, self.leafs[1])
self.addLink(h5, self.leafs[2])
self.hosts_dict['h5v6'] = h5
h6 = self.addHost('h6v6', cls=TrellisHost,
mac='00:aa:00:00:00:05', ips=['1005::3fe/120'],
gateway='1005::3ff', dhcpClient=dhcp, vlan=20)
self.addLink(h6, self.leafs[2])
self.hosts_dict['h6v6'] = h6
h7 = self.addHost('h7v6', cls=TrellisHost,
mac='00:aa:00:00:01:05', ips=['1006::3fe/120'],
gateway='1006::3ff', dhcpClient=dhcp, vlan=40)
self.addLink(h7, self.leafs[2])
self.hosts_dict['h7v6'] = h7
h8 = self.addHost('h8v6', cls=TrellisHost,
mac='00:aa:00:00:00:06', ips=['1007::3fe/120'],
gateway='1007::3ff', dhcpClient=dhcp, vlan=30)
self.addLink(h8, self.leafs[3])
self.hosts_dict['h8v6'] = h8
h9 = self.addHost('h9v6', cls=TrellisHost,
mac='00:aa:00:00:00:07', ips=['1008::3fe/120'],
gateway='1008::3ff', dhcpClient=dhcp, vlan=40,
dualHomed=True)
self.addLink(h9, self.leafs[3])
self.addLink(h9, self.leafs[4])
self.hosts_dict['h9v6'] = h9
h10 = self.addHost('h10v6', cls=TrellisHost,
mac='00:aa:00:00:00:08', ips=['1009::3fe/120'],
gateway='1009::3ff', dhcpClient=dhcp, vlan=40,
dualHomed=True)
self.addLink(h10, self.leafs[3])
self.addLink(h10, self.leafs[4])
self.hosts_dict['h10v6'] = h10
h11 = self.addHost('h11v6', cls=TrellisHost,
mac='00:aa:00:00:00:0a', ips=['1010::3fe/120'],
gateway='1010::3ff', dhcpClient=dhcp, vlan=40)
self.addLink(h11, self.leafs[4])
self.hosts_dict['h11v6'] = h11
return
'''
Creates the topology employed by Comcast which is a 2x5
leaf spine traffic.
S1 S2
L1 L2 L3 L4 L5
Where L2/L3 and L4/L5 are paired switches.
Parameters for this topology :
dhcp = True/False : set up dhcp servers
routers = True/False : set up external routers
'''
def __init__(self, dhcp=False, routers=False, ipv4=False, ipv6=False, **opts):
Topo.__init__(self, **opts)
# TODO: support IPv6 hosts
linkopts = dict( bw=10 )
spine = 2
leaf = 5
# Create spine switches
for s in range(spine):
self.spines[s] = self.addSwitch('spine10%s' % (s + 1), dpid = "00000000010%s" % (s + 1) )
# Create leaf switches
for ls in range(leaf):
self.leafs[ls] = self.addSwitch('leaf%s' % (ls + 1), dpid = "00000000000%s" % ( ls + 1) )
# connecting leaf and spines, leafs 1-5 have double links
for s in range( spine ):
spine_switch = self.spines[s]
for ls in range( leaf ):
leaf_switch = self.leafs[ls]
self.addLink( spine_switch, leaf_switch, **linkopts )
if ls > 0:
self.addLink( spine_switch, leaf_switch, **linkopts )
# connect paired leafs
self.addLink(self.leafs[1], self.leafs[2], **linkopts)
self.addLink(self.leafs[3], self.leafs[4], **linkopts)
# create dhcp servers
if dhcp:
if ipv4:
dhcp4 = self.addHost( 'dhcp', cls=TrellisHost,
mac="00:bb:00:00:00:01", ips=["10.0.3.253/24"],
gateway="10.0.3.254", dhcpServer=True)
self.addLink(self.spines[1], dhcp4, **linkopts)
if ipv6:
dhcp6 = self.addHost( 'dhcp', cls=TrellisHost,
mac="00:bb:00:00:00:02", ips=["2000::3fd/120"],
gateway="2000::3ff")
self.addLink(self.spines[1], dhcp4, **linkopts)
# creatte quagga routers
if routers:
print("NYI (quagga)!")
# create hosts
if ipv6:
self.createIpv6Hosts(dhcp)
if ipv4:
self.createIpv4Hosts(dhcp)
if not ipv4 and not ipv6:
print("No hosts were created!")
def config( opts ):
dhcp = bool(opts.dhcp)
routers = bool(opts.routers)
ipv6 = bool(opts.ipv6)
ipv4 = bool(opts.ipv4)
if opts.onosIp != '':
controllers = opts.onosIp.split( ',' )
else:
controllers = ['127.0.0.1']
topo = ComcastLeafSpineFabric(dhcp=dhcp, routers=routers, ipv6=ipv6,
ipv4=ipv4)
net = Mininet( topo=topo, link=TCLink, build=False,
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')