From: Jakub Kicinski <kuba@kernel.org>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com,
andrew+netdev@lunn.ch, horms@kernel.org, daniel.zahka@gmail.com,
willemdebruijn.kernel@gmail.com, donald.hunter@gmail.com,
shuah@kernel.org, linux-kselftest@vger.kernel.org,
Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net-next 6/6] selftests: drv-net: psp: check the PSP disassociation notifications
Date: Sat, 12 Sep 2026 13:04:26 -0700 [thread overview]
Message-ID: <20260912200426.121025-7-kuba@kernel.org> (raw)
In-Reply-To: <20260912200426.121025-1-kuba@kernel.org>
The main namespace must see a change which no longer lists the device,
and the namespace which lost its last association must see the device
go away. Check that on both paths which generate the notifications,
dev-disassoc and netdevice removal, and check that a namespace which
still has another association is only told about the change.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
tools/testing/selftests/drivers/net/psp.py | 112 +++++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/tools/testing/selftests/drivers/net/psp.py b/tools/testing/selftests/drivers/net/psp.py
index d44d2c83473e..13ff5188cca3 100755
--- a/tools/testing/selftests/drivers/net/psp.py
+++ b/tools/testing/selftests/drivers/net/psp.py
@@ -723,6 +723,111 @@ from lib.py import ip
f" in {label} namespace")
+def _subscribe_mgmt(cfg):
+ """Listen on the mgmt group in the guest and in the main namespace."""
+ # Listener in the guest namespace; socket stays bound to that ns
+ with NetNSEnter(cfg.netns.name):
+ peer_pspnl = PSPFamily()
+ peer_pspnl.ntf_subscribe('mgmt')
+
+ main_pspnl = PSPFamily()
+ main_pspnl.ntf_subscribe('mgmt')
+
+ return main_pspnl, peer_pspnl
+
+
+def _get_dev_ntf(cfg, pspnl, label):
+ """Wait for the next notification about the PSP device under test."""
+ for ntf in pspnl.poll_ntf(duration=10):
+ if ntf['msg'].get('id') == cfg.psp_dev_id:
+ return ntf
+ raise KsftFailEx(f"No notification received in the {label} namespace")
+
+
+def _check_disassoc_ntf(cfg, main_pspnl, peer_pspnl, ifindex):
+ """Check the notifications for a netns losing its last association."""
+ ntf = _get_dev_ntf(cfg, main_pspnl, "main")
+ ksft_eq(ntf['name'], 'dev-change-ntf')
+ for assoc in ntf['msg'].get('assoc-list', []):
+ if assoc['nsid'] != cfg.psp_dev_peer_nsid:
+ continue
+ ksft_ne(assoc['ifindex'], ifindex,
+ "Disassociated device still listed in the notification")
+
+ # The device is gone as far as the disassociated namespace is concerned
+ ntf = _get_dev_ntf(cfg, peer_pspnl, "guest")
+ ksft_eq(ntf['name'], 'dev-del-ntf')
+ ksft_true('ifindex' not in ntf['msg'],
+ "ifindex reported to an associated namespace")
+
+
+def _dev_disassoc_notify_multi_ns_netkit(cfg):
+ """ Test the notifications dev-disassoc generates in both namespaces """
+ _init_psp_dev(cfg, True)
+ defer(delattr, cfg, 'psp_dev_id')
+ defer(delattr, cfg, 'psp_info')
+
+ cfg.pspnl.dev_assoc({'id': cfg.psp_dev_id,
+ 'ifindex': cfg.nk_guest_ifindex,
+ 'nsid': cfg.psp_dev_peer_nsid})
+ defer(_try_disassoc, cfg, cfg.psp_dev_id, cfg.nk_guest_ifindex,
+ cfg.psp_dev_peer_nsid)
+
+ main_pspnl, peer_pspnl = _subscribe_mgmt(cfg)
+
+ cfg.pspnl.dev_disassoc({'id': cfg.psp_dev_id,
+ 'ifindex': cfg.nk_guest_ifindex,
+ 'nsid': cfg.psp_dev_peer_nsid})
+
+ _check_disassoc_ntf(cfg, main_pspnl, peer_pspnl, cfg.nk_guest_ifindex)
+
+
+def _dev_disassoc_notify_one_of_two_netkit(cfg):
+ """Test the notifications with two netkits associated in one netns.
+
+ Disassociating the first netkit leaves the PSP device visible in the
+ guest namespace, generates a dev-change-ntf.
+ Disassociating the second one takes the device out of its view,
+ generates 'dev-del-ntf'.
+ """
+ _init_psp_dev(cfg, True)
+ defer(delattr, cfg, 'psp_dev_id')
+ defer(delattr, cfg, 'psp_info')
+
+ tmp_ifindex, _ = _add_netkit_guest(cfg, "tmp_nk_host", "tmp_nk_guest")
+
+ for ifindex in [cfg.nk_guest_ifindex, tmp_ifindex]:
+ cfg.pspnl.dev_assoc({'id': cfg.psp_dev_id, 'ifindex': ifindex,
+ 'nsid': cfg.psp_dev_peer_nsid})
+ defer(_try_disassoc, cfg, cfg.psp_dev_id, ifindex,
+ cfg.psp_dev_peer_nsid)
+
+ main_pspnl, peer_pspnl = _subscribe_mgmt(cfg)
+
+ # One of the two goes away, the device stays visible in the guest netns
+ cfg.pspnl.dev_disassoc({'id': cfg.psp_dev_id, 'ifindex': tmp_ifindex,
+ 'nsid': cfg.psp_dev_peer_nsid})
+
+ ntf = _get_dev_ntf(cfg, main_pspnl, "main")
+ ksft_eq(ntf['name'], 'dev-change-ntf')
+
+ ntf = _get_dev_ntf(cfg, peer_pspnl, "guest")
+ ksft_eq(ntf['name'], 'dev-change-ntf')
+ found = False
+ for assoc in ntf['msg'].get('assoc-list', []):
+ ksft_ne(assoc['ifindex'], tmp_ifindex,
+ "Disassociated device still listed in the notification")
+ found |= assoc['ifindex'] == cfg.nk_guest_ifindex
+ ksft_true(found, "Remaining association missing from the notification")
+
+ # And now the last one, the device disappears from the guest netns
+ cfg.pspnl.dev_disassoc({'id': cfg.psp_dev_id,
+ 'ifindex': cfg.nk_guest_ifindex,
+ 'nsid': cfg.psp_dev_peer_nsid})
+
+ _check_disassoc_ntf(cfg, main_pspnl, peer_pspnl, cfg.nk_guest_ifindex)
+
+
def _psp_dev_get_check_netkit_psp_assoc(cfg):
""" Check psp dev-get output with netkit interface associated with PSP dev """
_assoc_nk_guest(cfg)
@@ -863,6 +968,9 @@ from lib.py import ip
_check_assoc_list(cfg, cfg.psp_dev_id, tmp_guest_ifindex,
cfg.psp_dev_peer_nsid)
+ # Removing the netdevice is notified like a disassociation
+ main_pspnl, peer_pspnl = _subscribe_mgmt(cfg)
+
# Delete the temporary netkit pair (deleting one end removes both)
ip(f"link del {tmp_host_name}")
cleanup_netkit.cancel()
@@ -873,6 +981,8 @@ from lib.py import ip
or len(dev_info['assoc-list']) == 0,
"assoc-list should be empty after netkit deletion")
+ _check_disassoc_ntf(cfg, main_pspnl, peer_pspnl, tmp_guest_ifindex)
+
def _try_disassoc(cfg, psp_dev_id, ifindex, nsid=None):
"""Best-effort disassociate, ignoring errors if already removed."""
@@ -991,6 +1101,8 @@ from lib.py import ip
data_basic_send_netkit_psp_assoc,
_key_rotation_notify_multi_ns_netkit,
_dev_change_notify_multi_ns_netkit,
+ _dev_disassoc_notify_multi_ns_netkit,
+ _dev_disassoc_notify_one_of_two_netkit,
_psp_dev_get_check_netkit_psp_assoc,
_dev_assoc_no_nsid,
_psp_dev_assoc_cleanup_on_netkit_del,
--
2.55.0
prev parent reply other threads:[~2026-09-12 20:04 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-12 20:04 [PATCH net-next 0/6] psp: correct notifications and device info around device assoc Jakub Kicinski
2026-09-12 20:04 ` [PATCH net-next 1/6] selftests: drv-net: psp: fix linter issues Jakub Kicinski
2026-09-12 20:04 ` [PATCH net-next 2/6] psp: don't report the main netdevice's ifindex to associated namespaces Jakub Kicinski
2026-09-12 20:04 ` [PATCH net-next 3/6] selftests: drv-net: psp: check the ifindex an associated netns sees Jakub Kicinski
2026-09-12 20:04 ` [PATCH net-next 4/6] psp: notify about a disassociation once it has happened Jakub Kicinski
2026-09-12 20:04 ` [PATCH net-next 5/6] selftests: drv-net: psp: factor out creating a netkit in the test netns Jakub Kicinski
2026-09-12 20:04 ` Jakub Kicinski [this message]
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=20260912200426.121025-7-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=daniel.zahka@gmail.com \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shuah@kernel.org \
--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