3 """Test TAP device support."""
7 from testlib import check, util, cmd
8 from testlib.log import log
9 from testlib.proc import Script, Tinc
10 from testlib.test import Test
11 from testlib.external import netns_add, netns_exec, ping
14 util.require_command("ip", "netns", "list")
15 util.require_path("/dev/net/tun")
28 def make_up(node: str, address: str) -> str:
29 """Create a network configuration script."""
31 import subprocess as subp
32 subp.run(['ip', 'link', 'set', 'dev', '{node}', 'netns', '{node}'], check=True)
33 subp.run(['ip', 'netns', 'exec', '{node}', 'ip', 'addr', 'add', 'dev', '{node}', '{address}/24'], check=True)
34 subp.run(['ip', 'netns', 'exec', '{node}', 'ip', 'link', 'set', '{node}', 'up'], check=True)
38 def init(ctx: Test, mode: str) -> T.Tuple[Tinc, Tinc]:
39 """Configure nodes."""
46 foo = ctx.node(init=stdin)
47 foo.cmd("set", "Interface", foo.name)
55 bar = ctx.node(init=stdin)
56 bar.cmd("set", "Interface", bar.name)
62 def run_tests(ctx: Test, mode: str) -> None:
63 """Test BindToAddress or ListenAddress."""
65 foo, bar = init(ctx, mode)
67 log.info("add tinc-up scripts")
68 foo.add_script(Script.TINC_UP, make_up(foo.name, IP_FOO))
69 bar.add_script(Script.TINC_UP, make_up(bar.name, IP_BAR))
71 log.info("start nodes and wait for them to connect")
75 assert ping(IP_FOO, bar.name)
77 log.info("create a dummy device for sending ARP requests")
78 netns_exec(bar.name, "ip", "link", "add", "dummy0", "type", "dummy", check=True)
79 netns_exec(bar.name, "ip", "addr", "add", IP_DUMMY, "dev", "dummy0", check=True)
80 netns_exec(bar.name, "ip", "link", "set", "dummy0", "up", check=True)
82 log.info("test ARP with Mode %s", mode)
83 proc = netns_exec(foo.name, "arping", "-c1", IP_DUMMY)
84 check.equals(ARP_WORKS[dev_mode], proc.returncode == 0)
87 for dev_mode in "switch", "hub", "router":
88 with Test(f"test TAP device ({dev_mode})") as context:
89 run_tests(context, dev_mode)