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