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: 12+ 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
2026-06-06 2:16 ` [PATCH v15 net-next 00/11] psp: Add support for dev-assoc/disassoc Jakub Kicinski
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.