mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-15 01:11:30 +02:00
Minor refactoring of BMv2 mininet scripts
With options to delay pushing the netcfg for each device and generating the full netcfg JSON for bmv2-demo. Change-Id: I046a93a8c639f4bb4cf76cbd61b826473760bfb1
This commit is contained in:
parent
6168994ad6
commit
6ec8f8ff93
@ -35,7 +35,8 @@ class ONOSHost(Host):
|
|||||||
def config(self, **params):
|
def config(self, **params):
|
||||||
r = super(Host, self).config(**params)
|
r = super(Host, self).config(**params)
|
||||||
for off in ["rx", "tx", "sg"]:
|
for off in ["rx", "tx", "sg"]:
|
||||||
cmd = "/sbin/ethtool --offload %s %s off" % (self.defaultIntf(), off)
|
cmd = "/sbin/ethtool --offload %s %s off"\
|
||||||
|
% (self.defaultIntf(), off)
|
||||||
self.cmd(cmd)
|
self.cmd(cmd)
|
||||||
# disable IPv6
|
# disable IPv6
|
||||||
self.cmd("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
|
self.cmd("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
|
||||||
@ -52,7 +53,8 @@ class ONOSBmv2Switch(Switch):
|
|||||||
|
|
||||||
def __init__(self, name, json=None, debugger=False, loglevel="warn", elogger=False,
|
def __init__(self, name, json=None, debugger=False, loglevel="warn", elogger=False,
|
||||||
persistent=False, grpcPort=None, thriftPort=None, netcfg=True, dryrun=False,
|
persistent=False, grpcPort=None, thriftPort=None, netcfg=True, dryrun=False,
|
||||||
pipeconfId="", pktdump=False, valgrind=False, **kwargs):
|
pipeconfId="", pktdump=False, valgrind=False, netcfgDelay=0,
|
||||||
|
**kwargs):
|
||||||
Switch.__init__(self, name, **kwargs)
|
Switch.__init__(self, name, **kwargs)
|
||||||
self.grpcPort = ONOSBmv2Switch.pickUnusedPort() if not grpcPort else grpcPort
|
self.grpcPort = ONOSBmv2Switch.pickUnusedPort() if not grpcPort else grpcPort
|
||||||
self.thriftPort = ONOSBmv2Switch.pickUnusedPort() if not thriftPort else thriftPort
|
self.thriftPort = ONOSBmv2Switch.pickUnusedPort() if not thriftPort else thriftPort
|
||||||
@ -71,6 +73,7 @@ class ONOSBmv2Switch(Switch):
|
|||||||
self.netcfg = parseBoolean(netcfg)
|
self.netcfg = parseBoolean(netcfg)
|
||||||
self.dryrun = parseBoolean(dryrun)
|
self.dryrun = parseBoolean(dryrun)
|
||||||
self.valgrind = parseBoolean(valgrind)
|
self.valgrind = parseBoolean(valgrind)
|
||||||
|
self.netcfgDelay = netcfgDelay
|
||||||
self.netcfgfile = '/tmp/bmv2-%d-netcfg.json' % self.deviceId
|
self.netcfgfile = '/tmp/bmv2-%d-netcfg.json' % self.deviceId
|
||||||
self.pipeconfId = pipeconfId
|
self.pipeconfId = pipeconfId
|
||||||
if persistent:
|
if persistent:
|
||||||
@ -229,11 +232,13 @@ class ONOSBmv2Switch(Switch):
|
|||||||
out = self.cmd(cmdStr)
|
out = self.cmd(cmdStr)
|
||||||
if out:
|
if out:
|
||||||
print out
|
print out
|
||||||
if self.netcfg and self.valgrind:
|
if self.netcfg:
|
||||||
# With valgrind, it takes some time before the gRPC server is available.
|
if self.valgrind:
|
||||||
# Wait before pushing the netcfg.
|
# With valgrind, it takes some time before the gRPC server is available.
|
||||||
info("\n*** Waiting %d seconds before pushing the config to ONOS...\n" % VALGRIND_SLEEP)
|
# Wait before pushing the netcfg.
|
||||||
time.sleep(VALGRIND_SLEEP)
|
info("\n*** Waiting %d seconds before pushing the config to ONOS...\n" % VALGRIND_SLEEP)
|
||||||
|
time.sleep(VALGRIND_SLEEP)
|
||||||
|
time.sleep(self.netcfgDelay)
|
||||||
|
|
||||||
try: # onos.py
|
try: # onos.py
|
||||||
clist = controllers[0].nodes()
|
clist = controllers[0].nodes()
|
||||||
|
@ -42,8 +42,12 @@ from mininet.node import RemoteController, Host
|
|||||||
from mininet.topo import Topo
|
from mininet.topo import Topo
|
||||||
|
|
||||||
|
|
||||||
|
def getCmdBg(cmd, logfile="/dev/null"):
|
||||||
|
return "{} > {} 2>&1 &".format(cmd, logfile)
|
||||||
|
|
||||||
|
|
||||||
class ClosTopo(Topo):
|
class ClosTopo(Topo):
|
||||||
"2 stage Clos topology"
|
"""2 stage Clos topology"""
|
||||||
|
|
||||||
def __init__(self, args, **opts):
|
def __init__(self, args, **opts):
|
||||||
# Initialize topology and default options
|
# Initialize topology and default options
|
||||||
@ -58,16 +62,17 @@ class ClosTopo(Topo):
|
|||||||
|
|
||||||
for switchId in bmv2SwitchIds:
|
for switchId in bmv2SwitchIds:
|
||||||
deviceId = int(switchId[1:])
|
deviceId = int(switchId[1:])
|
||||||
# Use first number in device id to calculate latitude (row number)
|
# Use first number in device id to calculate latitude (row number),
|
||||||
|
# use second to calculate longitude (column number)
|
||||||
latitude = SWITCH_BASE_LATITUDE + (deviceId // 10) * BASE_SHIFT
|
latitude = SWITCH_BASE_LATITUDE + (deviceId // 10) * BASE_SHIFT
|
||||||
|
|
||||||
# Use second number in device id to calculate longitude (column number)
|
|
||||||
longitude = BASE_LONGITUDE + (deviceId % 10) * BASE_SHIFT
|
longitude = BASE_LONGITUDE + (deviceId % 10) * BASE_SHIFT
|
||||||
|
|
||||||
bmv2Switches[switchId] = self.addSwitch(switchId,
|
bmv2Switches[switchId] = self.addSwitch(switchId,
|
||||||
cls=ONOSBmv2Switch,
|
cls=ONOSBmv2Switch,
|
||||||
loglevel="warn",
|
loglevel=args.log_level,
|
||||||
deviceId=deviceId,
|
deviceId=deviceId,
|
||||||
netcfg=False,
|
netcfg=True,
|
||||||
|
netcfgDelay=0.5,
|
||||||
longitude=longitude,
|
longitude=longitude,
|
||||||
latitude=latitude,
|
latitude=latitude,
|
||||||
pipeconfId=args.pipeconf_id)
|
pipeconfId=args.pipeconf_id)
|
||||||
@ -75,14 +80,17 @@ class ClosTopo(Topo):
|
|||||||
for i in range(1, args.size + 1):
|
for i in range(1, args.size + 1):
|
||||||
for j in range(1, args.size + 1):
|
for j in range(1, args.size + 1):
|
||||||
if i == j:
|
if i == j:
|
||||||
# 2 links
|
self.addLink(bmv2Switches["s1%d" % i],
|
||||||
self.addLink(bmv2Switches["s1%d" % i], bmv2Switches["s2%d" % j],
|
bmv2Switches["s2%d" % j],
|
||||||
cls=TCLink, bw=DEFAULT_SW_BW)
|
cls=TCLink, bw=DEFAULT_SW_BW)
|
||||||
if args.with_imbalanced_striping:
|
if args.with_imbalanced_striping:
|
||||||
self.addLink(bmv2Switches["s1%d" % i], bmv2Switches["s2%d" % j],
|
# 2 links
|
||||||
|
self.addLink(bmv2Switches["s1%d" % i],
|
||||||
|
bmv2Switches["s2%d" % j],
|
||||||
cls=TCLink, bw=DEFAULT_SW_BW)
|
cls=TCLink, bw=DEFAULT_SW_BW)
|
||||||
else:
|
else:
|
||||||
self.addLink(bmv2Switches["s1%d" % i], bmv2Switches["s2%d" % j],
|
self.addLink(bmv2Switches["s1%d" % i],
|
||||||
|
bmv2Switches["s2%d" % j],
|
||||||
cls=TCLink, bw=DEFAULT_SW_BW)
|
cls=TCLink, bw=DEFAULT_SW_BW)
|
||||||
|
|
||||||
for hostId in range(1, args.size + 1):
|
for hostId in range(1, args.size + 1):
|
||||||
@ -90,11 +98,12 @@ class ClosTopo(Topo):
|
|||||||
cls=DemoHost,
|
cls=DemoHost,
|
||||||
ip="10.0.0.%d/24" % hostId,
|
ip="10.0.0.%d/24" % hostId,
|
||||||
mac='00:00:00:00:00:%02x' % hostId)
|
mac='00:00:00:00:00:%02x' % hostId)
|
||||||
self.addLink(host, bmv2Switches["s1%d" % hostId], cls=TCLink, bw=DEFAULT_HOST_BW)
|
self.addLink(host, bmv2Switches["s1%d" % hostId],
|
||||||
|
cls=TCLink, bw=DEFAULT_HOST_BW)
|
||||||
|
|
||||||
|
|
||||||
class DemoHost(ONOSHost):
|
class DemoHost(ONOSHost):
|
||||||
"Demo host"
|
"""Demo host"""
|
||||||
|
|
||||||
def __init__(self, name, **params):
|
def __init__(self, name, **params):
|
||||||
ONOSHost.__init__(self, name, **params)
|
ONOSHost.__init__(self, name, **params)
|
||||||
@ -109,10 +118,11 @@ class DemoHost(ONOSHost):
|
|||||||
self.cmd(self.getInfiniteCmdBg("iperf -s -u"))
|
self.cmd(self.getInfiniteCmdBg("iperf -s -u"))
|
||||||
|
|
||||||
def startIperfClient(self, h, flowBw="512k", numFlows=5, duration=5):
|
def startIperfClient(self, h, flowBw="512k", numFlows=5, duration=5):
|
||||||
iperfCmd = "iperf -c{} -u -b{} -P{} -t{}".format(h.IP(), flowBw, numFlows, duration)
|
iperfCmd = "iperf -c{} -u -b{} -P{} -t{}".format(
|
||||||
self.cmd(self.getInfiniteCmdBg(iperfCmd, sleep=0))
|
h.IP(), flowBw, numFlows, duration)
|
||||||
|
self.cmd(self.getInfiniteCmdBg(iperfCmd, delay=0))
|
||||||
|
|
||||||
def stop(self):
|
def stop(self, **kwargs):
|
||||||
self.cmd("killall iperf")
|
self.cmd("killall iperf")
|
||||||
self.cmd("killall ping")
|
self.cmd("killall ping")
|
||||||
self.cmd("killall arping")
|
self.cmd("killall arping")
|
||||||
@ -127,28 +137,27 @@ class DemoHost(ONOSHost):
|
|||||||
)
|
)
|
||||||
print "**********"
|
print "**********"
|
||||||
|
|
||||||
def getInfiniteCmdBg(self, cmd, logfile="/dev/null", sleep=1):
|
def getInfiniteCmdBg(self, cmd, logfile="/dev/null", delay=1):
|
||||||
return "(while [ -e {} ]; " \
|
return "(while [ -e {} ]; " \
|
||||||
"do {}; " \
|
"do {}; " \
|
||||||
"sleep {}; " \
|
"sleep {}; " \
|
||||||
"done;) > {} 2>&1 &".format(self.exectoken, cmd, sleep, logfile)
|
"done;) > {} 2>&1 &".format(self.exectoken, cmd, delay, logfile)
|
||||||
|
|
||||||
def getCmdBg(self, cmd, logfile="/dev/null"):
|
|
||||||
return "{} > {} 2>&1 &".format(cmd, logfile)
|
|
||||||
|
|
||||||
|
|
||||||
def generateNetcfg(onosIp, net, args):
|
def generateNetcfg(onosIp, net, args):
|
||||||
netcfg = OrderedDict()
|
netcfg = OrderedDict()
|
||||||
|
|
||||||
|
netcfg['hosts'] = {}
|
||||||
netcfg['devices'] = {}
|
netcfg['devices'] = {}
|
||||||
netcfg['links'] = {}
|
netcfg['links'] = {}
|
||||||
netcfg['hosts'] = {}
|
|
||||||
# Device configs
|
if args.full_netcfg:
|
||||||
for sw in net.switches:
|
# Device configs
|
||||||
srcIp = sw.getSourceIp(onosIp)
|
for sw in net.switches:
|
||||||
netcfg['devices'][sw.onosDeviceId] = sw.getDeviceConfig(srcIp)
|
srcIp = sw.getSourceIp(onosIp)
|
||||||
|
netcfg['devices'][sw.onosDeviceId] = sw.getDeviceConfig(srcIp)
|
||||||
|
|
||||||
hostLocations = {}
|
hostLocations = {}
|
||||||
# Link configs
|
|
||||||
for link in net.links:
|
for link in net.links:
|
||||||
switchPort = link.intf1.name.split('-')
|
switchPort = link.intf1.name.split('-')
|
||||||
sw1Name = switchPort[0] # s11
|
sw1Name = switchPort[0] # s11
|
||||||
@ -172,14 +181,18 @@ def generateNetcfg(onosIp, net, args):
|
|||||||
hostLocations[sw2.name] = '%s/%s' % (sw1.onosDeviceId, port1)
|
hostLocations[sw2.name] = '%s/%s' % (sw1.onosDeviceId, port1)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for linkId in ('%s/%s-%s/%s' % (sw1.onosDeviceId, port1, sw2.onosDeviceId, port2),
|
if args.full_netcfg:
|
||||||
'%s/%s-%s/%s' % (sw2.onosDeviceId, port2, sw1.onosDeviceId, port1)):
|
# Link configs
|
||||||
netcfg['links'][linkId] = {
|
for linkId in ('%s/%s-%s/%s' % (sw1.onosDeviceId, port1,
|
||||||
'basic': {
|
sw2.onosDeviceId, port2),
|
||||||
'type': 'DIRECT',
|
'%s/%s-%s/%s' % (sw2.onosDeviceId, port2,
|
||||||
'bandwidth': DEFAULT_SW_BW
|
sw1.onosDeviceId, port1)):
|
||||||
|
netcfg['links'][linkId] = {
|
||||||
|
'basic': {
|
||||||
|
'type': 'DIRECT',
|
||||||
|
'bandwidth': DEFAULT_SW_BW
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# Host configs
|
# Host configs
|
||||||
longitude = BASE_LONGITUDE
|
longitude = BASE_LONGITUDE
|
||||||
@ -203,13 +216,14 @@ def generateNetcfg(onosIp, net, args):
|
|||||||
}
|
}
|
||||||
netcfg['hosts'][hostId] = hostConfig
|
netcfg['hosts'][hostId] = hostConfig
|
||||||
|
|
||||||
netcfg["apps"] = {
|
if args.full_netcfg:
|
||||||
"org.onosproject.core": {
|
netcfg["apps"] = {
|
||||||
"core": {
|
"org.onosproject.core": {
|
||||||
"linkDiscoveryMode": "STRICT"
|
"core": {
|
||||||
|
"linkDiscoveryMode": "STRICT"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
print "Writing network config to %s" % TEMP_NETCFG_FILE
|
print "Writing network config to %s" % TEMP_NETCFG_FILE
|
||||||
with open(TEMP_NETCFG_FILE, 'w') as tempFile:
|
with open(TEMP_NETCFG_FILE, 'w') as tempFile:
|
||||||
@ -233,7 +247,7 @@ def main(args):
|
|||||||
|
|
||||||
print "Network started"
|
print "Network started"
|
||||||
|
|
||||||
# Generate background traffic.
|
# Always generate background pings.
|
||||||
sleep(3)
|
sleep(3)
|
||||||
for (h1, h2) in combinations(net.hosts, 2):
|
for (h1, h2) in combinations(net.hosts, 2):
|
||||||
h1.startPingBg(h2)
|
h1.startPingBg(h2)
|
||||||
@ -246,14 +260,17 @@ def main(args):
|
|||||||
|
|
||||||
print "Iperf servers started"
|
print "Iperf servers started"
|
||||||
|
|
||||||
# sleep(4)
|
if args.bg_traffic:
|
||||||
# print "Starting traffic from h1 to h3..."
|
sleep(4)
|
||||||
# net.hosts[0].startIperfClient(net.hosts[-1], flowBw="200k", numFlows=100, duration=10)
|
print "Starting iperf clients..."
|
||||||
|
net.hosts[0].startIperfClient(net.hosts[-1], flowBw="400k",
|
||||||
|
numFlows=50, duration=10)
|
||||||
|
|
||||||
generateNetcfg(onosIp, net, args)
|
generateNetcfg(onosIp, net, args)
|
||||||
|
|
||||||
if args.netcfg_sleep > 0:
|
if args.netcfg_sleep > 0:
|
||||||
print "Waiting %d seconds before pushing config to ONOS..." % args.netcfg_sleep
|
print "Waiting %d seconds before pushing config to ONOS..." \
|
||||||
|
% args.netcfg_sleep
|
||||||
sleep(args.netcfg_sleep)
|
sleep(args.netcfg_sleep)
|
||||||
|
|
||||||
print "Pushing config to ONOS..."
|
print "Pushing config to ONOS..."
|
||||||
@ -275,12 +292,25 @@ if __name__ == '__main__':
|
|||||||
type=str, action="store", required=False)
|
type=str, action="store", required=False)
|
||||||
parser.add_argument('--size', help='Number of leaf/spine switches',
|
parser.add_argument('--size', help='Number of leaf/spine switches',
|
||||||
type=int, action="store", required=False, default=2)
|
type=int, action="store", required=False, default=2)
|
||||||
parser.add_argument('--with-imbalanced-striping', help='Topology with imbalanced striping',
|
parser.add_argument('--with-imbalanced-striping',
|
||||||
type=bool, action="store", required=False, default=False)
|
help='Topology with imbalanced striping',
|
||||||
|
type=bool, action="store", required=False,
|
||||||
|
default=False)
|
||||||
parser.add_argument('--pipeconf-id', help='Pipeconf ID for switches',
|
parser.add_argument('--pipeconf-id', help='Pipeconf ID for switches',
|
||||||
type=str, action="store", required=False, default='')
|
type=str, action="store", required=False, default='')
|
||||||
parser.add_argument('--netcfg-sleep', help='Seconds to wait before pushing config to ONOS',
|
parser.add_argument('--netcfg-sleep',
|
||||||
|
help='Seconds to wait before pushing config to ONOS',
|
||||||
type=int, action="store", required=False, default=5)
|
type=int, action="store", required=False, default=5)
|
||||||
args = parser.parse_args()
|
parser.add_argument('--log-level', help='BMv2 log level',
|
||||||
|
type=str, action="store", required=False,
|
||||||
|
default='warn')
|
||||||
|
parser.add_argument('--full-netcfg',
|
||||||
|
help='Generate full netcfg JSON with links and devices',
|
||||||
|
type=bool, action="store", required=False,
|
||||||
|
default=False)
|
||||||
|
parser.add_argument('--bg-traffic',
|
||||||
|
help='Starts background traffic',
|
||||||
|
type=bool, action="store", required=False,
|
||||||
|
default=False)
|
||||||
setLogLevel('info')
|
setLogLevel('info')
|
||||||
main(args)
|
main(parser.parse_args())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user