blob: b8a5f7c8766a70817479563e6d4c82615ed75fbd [file] [log] [blame]
#!/usr/bin/env python
from mininet.cli import CLI
from mininet.net import Mininet
from mininet.node import RemoteController, OVSKernelSwitch
MAC = 12
DPID = 16
def string_to_hex(s, length):
""" Convert a string like 00:00 in to hex 0x0000 format"""
tmp = '{0:#x}'.format(int(s.replace(':', '').lstrip('0'),length))
return tmp
def hex_to_string(h, length):
"""Convert a hex number from 0x0000 to 00:00 format"""
tmp = h.lstrip('0x').zfill(length)
tmp = ':'.join(a+b for a,b in zip(tmp[::2], tmp[1::2]))
return tmp
class Tower(object):
""" Create a tower topology from semi-scratch in Mininet """
def __init__(self, cname='flare', cip='15.255.126.183', k=4, h=6,
proto=None):
"""Create tower topology for mininet
cname: controller name
cip: controller ip
k: number of leaf switches
h: number of hosts perl leaf switch
"""
# We are creating the controller with local-loopback on purpose to avoid
# having the switches connect immediately. Instead, we'll set controller
# explicitly for each switch after configuring it as we want.
self.flare = RemoteController(cname, '127.0.0.1', 6633)
self.net = Mininet(controller=self.flare, switch = OVSKernelSwitch,
build=False)
self.cip = cip
self.spines = []
self.leaves = []
self.hosts = []
self.proto = proto
# Create the two spine switches
self.spines.append(self.net.addSwitch('s1'))
self.spines.append(self.net.addSwitch('s2'))
# Create two links between the spine switches
self.net.addLink(self.spines[0], self.spines[1])
self.net.addLink(self.spines[1], self.spines[0])
# Now create the leaf switches, their hosts and connect them together
i = 1
c = 0
while i <= k:
self.leaves.append(self.net.addSwitch('s1%d' % i))
for spine in self.spines:
self.net.addLink(self.leaves[i-1], spine)
j = 1
while j <= h:
self.hosts.append(self.net.addHost('h%d%d' % (i, j)))
self.net.addLink(self.hosts[c], self.leaves[i-1])
j+=1
c+=1
i+=1
def run(self):
""" Runs the created network topology and launches mininet cli"""
self.run_silent()
CLI(self.net)
self.net.stop()
def run_silent(self):
""" Runs silently - for unit testing """
self.net.build()
# Start the switches, configure them with desired protocols and only
# then set the controller
for sw in self.spines:
sw.start([self.flare])
if self.proto:
sw.cmd('ovs-vsctl set bridge %(sw)s protocols=%(proto)s' % \
{ 'sw': sw.name, 'proto': self.proto})
sw.cmdPrint('ovs-vsctl set-controller %(sw)s tcp:%(ctl)s:6633' % \
{'sw': sw.name, 'ctl': self.cip})
for sw in self.leaves:
sw.start([self.flare])
sw.cmdPrint('ovs-vsctl set-controller %(sw)s tcp:%(ctl)s:6633' % \
{'sw': sw.name, 'ctl': self.cip})
def pingAll(self):
""" PingAll to create flows - for unit testing """
self.net.pingAll()
def stop(self):
"Stops the topology. You should call this after run_silent"
self.net.stop()