blob: 646c73535b260418751a3575ef71495090a771e1 [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
Carmelo Cascone977ae3f2016-06-23 19:28:28 -07007if 'ONOS_ROOT' not in os.environ:
8 print "Environment var $ONOS_ROOT not set"
9 exit()
10else:
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -070011 ONOS_ROOT = os.environ["ONOS_ROOT"]
12 sys.path.append(ONOS_ROOT + "/tools/dev/mininet")
Devin Lim0d944e22017-06-23 15:17:53 -070013if 'RUN_PACK_PATH' not in os.environ:
14 print "Environment var $RUN_PACK_PATH not set"
15 exit()
16else:
17 RUN_PACK_PATH = os.environ["RUN_PACK_PATH"]
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -070018
19from onos import ONOSCluster, ONOSCLI
20from bmv2 import ONOSBmv2Switch
Carmelo Cascone977ae3f2016-06-23 19:28:28 -070021
Carmelo Cascone785fada2016-06-16 18:34:16 -070022from itertools import combinations
23from time import sleep
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -070024from subprocess import call
Carmelo Cascone785fada2016-06-16 18:34:16 -070025
Carmelo Cascone785fada2016-06-16 18:34:16 -070026from mininet.cli import CLI
27from mininet.link import TCLink
28from mininet.log import setLogLevel
29from mininet.net import Mininet
30from mininet.node import RemoteController, Host
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -070031from mininet.topo import Topo, SingleSwitchTopo
Carmelo Cascone785fada2016-06-16 18:34:16 -070032
33
34class ClosTopo(Topo):
35 "2 stage Clos topology"
36
37 def __init__(self, **opts):
38 # Initialize topology and default options
39 Topo.__init__(self, **opts)
40
41 bmv2SwitchIds = ["s11", "s12", "s13", "s21", "s22", "s23"]
42
43 bmv2Switches = {}
44
45 tport = 9090
46 for switchId in bmv2SwitchIds:
47 bmv2Switches[switchId] = self.addSwitch(switchId,
48 cls=ONOSBmv2Switch,
49 loglevel="warn",
Carmelo Cascone977ae3f2016-06-23 19:28:28 -070050 deviceId=int(switchId[1:]),
51 thriftPort=tport)
Carmelo Cascone785fada2016-06-16 18:34:16 -070052 tport += 1
53
54 for i in (1, 2, 3):
55 for j in (1, 2, 3):
56 if i == j:
57 # 2 links
58 self.addLink(bmv2Switches["s1%d" % i], bmv2Switches["s2%d" % j],
59 cls=TCLink, bw=50)
60 self.addLink(bmv2Switches["s1%d" % i], bmv2Switches["s2%d" % j],
61 cls=TCLink, bw=50)
62 else:
63 self.addLink(bmv2Switches["s1%d" % i], bmv2Switches["s2%d" % j],
64 cls=TCLink, bw=50)
65
66 for hostId in (1, 2, 3):
67 host = self.addHost("h%d" % hostId,
68 cls=DemoHost,
69 ip="10.0.0.%d/24" % hostId,
70 mac='00:00:00:00:00:%02x' % hostId)
71 self.addLink(host, bmv2Switches["s1%d" % hostId], cls=TCLink, bw=22)
72
73
74class DemoHost(Host):
75 "Demo host"
76
77 def __init__(self, name, inNamespace=True, **params):
78 Host.__init__(self, name, inNamespace=inNamespace, **params)
79 self.exectoken = "/tmp/mn-exec-token-host-%s" % name
80 self.cmd("touch %s" % self.exectoken)
81
82 def config(self, **params):
83 r = super(Host, self).config(**params)
84
85 self.defaultIntf().rename("eth0")
86
87 for off in ["rx", "tx", "sg"]:
88 cmd = "/sbin/ethtool --offload eth0 %s off" % off
89 self.cmd(cmd)
90
91 # disable IPv6
92 self.cmd("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
93 self.cmd("sysctl -w net.ipv6.conf.default.disable_ipv6=1")
94 self.cmd("sysctl -w net.ipv6.conf.lo.disable_ipv6=1")
95
96 return r
97
98 def startPingBg(self, h):
99 self.cmd(self.getInfiniteCmdBg("ping -i0.5 %s" % h.IP()))
100 self.cmd(self.getInfiniteCmdBg("arping -w5000000 %s" % h.IP()))
101
102 def startIperfServer(self):
103 self.cmd(self.getInfiniteCmdBg("iperf3 -s"))
104
105 def startIperfClient(self, h, flowBw="512k", numFlows=5, duration=5):
106 iperfCmd = "iperf3 -c{} -b{} -P{} -t{}".format(h.IP(), flowBw, numFlows, duration)
107 self.cmd(self.getInfiniteCmdBg(iperfCmd, sleep=0))
108
109 def stop(self):
110 self.cmd("killall iperf3")
111 self.cmd("killall ping")
112 self.cmd("killall arping")
113
114 def describe(self):
115 print "**********"
116 print self.name
117 print "default interface: %s\t%s\t%s" % (
118 self.defaultIntf().name,
119 self.defaultIntf().IP(),
120 self.defaultIntf().MAC()
121 )
122 print "**********"
123
124 def getInfiniteCmdBg(self, cmd, logfile="/dev/null", sleep=1):
125 return "(while [ -e {} ]; " \
126 "do {}; " \
127 "sleep {}; " \
128 "done;) > {} 2>&1 &".format(self.exectoken, cmd, sleep, logfile)
129
130 def getCmdBg(self, cmd, logfile="/dev/null"):
131 return "{} > {} 2>&1 &".format(cmd, logfile)
132
133
134def main(args):
135 topo = ClosTopo()
136
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -0700137 if not args.onos_ip:
138 controller = ONOSCluster('c0', 3)
139 onosIp = controller.nodes()[0].IP()
140 else:
141 controller = RemoteController('c0', ip=args.onos_ip, port=args.onos_port)
142 onosIp = args.onos_ip
Carmelo Cascone785fada2016-06-16 18:34:16 -0700143
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -0700144 net = Mininet(topo=topo, build=False, controller=[controller])
Carmelo Cascone785fada2016-06-16 18:34:16 -0700145
146 net.build()
147 net.start()
148
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -0700149 print "Network started"
Carmelo Cascone785fada2016-06-16 18:34:16 -0700150
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -0700151 # Generate background traffic.
Carmelo Cascone785fada2016-06-16 18:34:16 -0700152 sleep(3)
153 for (h1, h2) in combinations(net.hosts, 2):
154 h1.startPingBg(h2)
155 h2.startPingBg(h1)
156
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -0700157 print "Background ping started"
158
Carmelo Cascone785fada2016-06-16 18:34:16 -0700159 for h in net.hosts:
160 h.startIperfServer()
161
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -0700162 print "Iperf servers started"
Carmelo Cascone785fada2016-06-16 18:34:16 -0700163
164 # sleep(4)
165 # print "Starting traffic from h1 to h3..."
166 # net.hosts[0].startIperfClient(net.hosts[-1], flowBw="200k", numFlows=100, duration=10)
167
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -0700168 print "Setting netcfg..."
Devin Lim0d944e22017-06-23 15:17:53 -0700169 call(("%s/onos-netcfg" % RUN_PACK_PATH, onosIp,
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -0700170 "%s/tools/test/topos/bmv2-demo-cfg.json" % ONOS_ROOT))
171
172 if not args.onos_ip:
173 ONOSCLI(net)
174 else:
175 CLI(net)
Carmelo Cascone785fada2016-06-16 18:34:16 -0700176
177 net.stop()
178
179
180if __name__ == '__main__':
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -0700181 parser = argparse.ArgumentParser(
182 description='BMv2 mininet demo script (2-stage Clos topology)')
Carmelo Cascone785fada2016-06-16 18:34:16 -0700183 parser.add_argument('--onos-ip', help='ONOS-BMv2 controller IP address',
Carmelo Cascone12e4d8d2016-07-05 15:55:15 -0700184 type=str, action="store", required=False)
Carmelo Cascone785fada2016-06-16 18:34:16 -0700185 parser.add_argument('--onos-port', help='ONOS-BMv2 controller port',
186 type=int, action="store", default=40123)
187 args = parser.parse_args()
188 setLogLevel('info')
189 main(args)