Add tower topo.
diff --git a/tools/test/topos/tower.py b/tools/test/topos/tower.py
new file mode 100644
index 0000000..b8a5f7c
--- /dev/null
+++ b/tools/test/topos/tower.py
@@ -0,0 +1,101 @@
+#!/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()