def test_run_ping_routing(self): n1 = nemu.Node() n2 = nemu.Node() n3 = nemu.Node() i1 = n1.add_if() i2a = n2.add_if() i2b = n2.add_if() i3 = n3.add_if() i1.up = i2a.up = i2b.up = i3.up = True l1 = nemu.Switch() l2 = nemu.Switch() l1.connect(i1) l1.connect(i2a) l2.connect(i2b) l2.connect(i3) l1.up = l2.up = True i1.add_v4_address('10.0.0.1', 24) i2a.add_v4_address('10.0.0.2', 24) i2b.add_v4_address('10.0.1.1', 24) i3.add_v4_address('10.0.1.2', 24) n1.add_route(prefix='10.0.1.0', prefix_len=24, nexthop='10.0.0.2') n3.add_route(prefix='10.0.0.0', prefix_len=24, nexthop='10.0.1.1') null = file('/dev/null', 'wb') a1 = n1.Popen(['ping', '-qc1', '10.0.1.2'], stdout=null) a2 = n3.Popen(['ping', '-qc1', '10.0.0.1'], stdout=null) self.assertEquals(a1.wait(), 0) self.assertEquals(a2.wait(), 0)
def test_run_ping_p2pif(self): n1 = nemu.Node() n2 = nemu.Node() i1, i2 = nemu.P2PInterface.create_pair(n1, n2) i1.up = i2.up = True i1.lladdr = 'd6:4b:3f:f7:ff:7e' i2.lladdr = 'd6:4b:3f:f7:ff:7f' i1.add_v4_address('10.0.0.1', 24) i2.add_v4_address('10.0.0.2', 24) null = file('/dev/null', 'wb') a1 = n1.Popen(['ping', '-qc1', '10.0.0.2'], stdout=null) a2 = n2.Popen(['ping', '-qc1', '10.0.0.1'], stdout=null) self.assertEquals(a1.wait(), 0) self.assertEquals(a2.wait(), 0) # Test ipv6 autoconfigured addresses time.sleep(2) # Wait for autoconfiguration a1 = n1.Popen( ['ping6', '-qc1', '-I', i1.name, 'fe80::d44b:3fff:fef7:ff7f'], stdout=null) a2 = n2.Popen( ['ping6', '-qc1', '-I', i2.name, 'fe80::d44b:3fff:fef7:ff7e'], stdout=null) self.assertEquals(a1.wait(), 0) self.assertEquals(a2.wait(), 0)
def create_stuff(): a = nemu.Node() b = nemu.Node() ifa = a.add_if() ifb = b.add_if() switch = nemu.Switch() switch.connect(ifa) switch.connect(ifb)
def setUp(self): n1 = nemu.Node() n2 = nemu.Node() i1 = n1.add_if() i2 = n2.add_if() l = nemu.Switch() l.connect(i1) l.connect(i2) self.stuff = (n1, n2, i1, i2, l)
def test_Subprocess_chuser(self): node = nemu.Node(nonetns=True) user = '******' p = node.Subprocess(['/bin/sleep', '1000'], user=user) self._check_ownership(user, p.pid) p.signal() self.assertEquals(p.wait(), -signal.SIGTERM)
def test_interface_addresses(self): node0 = nemu.Node() if0 = node0.add_if() if0.add_v4_address(address='10.0.0.1', prefix_len=24, broadcast='10.0.0.255') if0.add_v4_address(address='10.0.2.1', prefix_len=26) if0.add_v6_address(address='fe80::222:19ff:fe22:615d', prefix_len=64) devs = get_devs_netns(node0) self.assertTrue({ 'address': '10.0.0.1', 'prefix_len': 24, 'broadcast': '10.0.0.255', 'family': 'inet' } in devs[if0.name]['addr']) self.assertTrue({ 'address': '10.0.2.1', 'prefix_len': 26, 'broadcast': '10.0.2.63', 'family': 'inet' } in devs[if0.name]['addr']) self.assertTrue({ 'address': 'fe80::222:19ff:fe22:615d', 'prefix_len': 64, 'family': 'inet6' } in devs[if0.name]['addr']) self.assertTrue(len(if0.get_addresses()) >= 2) self.assertEquals(if0.get_addresses(), devs[if0.name]['addr'])
def test_routing(self): node = nemu.Node() self.assertEquals(len(node.get_routes()), 0) if0 = node.add_if() if0.add_v4_address('10.0.0.1', 24) if0.up = True routes = node.get_routes() self.assertEquals( routes, [node.route(prefix='10.0.0.0', prefix_len=24, interface=if0)]) node.add_route(nexthop='10.0.0.2') # default route node.add_route(prefix='10.1.0.0', prefix_len=16, nexthop='10.0.0.3') node.add_route(prefix='11.1.0.1', prefix_len=32, interface=if0) routes = node.get_routes() self.assertTrue( node.route(nexthop='10.0.0.2', interface=if0) in routes) self.assertTrue( node.route(prefix='10.1.0.0', prefix_len=16, nexthop='10.0.0.3', interface=if0) in routes) self.assertTrue( node.route(prefix='11.1.0.1', prefix_len=32, interface=if0) in routes) node.del_route(nexthop='10.0.0.2') # default route node.del_route(prefix='10.1.0.0', prefix_len=16, nexthop='10.0.0.3') node.del_route(prefix='11.1.0.1', prefix_len=32, interface=if0) node.del_route(prefix='10.0.0.0', prefix_len=24, interface=if0) self.assertEquals(node.get_routes(), [])
def test_interface_migration(self): node = nemu.Node() self.dummyname = "dummy%d" % os.getpid() self.assertEquals( os.system("%s link add name %s type dummy" % (IP_PATH, self.dummyname)), 0) devs = get_devs() self.assertTrue(self.dummyname in devs) dummyidx = devs[self.dummyname]['idx'] if0 = node.import_if(self.dummyname) self.assertTrue(self.dummyname not in get_devs()) node_devs = dict([(i.index, i) for i in node.get_interfaces()]) self.assertTrue(dummyidx in node_devs) if0.lladdr = '42:71:e0:90:ca:43' if0.mtu = 1400 devs = get_devs_netns(node) self.assertTrue(if0.name in devs) self.assertEquals(devs[if0.name]['lladdr'], '42:71:e0:90:ca:43') self.assertEquals(devs[if0.name]['mtu'], 1400) node.destroy() self.assertTrue(self.dummyname in get_devs())
def test_base_routing(self): node = nemu.Node(nonetns=True) routes = node.get_routes() # main netns routes! if (len(routes)): self.assertRaises(RuntimeError, node.add_route, routes[0]) routes[0].metric += 1 # should be enough to make it unique self.assertRaises(RuntimeError, node.del_route, routes[0])
def test_run_ping_tap(self): """This test simulates a point to point connection between two hosts using two tap devices.""" n1 = nemu.Node() n2 = nemu.Node() tap1 = n1.add_tap() tap2 = n2.add_tap() tap1.up = tap2.up = True tap1.add_v4_address('10.0.1.1', 24) tap2.add_v4_address('10.0.1.2', 24) null = file('/dev/null', 'wb') a = n1.Popen(['ping', '-qc1', '10.0.1.2'], stdout=null) self._forward_packets(a, tap1, tap2) self.assertEquals(a.wait(), 0)
def test_run_ping_tap_routing(self): """This test simulates a point to point connection between two hosts using two tap devices, and normal connections with other two, to use routing.""" n1 = nemu.Node() n2 = nemu.Node() n3 = nemu.Node() n4 = nemu.Node() i1 = n1.add_if() i2 = n2.add_if() tap1 = n2.add_tap() tap2 = n3.add_tap() i3 = n3.add_if() i4 = n4.add_if() i1.up = i2.up = tap1.up = tap2.up = i3.up = i4.up = True l1 = nemu.Switch() l2 = nemu.Switch() l1.connect(i1) l1.connect(i2) l2.connect(i3) l2.connect(i4) l1.up = l2.up = True i1.add_v4_address('10.0.0.1', 24) i2.add_v4_address('10.0.0.2', 24) tap1.add_v4_address('10.0.1.1', 24) tap2.add_v4_address('10.0.1.2', 24) i3.add_v4_address('10.0.2.1', 24) i4.add_v4_address('10.0.2.2', 24) n1.add_route(prefix='10.0.1.0', prefix_len=24, nexthop='10.0.0.2') n1.add_route(prefix='10.0.2.0', prefix_len=24, nexthop='10.0.0.2') n2.add_route(prefix='10.0.2.0', prefix_len=24, nexthop='10.0.1.2') n3.add_route(prefix='10.0.0.0', prefix_len=24, nexthop='10.0.1.1') n4.add_route(prefix='10.0.1.0', prefix_len=24, nexthop='10.0.2.1') n4.add_route(prefix='10.0.0.0', prefix_len=24, nexthop='10.0.2.1') null = file('/dev/null', 'wb') a = n1.Popen(['ping', '-qc1', '10.0.2.2'], stdout=null) self._forward_packets(a, tap1, tap2) self.assertEquals(a.wait(), 0)
def test_run_xdpyinfo_netns(self): xdpy = nemu.environ.XDPYINFO_PATH info = nemu.environ.backticks([xdpy]) # remove first line, contains the display name info = info.partition("\n")[2] n = nemu.Node(forward_X11=True) info2 = n.backticks([xdpy]) info2 = info2.partition("\n")[2] self.assertEquals(info, info2)
def test_run_ping_tun(self): """This test simulates a point to point connection between two hosts using two tun devices.""" n1 = nemu.Node() n2 = nemu.Node() # Use PI, so that's tested too. tun1 = n1.add_tun(use_pi=True) tun2 = n2.add_tun(use_pi=True) tun1.up = tun2.up = True tun1.add_v4_address('10.0.1.1', 24) tun2.add_v4_address('10.0.1.2', 24) null = file('/dev/null', 'wb') a = n1.Popen(['ping', '-qc1', '10.0.1.2'], stdout=null) self._forward_packets(a, tun1, tun2) self.assertEquals(a.wait(), 0)
def test_run_ping_node_if(self): n1 = nemu.Node() n2 = nemu.Node() i1 = n1.add_if() i2 = n2.add_if() i1.up = i2.up = True l = nemu.Switch() l.connect(i1) l.connect(i2) l.up = True i1.add_v4_address('10.0.0.1', 24) i2.add_v4_address('10.0.0.2', 24) null = file('/dev/null', 'wb') a1 = n1.Popen(['ping', '-qc1', '10.0.0.2'], stdout=null) a2 = n2.Popen(['ping', '-qc1', '10.0.0.1'], stdout=null) self.assertEquals(a1.wait(), 0) self.assertEquals(a2.wait(), 0)
def test_backticks(self): node = nemu.Node(nonetns=True) self.assertEquals(node.backticks("echo hello world"), "hello world\n") self.assertEquals(node.backticks(r"echo hello\ \ world"), "hello world\n") self.assertEquals(node.backticks(["echo", "hello", "world"]), "hello world\n") self.assertEquals(node.backticks("echo hello world > /dev/null"), "") self.assertEquals(node.backticks_raise("true"), "") self.assertRaises(RuntimeError, node.backticks_raise, "false") self.assertRaises(RuntimeError, node.backticks_raise, "kill $$")
def create_topo(n, p2p, delay, jitter, bw): nodes = [] interfaces = [] links = [] for i in range(n): nodes.append(nemu.Node()) if p2p: interfaces = [[None]] for i in range(n - 1): a, b = nemu.P2PInterface.create_pair(nodes[i], nodes[i + 1]) interfaces[i].append(a) interfaces.append([]) interfaces[i + 1] = [b] interfaces[n - 1].append(None) else: for i in range(n): if i > 0: left = nodes[i].add_if() else: left = None if i < n - 1: right = nodes[i].add_if() else: right = None interfaces.append((left, right)) for i in range(n - 1): links = nemu.Switch(bandwidth=bw, delay=delay, delay_jitter=jitter) links.up = True links.connect(interfaces[i][1]) links.connect(interfaces[i + 1][0]) links.append(links) for i in range(n): for j in (0, 1): if interfaces[i][j]: interfaces[i][j].up = True ip = ip2dec("10.0.0.1") for i in range(n - 1): interfaces[i][1].add_v4_address(dec2ip(ip), 30) interfaces[i + 1][0].add_v4_address(dec2ip(ip + 1), 30) ip += 4 ipbase = ip2dec("10.0.0.0") lastnet = dec2ip(ipbase + 4 * (n - 2)) for i in range(n - 2): nodes[i].add_route(prefix=lastnet, prefix_len=30, nexthop=dec2ip(ipbase + 4 * i + 2)) nodes[n - 1 - i].add_route(prefix="10.0.0.0", prefix_len=30, nexthop=dec2ip(ipbase + (n - 2 - i) * 4 + 1)) return nodes, interfaces, links
def test_node(self): node = nemu.Node() self.failIfEqual(node.pid, os.getpid()) self.failIfEqual(node.pid, None) # check if it really exists os.kill(node.pid, 0) nodes = nemu.get_nodes() self.assertEquals(nodes, [node]) self.assertTrue(node.get_interface("lo").up)
def test_run_ping_routing_p2p(self): n1 = nemu.Node() n2 = nemu.Node() n3 = nemu.Node() i12, i21 = nemu.P2PInterface.create_pair(n1, n2) i23, i32 = nemu.P2PInterface.create_pair(n2, n3) i12.up = i21.up = i23.up = i32.up = True i12.add_v4_address('10.0.0.1', 24) i21.add_v4_address('10.0.0.2', 24) i23.add_v4_address('10.0.1.1', 24) i32.add_v4_address('10.0.1.2', 24) n1.add_route(prefix='10.0.1.0', prefix_len=24, nexthop='10.0.0.2') n3.add_route(prefix='10.0.0.0', prefix_len=24, nexthop='10.0.1.1') null = file('/dev/null', 'wb') a1 = n1.Popen(['ping', '-qc1', '10.0.1.2'], stdout=null) a2 = n3.Popen(['ping', '-qc1', '10.0.0.1'], stdout=null) self.assertEquals(a1.wait(), 0) self.assertEquals(a2.wait(), 0)
def test_interface_settings(self): node0 = nemu.Node() if0 = node0.add_if(lladdr='42:71:e0:90:ca:42', mtu=1492) self.assertEquals(if0.lladdr, '42:71:e0:90:ca:42', "Constructor parameters") self.assertEquals(if0.mtu, 1492, "Constructor parameters") if0.lladdr = '4271E090CA42' self.assertEquals( if0.lladdr, '42:71:e0:90:ca:42', """Normalization of link-level address: missing colons and upper caps""") if0.lladdr = '2:71:E0:90:CA:42' self.assertEquals( if0.lladdr, '02:71:e0:90:ca:42', """Normalization of link-level address: missing zeroes""") if0.lladdr = '271E090CA42' self.assertEquals( if0.lladdr, '02:71:e0:90:ca:42', """Automatic normalization of link-level address: missing colons and zeroes""") self.assertRaises(ValueError, setattr, if0, 'lladdr', 'foo') self.assertRaises(ValueError, setattr, if0, 'lladdr', '1234567890123') self.assertEquals(if0.mtu, 1492) # detected by setter self.assertRaises(ValueError, setattr, if0, 'mtu', 0) # error from ip self.assertRaises(RuntimeError, setattr, if0, 'mtu', 1) self.assertRaises(RuntimeError, setattr, if0, 'mtu', 65537) devs = get_devs_netns(node0) self.assertTrue(if0.name in devs) self.assertFalse(devs[if0.name]['up']) self.assertEquals(devs[if0.name]['lladdr'], if0.lladdr) self.assertEquals(devs[if0.name]['mtu'], if0.mtu) if0.up = True devs = get_devs_netns(node0) self.assertTrue(devs[if0.name]['up']) # Verify that data is actually read from the kernel r = node0.system([IP_PATH, "link", "set", if0.name, "mtu", "1500"]) self.assertEquals(r, 0) devs = get_devs_netns(node0) self.assertEquals(devs[if0.name]['mtu'], 1500) self.assertEquals(devs[if0.name]['mtu'], if0.mtu)
def test_interface_creation(self): node0 = nemu.Node() ifaces = [] for i in range(5): ifaces.append(node0.add_if()) devs = get_devs_netns(node0) for i in range(5): self.assertTrue(devs['lo']['up']) self.assertTrue(ifaces[i].name in devs) node_devs = set(node0.get_interfaces()) self.assertTrue(set(ifaces).issubset(node_devs)) loopback = node_devs - set(ifaces) # should be! self.assertEquals(len(loopback), 1) self.assertEquals(loopback.pop().name, 'lo') devs = get_devs() for i in range(5): peer_name = nemu.iproute.get_if(ifaces[i].control.index).name self.assertTrue(peer_name in devs)
import os, nemu, subprocess, time xterm = nemu.environ.find_bin("xterm") mtr = nemu.environ.find_bin("mtr") X = "DISPLAY" in os.environ and xterm # Do not use X stuff. X = False # each Node is a netns node = [] switch = [] iface = {} SIZE = 5 for i in range(SIZE): node.append(nemu.Node(forward_X11=X)) next_pair = (i, i + 1) prev_pair = (i, i - 1) if i < SIZE - 1: iface[(i, i + 1)] = nemu.NodeInterface(node[i]) iface[(i, i + 1)].up = True iface[(i, i + 1)].add_v4_address(address='10.0.%d.1' % i, prefix_len=24) if i > 0: iface[(i, i - 1)] = nemu.NodeInterface(node[i]) iface[(i, i - 1)].up = True iface[(i, i - 1)].add_v4_address(address='10.0.%d.2' % (i - 1), prefix_len=24) switch.append(nemu.Switch()) switch[-1].connect(iface[(i, i - 1)]) switch[-1].connect(iface[(i - 1, i)])
def test_system(self): node = nemu.Node(nonetns=True) self.assertEquals(node.system("true"), 0) self.assertEquals(node.system("false"), 1)
def test_Popen(self): node = nemu.Node(nonetns=True) # repeat test with Popen interface r0, w0 = os.pipe() r1, w1 = os.pipe() p = node.Popen('cat', stdout=w0, stdin=r1) os.close(w0) os.close(r1) os.write(w1, "hello world\n") os.close(w1) self.assertEquals(_readall(r0), "hello world\n") os.close(r0) # now with a socketpair, not using integers (s0, s1) = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM, 0) p = node.Popen('cat', stdout=s0, stdin=s0) s0.close() s1.send("hello world\n") self.assertEquals(s1.recv(512), "hello world\n") s1.close() # pipes p = node.Popen('cat', stdin=sp.PIPE, stdout=sp.PIPE) p.stdin.write("hello world\n") p.stdin.close() self.assertEquals(p.stdout.readlines(), ["hello world\n"]) self.assertEquals(p.stderr, None) self.assertEquals(p.wait(), 0) p = node.Popen('cat', stdin=sp.PIPE, stdout=sp.PIPE) self.assertEquals(p.communicate(_longstring), (_longstring, None)) p = node.Popen('cat', stdin=sp.PIPE, stdout=sp.PIPE) p.stdin.write(_longstring) self.assertEquals(p.communicate(), (_longstring, None)) p = node.Popen('cat', stdin=sp.PIPE) self.assertEquals(p.communicate(), (None, None)) p = node.Popen('cat >&2', shell=True, stdin=sp.PIPE, stderr=sp.PIPE) p.stdin.write("hello world\n") p.stdin.close() self.assertEquals(p.stderr.readlines(), ["hello world\n"]) self.assertEquals(p.stdout, None) self.assertEquals(p.wait(), 0) p = node.Popen(['sh', '-c', 'cat >&2'], stdin=sp.PIPE, stderr=sp.PIPE) self.assertEquals(p.communicate(_longstring), (None, _longstring)) # p = node.Popen(['sh', '-c', 'cat >&2'], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.STDOUT) p.stdin.write("hello world\n") p.stdin.close() self.assertEquals(p.stdout.readlines(), ["hello world\n"]) self.assertEquals(p.stderr, None) self.assertEquals(p.wait(), 0) p = node.Popen(['sh', '-c', 'cat >&2'], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.STDOUT) self.assertEquals(p.communicate(_longstring), (_longstring, None)) # p = node.Popen(['tee', '/dev/stderr'], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.STDOUT) p.stdin.write("hello world\n") p.stdin.close() self.assertEquals(p.stdout.readlines(), ["hello world\n"] * 2) self.assertEquals(p.stderr, None) self.assertEquals(p.wait(), 0) p = node.Popen(['tee', '/dev/stderr'], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.STDOUT) self.assertEquals(p.communicate(_longstring[0:512]), (_longstring[0:512] * 2, None)) # p = node.Popen(['tee', '/dev/stderr'], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE) p.stdin.write("hello world\n") p.stdin.close() self.assertEquals(p.stdout.readlines(), ["hello world\n"]) self.assertEquals(p.stderr.readlines(), ["hello world\n"]) self.assertEquals(p.wait(), 0) p = node.Popen(['tee', '/dev/stderr'], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE) self.assertEquals(p.communicate(_longstring), (_longstring, ) * 2)
def test_Subprocess_basic(self): node = nemu.Node(nonetns=True) # User does not exist self.assertRaises(ValueError, node.Subprocess, ['/bin/sleep', '1000'], user=self.nouser) self.assertRaises(ValueError, node.Subprocess, ['/bin/sleep', '1000'], user=self.nouid) # Invalid CWD: it is a file self.assertRaises(OSError, node.Subprocess, '/bin/sleep', cwd='/bin/sleep') # Invalid CWD: does not exist self.assertRaises(OSError, node.Subprocess, '/bin/sleep', cwd=self.nofile) # Exec failure self.assertRaises(OSError, node.Subprocess, self.nofile) # Test that the environment is cleared: sleep should not be found self.assertRaises(OSError, node.Subprocess, 'sleep', env={'PATH': ''}) # Argv self.assertRaises(OSError, node.Subprocess, 'true; false') self.assertEquals(node.Subprocess('true').wait(), 0) self.assertEquals(node.Subprocess('true; false', shell=True).wait(), 1) # Piping r, w = os.pipe() p = node.Subprocess(['echo', 'hello world'], stdout=w) os.close(w) self.assertEquals(_readall(r), "hello world\n") os.close(r) p.wait() # cwd r, w = os.pipe() p = node.Subprocess('/bin/pwd', stdout=w, cwd="/") os.close(w) self.assertEquals(_readall(r), "/\n") os.close(r) p.wait() p = node.Subprocess(['sleep', '100']) self.assertTrue(p.pid > 0) self.assertEquals(p.poll(), None) # not finished p.signal() p.signal() # verify no-op (otherwise there will be an exception) self.assertEquals(p.wait(), -signal.SIGTERM) self.assertEquals(p.wait(), -signal.SIGTERM) # no-op self.assertEquals(p.poll(), -signal.SIGTERM) # no-op # destroy p = node.Subprocess(['sleep', '100']) pid = p.pid os.kill(pid, 0) # verify process still there p.destroy() self.assertRaises(OSError, os.kill, pid, 0) # should be dead by now # forceful destroy # Command: ignore SIGTERM, write \n to synchronise and then sleep while # closing stdout (so _readall finishes) cmd = 'trap "" TERM; echo; exec sleep 100 > /dev/null' r, w = os.pipe() p = node.Subprocess(cmd, shell=True, stdout=w) os.close(w) self.assertEquals(_readall(r), "\n") # wait for trap to be installed os.close(r) pid = p.pid os.kill(pid, 0) # verify process still there # Avoid the warning about the process being killed orig_stderr = sys.stderr sys.stderr = open("/dev/null", "w") p.destroy() sys.stderr = orig_stderr self.assertRaises(OSError, os.kill, pid, 0) # should be dead by now p = node.Subprocess(['sleep', '100']) os.kill(p.pid, signal.SIGTERM) time.sleep(0.2) p.signal() # since it has not been waited for, it should not raise self.assertEquals(p.wait(), -signal.SIGTERM)
#!/usr/bin/env python2 # vim:ts=4:sw=4:et:ai:sts=4 import os, nemu, subprocess, time # Uncomment for verbose operation. #nemu.environ.set_log_level(nemu.environ.LOG_DEBUG) xterm = nemu.environ.find_bin("xterm") X = "DISPLAY" in os.environ and xterm # each Node is a netns node0 = nemu.Node(forward_X11=X) node1 = nemu.Node(forward_X11=X) node2 = nemu.Node(forward_X11=X) print "Nodes started with pids: %s" % str((node0.pid, node1.pid, node2.pid)) # interface object maps to a veth pair with one end in a netns if0 = nemu.NodeInterface(node0) if1a = nemu.NodeInterface(node1) # Between node1 and node2, we use a P2P interface (if1b, if2) = nemu.P2PInterface.create_pair(node1, node2) switch0 = nemu.Switch( bandwidth=100 * 1024 * 1024, delay=0.1, # 100 ms delay_jitter=0.01, # 10ms delay_correlation=0.25, # 25% correlation loss=0.005) # connect the interfaces switch0.connect(if0)