From: Wei Wang <weibunny.kernel@gmail.com>
To: netdev@vger.kernel.org, Jakub Kicinski <kuba@kernel.org>,
Daniel Zahka <daniel.zahka@gmail.com>,
Willem de Bruijn <willemdebruijn.kernel@gmail.com>,
David Wei <dw@davidwei.uk>, Andrew Lunn <andrew+netdev@lunn.ch>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>
Cc: Wei Wang <weibunny@fb.com>
Subject: [PATCH v15 net-next 07/10] selftests/net: psp: support PSP in NetDrvContEnv infrastructure
Date: Wed, 3 Jun 2026 16:59:36 -0700 [thread overview]
Message-ID: <20260603235947.2986110-8-weibunny.kernel@gmail.com> (raw)
In-Reply-To: <20260603235947.2986110-1-weibunny.kernel@gmail.com>
From: Wei Wang <weibunny@fb.com>
Add infrastructure to support PSP tests across network namespaces
using NetDrvContEnv with netkit pairs. This enables testing PSP device
association, where a non-PSP-capable device (e.g. netkit) in a guest
namespace is associated with a real PSP device in the host namespace,
allowing the guest to perform PSP encryption/decryption through the
host's PSP hardware.
The topology is:
Host NS: psp_dev_local <---> nk_host
| |
| | (netkit pair)
| |
Remote NS: psp_dev_peer Guest NS: nk_guest
(responder) (PSP tests)
env.py:
- nk_guest_ifindex is queried after moving the device into the guest
namespace, so tests can use it directly for dev-assoc
psp.py:
- PSP device lookup supports container environments where the PSP
device is on the physical interface, not the test interface
- Association helpers handle dev-assoc/dev-disassoc with defer-based
cleanup to prevent state leaks on test assertion failures
- main() tries NetDrvContEnv with primary_rx_redirect and falls back
to NetDrvEpEnv, so existing tests continue to work without the
container environment
Signed-off-by: Wei Wang <weibunny@fb.com>
---
tools/testing/selftests/drivers/net/config | 1 +
.../selftests/drivers/net/lib/py/env.py | 7 +-
tools/testing/selftests/drivers/net/psp.py | 102 +++++++++++++++++-
3 files changed, 104 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/config b/tools/testing/selftests/drivers/net/config
index 617de8aaf551..91d4fd410914 100644
--- a/tools/testing/selftests/drivers/net/config
+++ b/tools/testing/selftests/drivers/net/config
@@ -8,6 +8,7 @@ CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_NETCONSOLE_EXTENDED_LOG=y
CONFIG_NETDEVSIM=m
+CONFIG_NETKIT=y
CONFIG_NET_SCH_ETF=m
CONFIG_NET_SCH_FQ=m
CONFIG_PPP=y
diff --git a/tools/testing/selftests/drivers/net/lib/py/env.py b/tools/testing/selftests/drivers/net/lib/py/env.py
index 1d8964538abb..89a39c8b2cb1 100644
--- a/tools/testing/selftests/drivers/net/lib/py/env.py
+++ b/tools/testing/selftests/drivers/net/lib/py/env.py
@@ -337,7 +337,8 @@ class NetDrvContEnv(NetDrvEpEnv):
+---------------+
"""
- def __init__(self, src_path, rxqueues=1, primary_rx_redirect=False, **kwargs):
+ def __init__(self, src_path, rxqueues=1,
+ primary_rx_redirect=False, **kwargs):
self.netns = None
self.nk_host_ifname = None
self.nk_guest_ifname = None
@@ -351,7 +352,6 @@ class NetDrvContEnv(NetDrvEpEnv):
self._remote_route_added = False
self._old_fwd = None
self._old_accept_ra = None
-
super().__init__(src_path, **kwargs)
self.require_ipver("6")
@@ -468,6 +468,9 @@ class NetDrvContEnv(NetDrvEpEnv):
self._init_ns_attached = True
ip("netns set init 0", ns=self.netns)
ip(f"link set dev {self.nk_guest_ifname} netns {self.netns.name}")
+ nk_guest_dev = ip(f"link show dev {self.nk_guest_ifname}",
+ json=True, ns=self.netns)[0]
+ self.nk_guest_ifindex = nk_guest_dev['ifindex']
ip(f"link set dev {self.nk_host_ifname} up")
ip(f"-6 addr add fe80::1/64 dev {self.nk_host_ifname} nodad")
ip(f"-6 route add {self.nk_guest_ipv6}/128 via fe80::2 dev {self.nk_host_ifname}")
diff --git a/tools/testing/selftests/drivers/net/psp.py b/tools/testing/selftests/drivers/net/psp.py
index 6d5114be4c88..015af92c8d7b 100755
--- a/tools/testing/selftests/drivers/net/psp.py
+++ b/tools/testing/selftests/drivers/net/psp.py
@@ -5,6 +5,7 @@
import errno
import fcntl
+import os
import socket
import struct
import termios
@@ -16,8 +17,10 @@ from lib.py import ksft_true, ksft_eq, ksft_ne, ksft_gt, ksft_raises
from lib.py import ksft_not_none
from lib.py import ksft_variants, KsftNamedVariant
from lib.py import KsftSkipEx
-from lib.py import NetDrvEpEnv, PSPFamily, NlError
+from lib.py import NetDrvEpEnv, NetDrvContEnv
+from lib.py import NlError, PSPFamily
from lib.py import bkg, rand_port, wait_port_listen
+from lib.py import ip
def _get_outq(s):
@@ -118,11 +121,13 @@ def _get_stat(cfg, key):
# Test case boiler plate
#
-def _init_psp_dev(cfg):
+def _init_psp_dev(cfg, use_psp_ifindex=False):
if not hasattr(cfg, 'psp_dev_id'):
# Figure out which local device we are testing against
+ # For NetDrvContEnv: use psp_ifindex instead of ifindex
+ target_ifindex = cfg.psp_ifindex if use_psp_ifindex else cfg.ifindex
for dev in cfg.pspnl.dev_get({}, dump=True):
- if dev['ifindex'] == cfg.ifindex:
+ if dev['ifindex'] == target_ifindex:
cfg.psp_info = dev
cfg.psp_dev_id = cfg.psp_info['id']
break
@@ -597,13 +602,102 @@ def data_mss_adjust(cfg, ipver):
_data_mss_adjust(cfg, ipver)
+def _try_disassoc(cfg, psp_dev_id, ifindex, nsid=None):
+ """Best-effort disassociate, ignoring errors if already removed."""
+ try:
+ params = {'id': psp_dev_id, 'ifindex': ifindex}
+ if nsid is not None:
+ params['nsid'] = nsid
+ cfg.pspnl.dev_disassoc(params)
+ except NlError:
+ pass
+
+
+def _assoc_nk_guest(cfg):
+ """Associate nk_guest with PSP device and register cleanup via defer()."""
+ _init_psp_dev(cfg, True)
+
+ cfg.pspnl.dev_assoc({'id': cfg.psp_dev_id,
+ 'ifindex': cfg.nk_guest_ifindex,
+ 'nsid': cfg.psp_dev_peer_nsid})
+ defer(_disassoc_nk_guest, cfg,
+ cfg.psp_dev_id, cfg.nk_guest_ifindex)
+
+
+def _disassoc_nk_guest(cfg, psp_dev_id, nk_guest_ifindex):
+ """Disassociate nk_guest and reset cfg PSP state."""
+ pspnl = PSPFamily()
+ pspnl.dev_disassoc({'id': psp_dev_id, 'ifindex': nk_guest_ifindex,
+ 'nsid': cfg.psp_dev_peer_nsid})
+ cfg.pspnl = pspnl
+ del cfg.psp_dev_id
+ del cfg.psp_info
+
+
+def _get_nsid(ns_name):
+ """Get the nsid for a namespace."""
+ for entry in ip("netns list-id", json=True):
+ if entry.get("name") == str(ns_name):
+ return entry["nsid"]
+ raise KsftSkipEx(f"nsid not found for namespace {ns_name}")
+
+
+def _setup_psp_attributes(cfg):
+ # pylint: disable=protected-access
+ """
+ Set up PSP-specific attributes on the environment.
+
+ This sets attributes needed for PSP tests based on whether we're using
+ netdevsim or a real NIC.
+ """
+ if cfg._ns is not None:
+ # netdevsim case: PSP device is the local dev (in host namespace)
+ cfg.psp_dev = cfg._ns.nsims[0].dev
+ cfg.psp_ifname = cfg.psp_dev['ifname']
+ cfg.psp_ifindex = cfg.psp_dev['ifindex']
+
+ # PSP peer device is the remote dev (in _netns, where psp_responder runs)
+ cfg.psp_dev_peer = cfg._ns_peer.nsims[0].dev
+ cfg.psp_dev_peer_ifname = cfg.psp_dev_peer['ifname']
+ cfg.psp_dev_peer_ifindex = cfg.psp_dev_peer['ifindex']
+ else:
+ # Real NIC case: PSP device is the local interface
+ cfg.psp_dev = cfg.dev
+ cfg.psp_ifname = cfg.ifname
+ cfg.psp_ifindex = cfg.ifindex
+
+ # PSP peer device is the remote interface
+ cfg.psp_dev_peer = cfg.remote_dev
+ cfg.psp_dev_peer_ifname = cfg.remote_ifname
+ cfg.psp_dev_peer_ifindex = cfg.remote_ifindex
+
+ # Get nsid for the guest namespace (netns) where nk_guest is
+ cfg.psp_dev_peer_nsid = _get_nsid(cfg.netns.name)
+
+
+
def main() -> None:
""" Ksft boiler plate main """
- with NetDrvEpEnv(__file__) as cfg:
+ # Make sure LOCAL_PREFIX_V6 is set
+ if "LOCAL_PREFIX_V6" not in os.environ:
+ os.environ["LOCAL_PREFIX_V6"] = "2001:db8:2::"
+
+ try:
+ env = NetDrvContEnv(__file__, primary_rx_redirect=True)
+ has_cont = True
+ except KsftSkipEx:
+ env = NetDrvEpEnv(__file__)
+ has_cont = False
+
+ with env as cfg:
cfg.pspnl = PSPFamily()
+ if has_cont:
+ _setup_psp_attributes(cfg)
+
# Set up responder and communication sock
+ # psp_responder runs in _netns (remote namespace with psp_dev_peer)
responder = cfg.remote.deploy("psp_responder")
cfg.comm_port = rand_port()
--
2.52.0
next prev parent reply other threads:[~2026-06-03 23:59 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-03 23:59 [PATCH v15 net-next 00/11] psp: Add support for dev-assoc/disassoc Wei Wang
2026-06-03 23:59 ` [PATCH v15 net-next 01/10] psp: add admin/non-admin version of psp_device_get_locked Wei Wang
2026-06-03 23:59 ` [PATCH v15 net-next 02/10] psp: add new netlink cmd for dev-assoc and dev-disassoc Wei Wang
2026-06-03 23:59 ` [PATCH v15 net-next 03/10] psp: add a new netdev event for dev unregister Wei Wang
2026-06-03 23:59 ` [PATCH v15 net-next 04/10] selftests/net: psp: refactor test builders to use ksft_variants Wei Wang
2026-06-03 23:59 ` [PATCH v15 net-next 05/10] selftests/net: add _find_bpf_obj() to search hw/ for BPF objects Wei Wang
2026-06-03 23:59 ` [PATCH v15 net-next 06/10] selftests/net: rename _nk_host_ifname to nk_host_ifname Wei Wang
2026-06-03 23:59 ` Wei Wang [this message]
2026-06-03 23:59 ` [PATCH v15 net-next 08/10] selftests/net: psp: add dev-assoc data path test Wei Wang
2026-06-03 23:59 ` [PATCH v15 net-next 09/10] selftests/net: psp: add cross-namespace notification tests Wei Wang
2026-06-03 23:59 ` [PATCH v15 net-next 10/10] selftests/net: psp: add dev-get, no-nsid, and cleanup tests Wei Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260603235947.2986110-8-weibunny.kernel@gmail.com \
--to=weibunny.kernel@gmail.com \
--cc=andrew+netdev@lunn.ch \
--cc=daniel.zahka@gmail.com \
--cc=davem@davemloft.net \
--cc=dw@davidwei.uk \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=weibunny@fb.com \
--cc=willemdebruijn.kernel@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox