File Index
Files and directories
Sign in
FILE

link_netns.py

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/link_netns.py PYTHON
  1#!/usr/bin/env python3
  2# SPDX-License-Identifier: GPL-2.0
  3
  4import time
  5
  6from lib.py import ksft_run, ksft_exit, ksft_true
  7from lib.py import ip
  8from lib.py import NetNS, NetNSEnter
  9from lib.py import RtnlFamily
 10
 11
 12LINK_NETNSID = 100
 13
 14
 15def test_event() -> None:
 16    with NetNS() as ns1, NetNS() as ns2:
 17        with NetNSEnter(str(ns2)):
 18            rtnl = RtnlFamily()
 19
 20        rtnl.ntf_subscribe("rtnlgrp-link")
 21
 22        ip(f"netns set {ns2} {LINK_NETNSID}", ns=str(ns1))
 23        ip(f"link add netns {ns1} link-netnsid {LINK_NETNSID} dummy1 type dummy")
 24        ip(f"link add netns {ns1} dummy2 type dummy", ns=str(ns2))
 25
 26        ip("link del dummy1", ns=str(ns1))
 27        ip("link del dummy2", ns=str(ns1))
 28
 29        time.sleep(1)
 30        rtnl.check_ntf()
 31        ksft_true(rtnl.async_msg_queue.empty(),
 32                  "Received unexpected link notification")
 33
 34
 35def validate_link_netns(netns, ifname, link_netnsid) -> bool:
 36    link_info = ip(f"-d link show dev {ifname}", ns=netns, json=True)
 37    if not link_info:
 38        return False
 39    return link_info[0].get("link_netnsid") == link_netnsid
 40
 41
 42def test_link_net() -> None:
 43    configs = [
 44        # type, common args, type args, fallback to dev_net
 45        ("ipvlan", "link dummy1", "", False),
 46        ("macsec", "link dummy1", "", False),
 47        ("macvlan", "link dummy1", "", False),
 48        ("macvtap", "link dummy1", "", False),
 49        ("vlan", "link dummy1", "id 100", False),
 50        ("gre", "", "local 192.0.2.1", True),
 51        ("vti", "", "local 192.0.2.1", True),
 52        ("ipip", "", "local 192.0.2.1", True),
 53        ("ip6gre", "", "local 2001:db8::1", True),
 54        ("ip6tnl", "", "local 2001:db8::1", True),
 55        ("vti6", "", "local 2001:db8::1", True),
 56        ("sit", "", "local 192.0.2.1", True),
 57        ("xfrm", "", "if_id 1", True),
 58    ]
 59
 60    with NetNS() as ns1, NetNS() as ns2, NetNS() as ns3:
 61        net1, net2, net3 = str(ns1), str(ns2), str(ns3)
 62
 63        # prepare link netnsid  and a dummy link needed by certain drivers
 64        ip(f"netns set {net3} {LINK_NETNSID}", ns=str(net2))
 65        ip("link add dummy1 type dummy", ns=net3)
 66
 67        cases = [
 68            # source, "netns", "link-netns", expected link-netns
 69            (net3, None, None, None, None),
 70            (net3, net2, None, None, LINK_NETNSID),
 71            (net2, None, net3, LINK_NETNSID, LINK_NETNSID),
 72            (net1, net2, net3, LINK_NETNSID, LINK_NETNSID),
 73        ]
 74
 75        for src_net, netns, link_netns, exp1, exp2 in cases:
 76            tgt_net = netns or src_net
 77            for typ, cargs, targs, fb_dev_net in configs:
 78                cmd = "link add"
 79                if netns:
 80                    cmd += f" netns {netns}"
 81                if link_netns:
 82                    cmd += f" link-netns {link_netns}"
 83                cmd += f" {cargs} foo type {typ} {targs}"
 84                ip(cmd, ns=src_net)
 85                if fb_dev_net:
 86                    ksft_true(validate_link_netns(tgt_net, "foo", exp1),
 87                              f"{typ} link_netns validation failed")
 88                else:
 89                    ksft_true(validate_link_netns(tgt_net, "foo", exp2),
 90                              f"{typ} link_netns validation failed")
 91                ip(f"link del foo", ns=tgt_net)
 92
 93
 94def test_peer_net() -> None:
 95    types = [
 96        "vxcan",
 97        "netkit",
 98        "veth",
 99    ]
100
101    with NetNS() as ns1, NetNS() as ns2, NetNS() as ns3, NetNS() as ns4:
102        net1, net2, net3, net4 = str(ns1), str(ns2), str(ns3), str(ns4)
103
104        ip(f"netns set {net3} {LINK_NETNSID}", ns=str(net2))
105
106        cases = [
107            # source, "netns", "link-netns", "peer netns", expected
108            (net1, None, None, None, None),
109            (net1, net2, None, None, None),
110            (net2, None, net3, None, LINK_NETNSID),
111            (net1, net2, net3, None, None),
112            (net2, None, None, net3, LINK_NETNSID),
113            (net1, net2, None, net3, LINK_NETNSID),
114            (net2, None, net2, net3, LINK_NETNSID),
115            (net1, net2, net4, net3, LINK_NETNSID),
116        ]
117
118        for src_net, netns, link_netns, peer_netns, exp in cases:
119            tgt_net = netns or src_net
120            for typ in types:
121                cmd = "link add"
122                if netns:
123                    cmd += f" netns {netns}"
124                if link_netns:
125                    cmd += f" link-netns {link_netns}"
126                cmd += f" foo type {typ}"
127                if peer_netns:
128                    cmd += f" peer netns {peer_netns}"
129                ip(cmd, ns=src_net)
130                ksft_true(validate_link_netns(tgt_net, "foo", exp),
131                          f"{typ} peer_netns validation failed")
132                ip(f"link del foo", ns=tgt_net)
133
134
135def main() -> None:
136    ksft_run([test_event, test_link_net, test_peer_net])
137    ksft_exit()
138
139
140if __name__ == "__main__":
141    main()
~/ Read-only file preview.