tom | e2918e6 | 2014-09-12 18:23:20 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | from mininet.cli import CLI |
| 3 | from mininet.net import Mininet |
| 4 | from mininet.node import RemoteController, OVSKernelSwitch |
| 5 | |
| 6 | MAC = 12 |
| 7 | DPID = 16 |
| 8 | |
| 9 | class CustomCLI(CLI): |
| 10 | """Custom CLI to allow us to add our own commands.""" |
| 11 | |
| 12 | def __init__ (self, net): |
| 13 | """Init method for our custom CLI.""" |
| 14 | self.net = net |
| 15 | CLI.__init__(self, net) |
| 16 | |
| 17 | class Solar(object): |
| 18 | """ Create a tiered topology from semi-scratch in Mininet """ |
| 19 | |
| 20 | def __init__(self, cname='onos', cip='192.168.56.1', islands=3, edges=2, hosts=2, |
| 21 | proto=None): |
| 22 | """Create tower topology for mininet""" |
| 23 | |
| 24 | # We are creating the controller with local-loopback on purpose to avoid |
| 25 | # having the switches connect immediately. Instead, we'll set controller |
| 26 | # explicitly for each switch after configuring it as we want. |
| 27 | self.flare = RemoteController(cname, cip, 6633) |
| 28 | self.net = Mininet(controller=self.flare, switch = OVSKernelSwitch, |
| 29 | build=False) |
| 30 | |
| 31 | self.cip = cip |
| 32 | self.spines = [] |
| 33 | self.leaves = [] |
| 34 | self.hosts = [] |
| 35 | self.proto = proto |
| 36 | |
| 37 | # Create the two core switches and links between them |
| 38 | c1 = self.net.addSwitch('c1',dpid='1111000000000000') |
| 39 | c2 = self.net.addSwitch('c2',dpid='2222000000000000') |
| 40 | self.spines.append(c1) |
| 41 | self.spines.append(c2) |
| 42 | |
| 43 | self.net.addLink(c1, c2) |
| 44 | self.net.addLink(c2, c1) |
| 45 | |
| 46 | for i in range(1, islands + 1): |
| 47 | sc = self.createSpineClump(i, edges, hosts) |
| 48 | self.net.addLink(c1, sc[0]) |
| 49 | self.net.addLink(c2, sc[0]) |
| 50 | self.net.addLink(c1, sc[1]) |
| 51 | self.net.addLink(c2, sc[1]) |
| 52 | |
| 53 | def createSpineClump(self, island, edges, hosts): |
| 54 | """ Creates a clump of spine and edge switches with hosts""" |
| 55 | s1 = self.net.addSwitch('s%1d1' % island,dpid='00000%1d0100000000' % island) |
| 56 | s2 = self.net.addSwitch('s%1d2' % island,dpid='00000%1d0200000000' % island) |
| 57 | self.net.addLink(s1, s2) |
| 58 | self.net.addLink(s2, s1) |
| 59 | |
| 60 | for i in range(1, edges + 1): |
| 61 | es = self.createEdgeSwitch(island, i, hosts) |
| 62 | self.net.addLink(es, s1) |
| 63 | self.net.addLink(es, s2) |
| 64 | |
| 65 | self.spines.append(s1) |
| 66 | self.spines.append(s2) |
| 67 | |
| 68 | clump = [] |
| 69 | clump.append(s1) |
| 70 | clump.append(s2) |
| 71 | return clump |
| 72 | |
| 73 | def createEdgeSwitch(self, island, index, hosts): |
| 74 | """ Creates an edge switch in an island and ads hosts to it""" |
| 75 | sw = self.net.addSwitch('e%1d%1d' % (island, index),dpid='0000000%1d0000000%1d' % (island, index)) |
| 76 | self.leaves.append(sw) |
| 77 | |
| 78 | for j in range(1, hosts + 1): |
| 79 | host = self.net.addHost('h%d%d%d' % (island, index, j),ip='10.%d.%d.%d' % (island, index, j)) |
| 80 | self.net.addLink(host, sw) |
| 81 | self.hosts.append(host) |
| 82 | return sw |
| 83 | |
| 84 | def run(self): |
| 85 | """ Runs the created network topology and launches mininet cli""" |
| 86 | self.run_silent() |
| 87 | CustomCLI(self.net) |
| 88 | self.net.stop() |
| 89 | |
| 90 | def run_silent(self): |
| 91 | """ Runs silently - for unit testing """ |
| 92 | self.net.build() |
| 93 | |
| 94 | # Start the switches, configure them with desired protocols and only |
| 95 | # then set the controller |
| 96 | for sw in self.spines: |
| 97 | sw.start([self.flare]) |
| 98 | if self.proto: |
| 99 | sw.cmd('ovs-vsctl set bridge %(sw)s protocols=%(proto)s' % \ |
| 100 | { 'sw': sw.name, 'proto': self.proto}) |
| 101 | sw.cmdPrint('ovs-vsctl set-controller %(sw)s tcp:%(ctl)s:6633' % \ |
| 102 | {'sw': sw.name, 'ctl': self.cip}) |
| 103 | |
| 104 | for sw in self.leaves: |
| 105 | sw.start([self.flare]) |
| 106 | sw.cmdPrint('ovs-vsctl set-controller %(sw)s tcp:%(ctl)s:6633' % \ |
| 107 | {'sw': sw.name, 'ctl': self.cip}) |
| 108 | |
| 109 | def pingAll(self): |
| 110 | """ PingAll to create flows - for unit testing """ |
| 111 | self.net.pingAll() |
| 112 | |
| 113 | def stop(self): |
| 114 | "Stops the topology. You should call this after run_silent" |
| 115 | self.net.stop() |