Skip to content

Instantly share code, notes, and snippets.

@charlesmcchan
Created February 19, 2014 13:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save charlesmcchan/9092080 to your computer and use it in GitHub Desktop.
Save charlesmcchan/9092080 to your computer and use it in GitHub Desktop.
MPTCP test environment
#!/usr/bin/python
import sys
from time import sleep
from math import sqrt
import argparse
from subprocess import Popen, PIPE
from mininet.net import Mininet
from mininet.link import TCLink
from mininet.topo import Topo
from mininet.log import lg
"""
bandwidth: Mbps
delay: ms, 1-way
loss rate: 0-100
queue size: # packets
"""
links = [
[10, 20, 0, 1000000],
[10, 20, 0, 1000000]
]
class TwoHostNLink(Topo):
def __init__(self, **opts):
super(TwoHostNLink, self).__init__(**opts)
# add switches
switches = []
for i in range(len(links)):
switches.append('s%i' % (i+1))
self.addSwitch('s%i' % (i+1))
# add hosts
self.addHost('h1')
self.addHost('h2')
# add links
for i in range(len(links)):
bw = links[i][0]
delay = links[i][1]/2
loss = (100-sqrt(100-links[i][2]))/100
qsize = links[i][3]
self.addLink('h1', switches[i], bw=bw, delay=str(delay)+'ms', loss=loss, max_queue_size=qsize)
self.addLink('h2', switches[i], bw=bw, delay=str(delay)+'ms', loss=loss, max_queue_size=qsize)
def progress(t):
while t > 0:
print "%3d seconds left" % t
t -= 1
sleep(1)
print "\n"
def parse_args():
parser = argparse.ArgumentParser(description="MPTCP 2-host n-switch test")
parser.add_argument('--mptcp',
action="store_true",
help="Enable MPTCP (net.mptcp.mptcp_enabled)",
default=False)
parser.add_argument('--ndiffports',
action="store",
help="Set # subflows (net.mptcp.mptcp_ndiffports)",
default=1)
parser.add_argument('-t',
action="store",
help="Seconds to run the experiment",
default=2)
args = parser.parse_args()
args.ndiffports = int(args.ndiffports)
return args
def sysctl_set(key, value):
"""Issue systcl for given param to given value and check for error."""
p = Popen("sysctl -w %s=%s" % (key, value), shell=True, stdout=PIPE,
stderr=PIPE)
# Output should be empty; otherwise, we have an issue.
stdout, stderr = p.communicate()
stdout_expected = "%s = %s\n" % (key, value)
if stdout != stdout_expected:
raise Exception("Popen returned unexpected stdout: %s != %s" % (stdout, stdout_expected))
if stderr:
raise Exception("Popen returned unexpected stderr: %s" % stderr)
def set_mptcp_enabled(enabled):
"""Enable MPTCP if true, disable if false"""
e = 1 if enabled else 0
lg.info("setting MPTCP enabled to %s\n" % e)
sysctl_set('net.mptcp.mptcp_enabled', e)
def set_mptcp_ndiffports(ports):
"""Set ndiffports, the number of subflows to instantiate"""
lg.info("setting MPTCP ndiffports to %s\n" % ports)
sysctl_set("net.mptcp.mptcp_ndiffports", ports)
def setup(args):
set_mptcp_enabled(args.mptcp)
set_mptcp_ndiffports(args.ndiffports)
def end(args):
set_mptcp_enabled(False)
set_mptcp_ndiffports(1)
def run(args, net):
seconds = int(args.t)
h1 = net.getNodeByName('h1')
h2 = net.getNodeByName('h2')
for i in range(len(links)):
# Setup IPs:
h1.cmdPrint('ifconfig h1-eth%i 10.0.%i.3 netmask 255.255.255.0' % (i, i))
h2.cmdPrint('ifconfig h2-eth%i 10.0.%i.4 netmask 255.255.255.0' % (i, i))
if args.mptcp:
lg.info("configuring source-specific routing tables for MPTCP\n")
# This creates two different routing tables, that we use based on the
# source-address.
dev = 'h1-eth%i' % i
table = '%s' % (i + 1)
h1.cmdPrint('ip rule add from 10.0.%i.3 table %s' % (i, table))
h1.cmdPrint('ip route add 10.0.%i.0/24 dev %s scope link table %s' % (i, dev, table))
h1.cmdPrint('ip route add default via 10.0.%i.1 dev %s table %s' % (i, dev, table))
# TODO: expand this to verify connectivity with a ping test.
lg.info("pinging each destination interface\n")
for i in range(len(links)):
h2_out = h2.cmd('ping -c 1 10.0.%i.3' % i)
lg.info("ping test output: %s\n" % h2_out)
lg.info("iperfing\n")
h2.sendCmd('iperf -s -i 1')
cmd = 'iperf -c 10.0.0.4 -t %d -i 1' % seconds
h1.sendCmd(cmd)
progress(seconds + 1)
h1_out = h1.waitOutput()
lg.info("client output:\n%s\n" % h1_out)
sleep(0.1) # hack to wait for iperf server output.
out = h2.read(10000)
lg.info("server output: %s\n" % out)
return None
def genericTest(args, topo, setup, run, end):
net = Mininet(topo=topo, link=TCLink)
setup(args)
net.start()
data = run(args, net)
net.stop()
end(args)
return data
def main():
args = parse_args()
lg.setLogLevel('info')
topo = TwoHostNLink()
genericTest(args, topo, setup, run, end)
if __name__ == '__main__':
main()
@alitalpur99
Copy link

Hello,
I wanted to run the above code in Ubuntu 14.04 , running MPTCP kernel and mininet ver 2.2.1. It gives following error, can you help in this regard:

File "mptcp-test.py", line 90, in set_mptcp_enabled
sysctl_set('net.mptcp.mptcp_enabled', e)
File "mptcp-test.py", line 82, in sysctl_set
raise Exception("Popen returned unexpected stdout: %s != %s" % (stdout, stdout_expected))
Exception: Popen returned unexpected stdout: != net.mptcp.mptcp_enabled = 0

@delinage
Copy link

delinage commented Dec 1, 2016

Hello, I get an assertion error on net.stop(). Do you know how can I solve it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment