mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-04-13 09:59:31 +00:00
selftests: net: Add test cases for link and peer netns
- Add test for creating link in another netns when a link of the same name and ifindex exists in current netns. - Add test to verify that link is created in target netns directly - no link new/del events should be generated in link netns or current netns. - Add test cases to verify that link-netns is set as expected for various drivers and combination of namespace-related parameters. Signed-off-by: Xiao Liang <shaw.leon@gmail.com> Link: https://patch.msgid.link/20250219125039.18024-14-shaw.leon@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
0303294162
commit
85cb3711ac
4 changed files with 157 additions and 0 deletions
|
@ -36,6 +36,7 @@ TEST_PROGS += cmsg_so_priority.sh
|
|||
TEST_PROGS += test_so_rcv.sh
|
||||
TEST_PROGS += cmsg_time.sh cmsg_ipv6.sh
|
||||
TEST_PROGS += netns-name.sh
|
||||
TEST_PROGS += link_netns.py
|
||||
TEST_PROGS += nl_netdev.py
|
||||
TEST_PROGS += rtnetlink.py
|
||||
TEST_PROGS += srv6_end_dt46_l3vpn_test.sh
|
||||
|
|
|
@ -107,3 +107,8 @@ CONFIG_XFRM_INTERFACE=m
|
|||
CONFIG_XFRM_USER=m
|
||||
CONFIG_IP_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IPVLAN=m
|
||||
CONFIG_CAN=m
|
||||
CONFIG_CAN_DEV=m
|
||||
CONFIG_CAN_VXCAN=m
|
||||
CONFIG_NETKIT=y
|
||||
|
|
141
tools/testing/selftests/net/link_netns.py
Executable file
141
tools/testing/selftests/net/link_netns.py
Executable file
|
@ -0,0 +1,141 @@
|
|||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
import time
|
||||
|
||||
from lib.py import ksft_run, ksft_exit, ksft_true
|
||||
from lib.py import ip
|
||||
from lib.py import NetNS, NetNSEnter
|
||||
from lib.py import RtnlFamily
|
||||
|
||||
|
||||
LINK_NETNSID = 100
|
||||
|
||||
|
||||
def test_event() -> None:
|
||||
with NetNS() as ns1, NetNS() as ns2:
|
||||
with NetNSEnter(str(ns2)):
|
||||
rtnl = RtnlFamily()
|
||||
|
||||
rtnl.ntf_subscribe("rtnlgrp-link")
|
||||
|
||||
ip(f"netns set {ns2} {LINK_NETNSID}", ns=str(ns1))
|
||||
ip(f"link add netns {ns1} link-netnsid {LINK_NETNSID} dummy1 type dummy")
|
||||
ip(f"link add netns {ns1} dummy2 type dummy", ns=str(ns2))
|
||||
|
||||
ip("link del dummy1", ns=str(ns1))
|
||||
ip("link del dummy2", ns=str(ns1))
|
||||
|
||||
time.sleep(1)
|
||||
rtnl.check_ntf()
|
||||
ksft_true(rtnl.async_msg_queue.empty(),
|
||||
"Received unexpected link notification")
|
||||
|
||||
|
||||
def validate_link_netns(netns, ifname, link_netnsid) -> bool:
|
||||
link_info = ip(f"-d link show dev {ifname}", ns=netns, json=True)
|
||||
if not link_info:
|
||||
return False
|
||||
return link_info[0].get("link_netnsid") == link_netnsid
|
||||
|
||||
|
||||
def test_link_net() -> None:
|
||||
configs = [
|
||||
# type, common args, type args, fallback to dev_net
|
||||
("ipvlan", "link dummy1", "", False),
|
||||
("macsec", "link dummy1", "", False),
|
||||
("macvlan", "link dummy1", "", False),
|
||||
("macvtap", "link dummy1", "", False),
|
||||
("vlan", "link dummy1", "id 100", False),
|
||||
("gre", "", "local 192.0.2.1", True),
|
||||
("vti", "", "local 192.0.2.1", True),
|
||||
("ipip", "", "local 192.0.2.1", True),
|
||||
("ip6gre", "", "local 2001:db8::1", True),
|
||||
("ip6tnl", "", "local 2001:db8::1", True),
|
||||
("vti6", "", "local 2001:db8::1", True),
|
||||
("sit", "", "local 192.0.2.1", True),
|
||||
("xfrm", "", "if_id 1", True),
|
||||
]
|
||||
|
||||
with NetNS() as ns1, NetNS() as ns2, NetNS() as ns3:
|
||||
net1, net2, net3 = str(ns1), str(ns2), str(ns3)
|
||||
|
||||
# prepare link netnsid and a dummy link needed by certain drivers
|
||||
ip(f"netns set {net3} {LINK_NETNSID}", ns=str(net2))
|
||||
ip("link add dummy1 type dummy", ns=net3)
|
||||
|
||||
cases = [
|
||||
# source, "netns", "link-netns", expected link-netns
|
||||
(net3, None, None, None, None),
|
||||
(net3, net2, None, None, LINK_NETNSID),
|
||||
(net2, None, net3, LINK_NETNSID, LINK_NETNSID),
|
||||
(net1, net2, net3, LINK_NETNSID, LINK_NETNSID),
|
||||
]
|
||||
|
||||
for src_net, netns, link_netns, exp1, exp2 in cases:
|
||||
tgt_net = netns or src_net
|
||||
for typ, cargs, targs, fb_dev_net in configs:
|
||||
cmd = "link add"
|
||||
if netns:
|
||||
cmd += f" netns {netns}"
|
||||
if link_netns:
|
||||
cmd += f" link-netns {link_netns}"
|
||||
cmd += f" {cargs} foo type {typ} {targs}"
|
||||
ip(cmd, ns=src_net)
|
||||
if fb_dev_net:
|
||||
ksft_true(validate_link_netns(tgt_net, "foo", exp1),
|
||||
f"{typ} link_netns validation failed")
|
||||
else:
|
||||
ksft_true(validate_link_netns(tgt_net, "foo", exp2),
|
||||
f"{typ} link_netns validation failed")
|
||||
ip(f"link del foo", ns=tgt_net)
|
||||
|
||||
|
||||
def test_peer_net() -> None:
|
||||
types = [
|
||||
"vxcan",
|
||||
"netkit",
|
||||
"veth",
|
||||
]
|
||||
|
||||
with NetNS() as ns1, NetNS() as ns2, NetNS() as ns3, NetNS() as ns4:
|
||||
net1, net2, net3, net4 = str(ns1), str(ns2), str(ns3), str(ns4)
|
||||
|
||||
ip(f"netns set {net3} {LINK_NETNSID}", ns=str(net2))
|
||||
|
||||
cases = [
|
||||
# source, "netns", "link-netns", "peer netns", expected
|
||||
(net1, None, None, None, None),
|
||||
(net1, net2, None, None, None),
|
||||
(net2, None, net3, None, LINK_NETNSID),
|
||||
(net1, net2, net3, None, None),
|
||||
(net2, None, None, net3, LINK_NETNSID),
|
||||
(net1, net2, None, net3, LINK_NETNSID),
|
||||
(net2, None, net2, net3, LINK_NETNSID),
|
||||
(net1, net2, net4, net3, LINK_NETNSID),
|
||||
]
|
||||
|
||||
for src_net, netns, link_netns, peer_netns, exp in cases:
|
||||
tgt_net = netns or src_net
|
||||
for typ in types:
|
||||
cmd = "link add"
|
||||
if netns:
|
||||
cmd += f" netns {netns}"
|
||||
if link_netns:
|
||||
cmd += f" link-netns {link_netns}"
|
||||
cmd += f" foo type {typ}"
|
||||
if peer_netns:
|
||||
cmd += f" peer netns {peer_netns}"
|
||||
ip(cmd, ns=src_net)
|
||||
ksft_true(validate_link_netns(tgt_net, "foo", exp),
|
||||
f"{typ} peer_netns validation failed")
|
||||
ip(f"link del foo", ns=tgt_net)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
ksft_run([test_event, test_link_net, test_peer_net])
|
||||
ksft_exit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -78,6 +78,16 @@ ip -netns $NS link show dev $ALT_NAME 2> /dev/null &&
|
|||
fail "Can still find alt-name after move"
|
||||
ip -netns $test_ns link del $DEV || fail
|
||||
|
||||
#
|
||||
# Test no conflict of the same name/ifindex in different netns
|
||||
#
|
||||
ip -netns $NS link add name $DEV index 100 type dummy || fail
|
||||
ip -netns $NS link add netns $test_ns name $DEV index 100 type dummy ||
|
||||
fail "Can create in netns without moving"
|
||||
ip -netns $test_ns link show dev $DEV >> /dev/null || fail "Device not found"
|
||||
ip -netns $NS link del $DEV || fail
|
||||
ip -netns $test_ns link del $DEV || fail
|
||||
|
||||
echo -ne "$(basename $0) \t\t\t\t"
|
||||
if [ $RET_CODE -eq 0 ]; then
|
||||
echo "[ OK ]"
|
||||
|
|
Loading…
Add table
Reference in a new issue