blob: c833d084a6267ae05407711ba505558fbb755e1b [file] [log] [blame]
Carmelo Cascone785fada2016-06-16 18:34:16 -07001#!/usr/bin/python
2
3import argparse
4from itertools import combinations
5from time import sleep
6
7from bmv2 import ONOSBmv2Switch
8from mininet.cli import CLI
9from mininet.link import TCLink
10from mininet.log import setLogLevel
11from mininet.net import Mininet
12from mininet.node import RemoteController, Host
13from mininet.topo import Topo
14
15
16class ClosTopo(Topo):
17 "2 stage Clos topology"
18
19 def __init__(self, **opts):
20 # Initialize topology and default options
21 Topo.__init__(self, **opts)
22
23 bmv2SwitchIds = ["s11", "s12", "s13", "s21", "s22", "s23"]
24
25 bmv2Switches = {}
26
27 tport = 9090
28 for switchId in bmv2SwitchIds:
29 bmv2Switches[switchId] = self.addSwitch(switchId,
30 cls=ONOSBmv2Switch,
31 loglevel="warn",
32 device_id=int(switchId[1:]),
33 thrift_port=tport)
34 tport += 1
35
36 for i in (1, 2, 3):
37 for j in (1, 2, 3):
38 if i == j:
39 # 2 links
40 self.addLink(bmv2Switches["s1%d" % i], bmv2Switches["s2%d" % j],
41 cls=TCLink, bw=50)
42 self.addLink(bmv2Switches["s1%d" % i], bmv2Switches["s2%d" % j],
43 cls=TCLink, bw=50)
44 else:
45 self.addLink(bmv2Switches["s1%d" % i], bmv2Switches["s2%d" % j],
46 cls=TCLink, bw=50)
47
48 for hostId in (1, 2, 3):
49 host = self.addHost("h%d" % hostId,
50 cls=DemoHost,
51 ip="10.0.0.%d/24" % hostId,
52 mac='00:00:00:00:00:%02x' % hostId)
53 self.addLink(host, bmv2Switches["s1%d" % hostId], cls=TCLink, bw=22)
54
55
56class DemoHost(Host):
57 "Demo host"
58
59 def __init__(self, name, inNamespace=True, **params):
60 Host.__init__(self, name, inNamespace=inNamespace, **params)
61 self.exectoken = "/tmp/mn-exec-token-host-%s" % name
62 self.cmd("touch %s" % self.exectoken)
63
64 def config(self, **params):
65 r = super(Host, self).config(**params)
66
67 self.defaultIntf().rename("eth0")
68
69 for off in ["rx", "tx", "sg"]:
70 cmd = "/sbin/ethtool --offload eth0 %s off" % off
71 self.cmd(cmd)
72
73 # disable IPv6
74 self.cmd("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
75 self.cmd("sysctl -w net.ipv6.conf.default.disable_ipv6=1")
76 self.cmd("sysctl -w net.ipv6.conf.lo.disable_ipv6=1")
77
78 return r
79
80 def startPingBg(self, h):
81 self.cmd(self.getInfiniteCmdBg("ping -i0.5 %s" % h.IP()))
82 self.cmd(self.getInfiniteCmdBg("arping -w5000000 %s" % h.IP()))
83
84 def startIperfServer(self):
85 self.cmd(self.getInfiniteCmdBg("iperf3 -s"))
86
87 def startIperfClient(self, h, flowBw="512k", numFlows=5, duration=5):
88 iperfCmd = "iperf3 -c{} -b{} -P{} -t{}".format(h.IP(), flowBw, numFlows, duration)
89 self.cmd(self.getInfiniteCmdBg(iperfCmd, sleep=0))
90
91 def stop(self):
92 self.cmd("killall iperf3")
93 self.cmd("killall ping")
94 self.cmd("killall arping")
95
96 def describe(self):
97 print "**********"
98 print self.name
99 print "default interface: %s\t%s\t%s" % (
100 self.defaultIntf().name,
101 self.defaultIntf().IP(),
102 self.defaultIntf().MAC()
103 )
104 print "**********"
105
106 def getInfiniteCmdBg(self, cmd, logfile="/dev/null", sleep=1):
107 return "(while [ -e {} ]; " \
108 "do {}; " \
109 "sleep {}; " \
110 "done;) > {} 2>&1 &".format(self.exectoken, cmd, sleep, logfile)
111
112 def getCmdBg(self, cmd, logfile="/dev/null"):
113 return "{} > {} 2>&1 &".format(cmd, logfile)
114
115
116def main(args):
117 topo = ClosTopo()
118
119 net = Mininet(topo=topo, build=False)
120
121 net.addController('c0', controller=RemoteController, ip=args.onos_ip, port=args.onos_port)
122
123 net.build()
124 net.start()
125
126 print "Network started..."
127
128 # Generates background traffic (needed for host discovery and bmv2 config swap).
129 sleep(3)
130 for (h1, h2) in combinations(net.hosts, 2):
131 h1.startPingBg(h2)
132 h2.startPingBg(h1)
133
134 for h in net.hosts:
135 h.startIperfServer()
136
137 print "Background ping started..."
138
139 # sleep(4)
140 # print "Starting traffic from h1 to h3..."
141 # net.hosts[0].startIperfClient(net.hosts[-1], flowBw="200k", numFlows=100, duration=10)
142
143 CLI(net)
144
145 net.stop()
146
147
148if __name__ == '__main__':
149 parser = argparse.ArgumentParser(description='BMv2 mininet demo script (2-stage Clos topology)')
150 parser.add_argument('--onos-ip', help='ONOS-BMv2 controller IP address',
151 type=str, action="store", required=True)
152 parser.add_argument('--onos-port', help='ONOS-BMv2 controller port',
153 type=int, action="store", default=40123)
154 args = parser.parse_args()
155 setLogLevel('info')
156 main(args)