[Devel] [PATCH vz10 2/3] selftests: drv-net: run ping in its own netns

Eva Kurchatova eva.kurchatova at virtuozzo.com
Tue Sep 1 02:43:48 MSK 2026


In netdevsim mode NetDrvEpEnv gives the remote end a namespace of its
own and leaves the local end in the one the test was started in, so
the filtering of the host applies to the traffic the test sends to
itself. A host that drops it fails the test:

  # nft add rule inet t input ip saddr 192.0.2.0/24 tcp flags syn drop
  # ./ping.py
  ok 1 ping.test_v4
  ok 2 ping.test_v6
  not ok 3 ping.test_tcp
  # Stopping tests due to KsftTerminate.

ICMP is let through where TCP is not, which is why the first two pass
and the test then sits there until it is killed.

Re-execute the test in a namespace of its own, the way nft_audit.sh and
nft_concat_range.sh already do, and mount sysfs again there so that the
netdevsim devices the test creates are the ones it sees.

https://virtuozzo.atlassian.net/browse/VSTOR-139651
Feature: fix selftests
Signed-off-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>
---
 .../selftests/drivers/net/lib/py/__init__.py  |  2 +-
 tools/testing/selftests/drivers/net/ping.py   |  5 ++++
 tools/testing/selftests/net/lib/py/utils.py   | 24 +++++++++++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/drivers/net/lib/py/__init__.py b/tools/testing/selftests/drivers/net/lib/py/__init__.py
index fce5d9218f1d..2d3fdaa81550 100644
--- a/tools/testing/selftests/drivers/net/lib/py/__init__.py
+++ b/tools/testing/selftests/drivers/net/lib/py/__init__.py
@@ -15,7 +15,7 @@ try:
         NlError, RtnlFamily, DevlinkFamily
     from net.lib.py import CmdExitFailure
     from net.lib.py import bkg, cmd, defer, ethtool, fd_read_timeout, ip, \
-        rand_port, tool, wait_port_listen
+        rand_port, rexec_in_netns, tool, wait_port_listen
     from net.lib.py import fd_read_timeout
     from net.lib.py import KsftSkipEx, KsftFailEx, KsftXfailEx
     from net.lib.py import ksft_disruptive, ksft_exit, ksft_pr, ksft_run, \
diff --git a/tools/testing/selftests/drivers/net/ping.py b/tools/testing/selftests/drivers/net/ping.py
index dfcf6ddd4c01..4799c94369d4 100755
--- a/tools/testing/selftests/drivers/net/ping.py
+++ b/tools/testing/selftests/drivers/net/ping.py
@@ -5,6 +5,7 @@ from lib.py import ksft_run, ksft_exit
 from lib.py import ksft_eq
 from lib.py import NetDrvEpEnv
 from lib.py import bkg, cmd, wait_port_listen, rand_port
+from lib.py import rexec_in_netns
 
 
 def test_v4(cfg) -> None:
@@ -42,6 +43,10 @@ def test_tcp(cfg) -> None:
 
 
 def main() -> None:
+    # In netdevsim mode the local end of the test stays in the namespace
+    # the test was started in, so the rules of the host apply to it.
+    rexec_in_netns(__file__)
+
     with NetDrvEpEnv(__file__) as cfg:
         ksft_run(globs=globals(), case_pfx={"test_"}, args=(cfg, ))
     ksft_exit()
diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
index afce547bcab0..13d7a7e6562e 100644
--- a/tools/testing/selftests/net/lib/py/utils.py
+++ b/tools/testing/selftests/net/lib/py/utils.py
@@ -8,6 +8,7 @@ import re
 import select
 import socket
 import subprocess
+import sys
 import time
 
 
@@ -131,6 +132,29 @@ def ethtool(args, json=None, ns=None, host=None):
     return tool('ethtool', args, json=json, ns=ns, host=host)
 
 
+def rexec_in_netns(path):
+    """
+    Re-exec the test in a network namespace of its own.
+
+    A test that puts one end of its traffic in the namespace it was
+    started in otherwise depends on what the host filters.  sysfs is
+    mounted again in the new namespace, without it the netdevsim
+    devices the test creates are not the ones it sees.  The test is
+    left where it is if unshare is not there to move it.
+    """
+    if os.environ.get("KSFT_IN_NETNS"):
+        return
+
+    os.environ["KSFT_IN_NETNS"] = "1"
+    try:
+        os.execvp("unshare",
+                  ["unshare", "-n", "-m",
+                   "sh", "-c", 'mount -t sysfs sysfs /sys && exec "$@"',
+                   "sh", sys.executable, os.path.abspath(path)] + sys.argv[1:])
+    except OSError:
+        del os.environ["KSFT_IN_NETNS"]
+
+
 def rand_port(type=socket.SOCK_STREAM):
     """
     Get a random unprivileged port.
-- 
2.55.0



More information about the Devel mailing list