Commit 8ae7eb92 authored by Martín Ferrari's avatar Martín Ferrari

Sample script

parent adf25d81
...@@ -7,25 +7,31 @@ __doc__ = """Creates a linear network topology, and measures the maximum ...@@ -7,25 +7,31 @@ __doc__ = """Creates a linear network topology, and measures the maximum
end-to-end throughput for the specified packet size.""" end-to-end throughput for the specified packet size."""
def usage(f): def usage(f):
f.write("Usage: %s --nodes=NUM --pktsize=BYTES [OPTIONS]\n%s\n\n" % f.write("Usage: %s --nodes=NUM [TOPOLOGY_OPTIONS] [TEST_OPTIONS]\n%s\n\n" %
(os.path.basename(sys.argv[0]), __doc__)) (os.path.basename(sys.argv[0]), __doc__))
f.write("Mandatory arguments:\n")
f.write(" -n, --nodes=NUM Number of nodes to create\n")
f.write(" -s, --pktsize=BYTES Size of packet payload\n\n")
f.write("Topology configuration:\n") f.write("Topology configuration:\n")
f.write(" --use-p2p Use P2P switchs, to avoid bridging\n") f.write(" -n, --nodes=NUM Number of nodes to create (mandatory)\n")
f.write(" --delay=SECS Add delay emulation in switchs\n") f.write(" --use-p2p Use P2P links, to avoid bridging\n")
f.write(" --jitter=PERCENT Add jitter emulation in switchs\n") f.write(" --delay=SECS Add delay emulation in links\n")
f.write(" --bandwidth=BPS Maximum bandwidth of switchs\n\n") f.write(" --jitter=PERCENT Add jitter emulation in links\n")
f.write(" --bandwidth=BPS Maximum bandwidth of links\n\n")
f.write("How long should the benchmark run (defaults to -t 10):\n")
f.write(" -t, --time=SECS Stop after SECS seconds\n") f.write("Test specification:\n")
f.write(" -p, --packets=NUM Stop after NUM packets\n") f.write(" Parameters take single values or ranges of falues in the form " +
f.write(" -b, --bytes=BYTES Stop after BYTES bytes sent\n\n") "nnn-NNN, a test\n")
f.write(" will be run for each possible combination.\n")
f.write(" -s, --pktsize=BYTES Size of packet payload (mandatory)\n")
f.write(" --bwlimit=BPS Apply bandwidth limitation in the " +
"traffic generator\n\n")
# background noise
f.write("How long should each test run (defaults to -t 10):\n")
f.write(" -t, --time=SECS Stop after SECS seconds\n")
f.write(" -p, --packets=NUM Stop after NUM packets\n")
f.write(" -b, --bytes=BYTES Stop after BYTES bytes sent\n\n")
f.write("Output format:\n") f.write("Output format:\n")
f.write(" --format=FMT Valid values are `csv', `brief', " + f.write(" --format=FMT Valid values are `csv', `brief', " +
"and `verbose'\n") "and `verbose'\n")
def main(): def main():
...@@ -89,7 +95,7 @@ def main(): ...@@ -89,7 +95,7 @@ def main():
elif not pktsize: elif not pktsize:
error = "Missing mandatory --pktsize argument" error = "Missing mandatory --pktsize argument"
elif use_p2p and (delay or jitter or bandwidth): elif use_p2p and (delay or jitter or bandwidth):
error = "Cannot use switch emulation with P2P switchs" error = "Cannot use links emulation with P2P links"
if error: if error:
sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), error)) sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), error))
...@@ -106,7 +112,7 @@ def main(): ...@@ -106,7 +112,7 @@ def main():
if not udp_perf: if not udp_perf:
raise RuntimeError("Cannot find `udp-perf'") raise RuntimeError("Cannot find `udp-perf'")
nodes, interfaces, switchs = create_topo(nr, use_p2p, delay, jitter, nodes, interfaces, links = create_topo(nr, use_p2p, delay, jitter,
bandwidth) bandwidth)
cmdline = [udp_perf, "--server"] cmdline = [udp_perf, "--server"]
...@@ -189,7 +195,7 @@ def dec2ip(dec): ...@@ -189,7 +195,7 @@ def dec2ip(dec):
def create_topo(n, p2p, delay, jitter, bw): def create_topo(n, p2p, delay, jitter, bw):
nodes = [] nodes = []
interfaces = [] interfaces = []
switchs = [] links = []
for i in range(n): for i in range(n):
nodes.append(netns.Node()) nodes.append(netns.Node())
if p2p: if p2p:
...@@ -212,12 +218,12 @@ def create_topo(n, p2p, delay, jitter, bw): ...@@ -212,12 +218,12 @@ def create_topo(n, p2p, delay, jitter, bw):
right = None right = None
interfaces.append((left, right)) interfaces.append((left, right))
for i in range(n - 1): for i in range(n - 1):
switch = netns.Switch(bandwidth = bw, delay = delay, links = netns.Switch(bandwidth = bw, delay = delay,
delay_jitter = jitter) delay_jitter = jitter)
switch.up = True links.up = True
switch.connect(interfaces[i][1]) links.connect(interfaces[i][1])
switch.connect(interfaces[i + 1][0]) links.connect(interfaces[i + 1][0])
switchs.append(switch) links.append(links)
for i in range(n): for i in range(n):
for j in (0, 1): for j in (0, 1):
...@@ -237,7 +243,7 @@ def create_topo(n, p2p, delay, jitter, bw): ...@@ -237,7 +243,7 @@ def create_topo(n, p2p, delay, jitter, bw):
nexthop = dec2ip(ipbase + 4 * i + 2)) nexthop = dec2ip(ipbase + 4 * i + 2))
nodes[n - 1 - i].add_route(prefix = "10.0.0.0", prefix_len = 30, nodes[n - 1 - i].add_route(prefix = "10.0.0.0", prefix_len = 30,
nexthop = dec2ip(ipbase + (n - 2 - i) * 4 + 1)) nexthop = dec2ip(ipbase + (n - 2 - i) * 4 + 1))
return nodes, interfaces, switchs return nodes, interfaces, links
if __name__ == "__main__": if __name__ == "__main__":
main() main()
#/usr/bin/env python
# vim:ts=4:sw=4:et:ai:sts=4
import netns, subprocess
# each Node is a netns
node0 = netns.Node()
node1 = netns.Node()
node2 = netns.Node()
print "Nodes started with pids: %s\n" % str((node0.pid, node1.pid, node2.pid))
# interface object maps to a veth pair with one end in a netns
if0 = netns.NodeInterface(node0)
if1a = netns.NodeInterface(node1)
# Between node1 and node2, we use a P2P interface
(if1b, if2) = netns.P2PInterface.create_pair(node1, node2)
switch0 = netns.Switch(
bandwidth = 100 * 1024 * 1024,
delay = 0.01, # 10 ms
delay_correlation = 0.25, # 25% correlation
loss = 0.005)
# connect the interfaces
switch0.connect(if0)
switch0.connect(if1a)
# bring the interfaces up
switch0.up = if0.up = if1a.up = if1b.up = if2.up = True
# Add IP addresses
if0.add_v4_address(addr = '10.0.0.1', prefix_len = 24)
if1a.add_v4_address(addr = '10.0.0.2', prefix_len = 24)
if1b.add_v4_address(addr = '10.0.1.1', prefix_len = 24)
if2.add_v4_address(addr = '10.0.1.2', prefix_len = 24)
# RFC-4193 Unique local addresses.
# Pre-generated random block: fde2:4a1d:8870::/48
if0.add_v6_address(addr = 'fde2:4a1d:8870:0::0', prefix_len = 32)
if1a.add_v6_address(addr = 'fde2:4a1d:8870:0::1', prefix_len = 32)
if1b.add_v6_address(addr = 'fde2:4a1d:8870:1::0', prefix_len = 32)
if2.add_v6_address(addr = 'fde2:4a1d:8870:1::1', prefix_len = 32)
# Configure routing
node0.add_route(prefix = '10.0.1.0', prefix_len = 24, nexthop = '10.0.0.2')
node2.add_route(prefix = '10.0.0.0', prefix_len = 24, nexthop = '10.0.1.1')
node0.add_route(prefix = 'fde2:4a1d:8870:1::', prefix_len = 32,
nexthop = 'fde2:4a1d:8870:0::1')
node2.add_route(prefix = 'fde2:4a1d:8870:0::', prefix_len = 32,
nexthop = 'fde2:4a1d:8870:1::0')
# Test connectivity first. Run process, hide output and check return code
app0 = node0.Popen("ping -c 1 10.0.1.2", shell = True, stdout = subprocess.NONE)
ret = app0.wait()
assert ret == 0
app1 = node2.Popen("ping -c 1 10.0.0.1", shell = True, stdout = subprocess.NONE)
ret = app1.wait()
assert ret == 0
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment