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

Konstantin Khorenko khorenko at virtuozzo.com
Thu Sep 24 14:53:20 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>
>
> diff --git a/tools/testing/selftests/drivers/net/lib/py/__init__.py b/tools/testing/selftests/drivers/net/lib/py/__init__.py
> index fce5d9218f1d6..2d3fdaa815504 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 @@ KSFT_DIR = (Path(__file__).parent / "../../../..").resolve()
>          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 eb83e7b487978..e1cc74084a244 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 @@ from lib.py import bkg, cmd, wait_port_listen, rand_port
>  
>  
>  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__)
> +

This re-execs unconditionally, but ping.py lives in drivers/net/, and
per the README the tests there run against a real driver as well, with
NETIF set in the environment or in net.config. _load_env_file() starts
from os.environ, so NETIF survives the exec, but the device itself
stays in init_net, and "ip link show dev $NETIF" fails in the new
namespace. The commit message says "in netdevsim mode"; the code does
not check for it.

Please re-exec only when NETIF is not set. Either in main(), or better
inside rexec_in_netns() itself, since the helper went into the shared
library and every caller will need the same check.

>      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 afce547bcab09..13d7a7e6562e6 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 @@ global_defer_queue = []
>      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

drop double spaces

> +    mounted again in the new namespace, without it the netdevsim
> +    devices the test creates are not the ones it sees.  The test is

drop double spaces

> +    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 "$@"',

lo is down in the new namespace. ping.py does not depend on loopback
and rand_port() binds to "", so nothing breaks today, but the helper is
shared, and the next test that talks to 127.0.0.1 will trip over it. An
"ip link set lo up" in the wrapper closes that for one line.

-- 
Konstantin Khorenko <khorenko at virtuozzo.com>


More information about the Devel mailing list