3 """Create two network namespaces and run ping between them."""
5 import subprocess as subp
8 from testlib import external as ext, util, template, cmd
9 from testlib.log import log
10 from testlib.proc import Tinc, Script
11 from testlib.test import Test
14 util.require_command("ip", "netns", "list")
15 util.require_path("/dev/net/tun")
17 IP_FOO = "192.168.1.1"
18 IP_BAR = "192.168.1.2"
22 def init(ctx: Test) -> T.Tuple[Tinc, Tinc]:
23 """Initialize new test nodes."""
24 foo, bar = ctx.node(), ctx.node()
26 log.info("create network namespaces")
27 assert ext.netns_add(foo.name)
28 assert ext.netns_add(bar.name)
30 log.info("initialize two nodes")
41 foo.add_script(Script.TINC_UP, template.make_netns_config(foo.name, IP_FOO, MASK))
53 bar.add_script(Script.TINC_UP, template.make_netns_config(bar.name, IP_BAR, MASK))
55 cmd.exchange(foo, bar)
60 def ping(namespace: str, ip_addr: str) -> int:
61 """Send pings between two network namespaces."""
62 log.info("pinging node from netns %s at %s", namespace, ip_addr)
64 ["ip", "netns", "exec", namespace, "ping", "-W1", "-c1", ip_addr], check=False
67 log.info("ping finished with code %d", proc.returncode)
68 return proc.returncode
71 with Test("ns-ping") as context:
72 foo_node, bar_node = init(context)
75 log.info("waiting for nodes to come up")
76 bar_node[Script.TINC_UP].wait()
78 log.info("ping must not work when there is no connection")
79 assert ping(foo_node.name, IP_BAR)
81 log.info("add script foo/host-up")
82 bar_node.add_script(foo_node.script_up)
84 log.info("add ConnectTo clause")
85 bar_node.cmd("add", "ConnectTo", foo_node.name)
87 log.info("bar waits for foo")
88 bar_node[foo_node.script_up].wait()
90 log.info("ping must work after connection is up")
91 assert not ping(foo_node.name, IP_BAR)