* [PATCH net v2 0/2] net: psp: preserve SKB_EXT_PSP across packet scrubbing
@ 2026-10-30 4:31 Wei Wang
2026-10-30 4:31 ` [PATCH net v2 1/2] net: Make PSP skb extension survive " Wei Wang
2026-10-30 4:31 ` [PATCH net v2 2/2] selftests/net: psp: test bidirectional data transfer Wei Wang
0 siblings, 2 replies; 3+ messages in thread
From: Wei Wang @ 2026-10-30 4:31 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
Shuah Khan
Cc: Simon Horman, Jakub Sitnicki, Daniel Zahka, Willem de Bruijn,
netdev, linux-kselftest, linux-kernel, bpf, Wei Wang
When a virtual interface such as netkit is associated with a PSP device
in another network namespace via PSP_CMD_DEV_ASSOC, incoming PSP packets
decapsulated on the physical device lose their SKB_EXT_PSP extension
when scrubbed during redirection (e.g. skb_do_redirect() or
netkit_xmit() calling skb_scrub_packet()). As a result,
__psp_sk_rx_policy_check() rejects incoming PSP-encrypted TCP data
segments at the socket layer.
This gap slipped through the existing psp.py selftests because both
_data_basic_send() and _data_basic_send_netkit_psp_assoc() only sent a
unidirectional data stream from the test socket to psp_responder; the
returning pure TCP ACKs had SKB_EXT_PSP stripped by skb_scrub_packet(),
but were still accepted by __psp_sk_rx_policy_check() while peer_tx was
unset.
Patch 1 (originally from Jakub Sitnicki's BPF skb extension series [1])
introduces skb_ext_scrub() to selectively preserve SKB_EXT_PSP during
skb_scrub_packet().
Patch 2 updates the psp.py selftests to exercise bidirectional PSP data
transfer using psp_responder's "data echo" command in both direct and
netkit dev-assoc test cases.
Changes in v2:
- Patch 1: Replace the skb_ext_del() loop in skb_ext_scrub() with
skb_ext_reset() + skb_ext_add() (and a fast path when SKB_EXT_PSP is
the only extension in the skb_ext buffer) so shared skb_ext buffers
with refcounted extensions (SKB_EXT_SEC_PATH / SKB_EXT_MCTP) are not
left half-deleted; clear skb->decrypted if skb_ext_add() fails.
- Patch 1: Make skb_ext_scrub() static in net/core/skbuff.c and drop
EXPORT_SYMBOL() / public header prototype.
Link: https://lore.kernel.org/netdev/20260910-bpf-meta-inside-skb-ext-v2-3-0b21e42180b0@cloudflare.com/ [1]
Wei Wang (2):
net: Make PSP skb extension survive packet scrubbing
selftests/net: psp: test bidirectional data transfer
net/core/skbuff.c | 31 ++++++++++++++++++++--
tools/testing/selftests/drivers/net/psp.py | 8 ++++++
2 files changed, 37 insertions(+), 2 deletions(-)
--
2.56.0.317.g454f8302e1-goog
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH net v2 1/2] net: Make PSP skb extension survive packet scrubbing
2026-10-30 4:31 [PATCH net v2 0/2] net: psp: preserve SKB_EXT_PSP across packet scrubbing Wei Wang
@ 2026-10-30 4:31 ` Wei Wang
2026-10-30 4:31 ` [PATCH net v2 2/2] selftests/net: psp: test bidirectional data transfer Wei Wang
1 sibling, 0 replies; 3+ messages in thread
From: Wei Wang @ 2026-10-30 4:31 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
Shuah Khan
Cc: Simon Horman, Jakub Sitnicki, Daniel Zahka, Willem de Bruijn,
netdev, linux-kselftest, linux-kernel, bpf, Wei Wang
skb_scrub_packet() drops all skb extensions unconditionally via
skb_ext_reset(). It runs on tunnel encap/decap (ip_tunnel_rcv, vxlan_rcv,
etc.) and virtual device forwarding/redirection (dev_forward_skb,
netkit_xmit, skb_do_redirect).
When a virtual device such as netkit is associated with a PSP device in
another network namespace via PSP_CMD_DEV_ASSOC, incoming PSP packets
decapsulated by psp_dev_rcv() lose their SKB_EXT_PSP extension when
scrubbed during redirection into the peer netns. Without SKB_EXT_PSP,
__psp_sk_rx_policy_check() rejects incoming TCP data segments at the
socket layer with SKB_DROP_REASON_PSP_INPUT.
Introduce a static skb_ext_scrub() helper in net/core/skbuff.c to
preserve SKB_EXT_PSP across skb_scrub_packet() while dropping all other
extensions. If SKB_EXT_PSP is not active, skb_ext_scrub() simply calls
skb_ext_reset(). If SKB_EXT_PSP is the only extension in the skb_ext
buffer, nothing needs to be scrubbed. Otherwise, save the PSP metadata,
reset the extension block, and re-add a fresh SKB_EXT_PSP extension (or
clear skb->decrypted if the allocation fails).
Fixes: 06c2dce2d0f6 ("psp: add new netlink cmd for dev-assoc and dev-disassoc")
Link: https://lore.kernel.org/r/20260910-bpf-meta-inside-skb-ext-v2-3-0b21e42180b0@cloudflare.com
Reported-by: Daniel Zahka <daniel.zahka@gmail.com>
Closes: https://lore.kernel.org/netdev/DLODSKPY6ON6.1G6SP3CFFLCPJ@gmail.com/
Co-developed-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Wei Wang <weiwan@google.com>
---
net/core/skbuff.c | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 93c2f440b9ec..5c4a2e982ebc 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -6369,6 +6369,32 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
}
EXPORT_SYMBOL(skb_try_coalesce);
+static void skb_ext_scrub(struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_INET_PSP)
+ struct psp_skb_ext *pse = skb_ext_find(skb, SKB_EXT_PSP);
+
+ if (pse) {
+ struct skb_ext *ext = skb->extensions;
+ struct psp_skb_ext tmp = *pse;
+
+ /* Nothing else to scrub if PSP is the only extension in ext. */
+ if (ext->chunks == SKB_EXT_CHUNKSIZEOF(*ext) +
+ skb_ext_type_len[SKB_EXT_PSP])
+ return;
+
+ skb_ext_reset(skb);
+ pse = skb_ext_add(skb, SKB_EXT_PSP);
+ if (pse)
+ memcpy(pse, &tmp, sizeof(*pse));
+ else
+ skb->decrypted = 0;
+ return;
+ }
+#endif
+ skb_ext_reset(skb);
+}
+
/**
* skb_scrub_packet - scrub an skb
*
@@ -6380,7 +6406,8 @@ EXPORT_SYMBOL(skb_try_coalesce);
* operations.
* skb_scrub_packet can also be used to clean a skb before injecting it in
* another namespace (@xnet == true). We have to clear all information in the
- * skb that could impact namespace isolation.
+ * skb that could impact namespace isolation. Note that PSP skb extension is
+ * preserved across packet scrubbing by design.
*/
void skb_scrub_packet(struct sk_buff *skb, bool xnet)
{
@@ -6388,7 +6415,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet)
skb->skb_iif = 0;
skb->ignore_df = 0;
skb_dst_drop(skb);
- skb_ext_reset(skb);
+ skb_ext_scrub(skb);
nf_reset_ct(skb);
nf_reset_trace(skb);
--
2.56.0.317.g454f8302e1-goog
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH net v2 2/2] selftests/net: psp: test bidirectional data transfer
2026-10-30 4:31 [PATCH net v2 0/2] net: psp: preserve SKB_EXT_PSP across packet scrubbing Wei Wang
2026-10-30 4:31 ` [PATCH net v2 1/2] net: Make PSP skb extension survive " Wei Wang
@ 2026-10-30 4:31 ` Wei Wang
1 sibling, 0 replies; 3+ messages in thread
From: Wei Wang @ 2026-10-30 4:31 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
Shuah Khan
Cc: Simon Horman, Jakub Sitnicki, Daniel Zahka, Willem de Bruijn,
netdev, linux-kselftest, linux-kernel, bpf, Wei Wang
_data_basic_send() and _data_basic_send_netkit_psp_assoc() currently
only verify unidirectional data transmission from the test socket to
psp_responder. As a result, they do not exercise the receive path for
PSP-encrypted TCP data segments arriving at the test socket (such as
packets redirected across a netkit interface associated via dev-assoc,
which relies on SKB_EXT_PSP surviving packet scrubbing).
Use the existing "data echo" command in psp_responder to verify that the
test socket can also receive PSP-encrypted data from the peer in both
_data_basic_send() and _data_basic_send_netkit_psp_assoc().
Signed-off-by: Wei Wang <weiwan@google.com>
---
tools/testing/selftests/drivers/net/psp.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tools/testing/selftests/drivers/net/psp.py b/tools/testing/selftests/drivers/net/psp.py
index 473500901879..e507951b440b 100755
--- a/tools/testing/selftests/drivers/net/psp.py
+++ b/tools/testing/selftests/drivers/net/psp.py
@@ -120,6 +120,12 @@ def _check_data_rx(cfg, exp_len):
ksft_eq(read_len, exp_len)
+def _check_data_echo(cfg, s):
+ _send_with_ack(cfg, b'data echo\0')
+ s.settimeout(1.0)
+ ksft_eq(s.recv(5), b'echo\0')
+
+
def _check_data_outq(s, exp_len, force_wait=False):
outq = 0
for _ in range(10):
@@ -478,6 +484,7 @@ def _data_basic_send(cfg, version, ipver):
data_len = _send_careful(cfg, s, 100)
_check_data_rx(cfg, data_len)
+ _check_data_echo(cfg, s)
_close_psp_conn(cfg, s)
@@ -726,6 +733,7 @@ def _data_basic_send_netkit_psp_assoc(cfg, version, ipver):
data_len = _send_careful(cfg, sock, 100)
_check_data_rx(cfg, data_len)
+ _check_data_echo(cfg, sock)
_close_psp_conn(cfg, sock)
--
2.56.0.317.g454f8302e1-goog
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-30 4:31 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-30 4:31 [PATCH net v2 0/2] net: psp: preserve SKB_EXT_PSP across packet scrubbing Wei Wang
2026-10-30 4:31 ` [PATCH net v2 1/2] net: Make PSP skb extension survive " Wei Wang
2026-10-30 4:31 ` [PATCH net v2 2/2] selftests/net: psp: test bidirectional data transfer Wei Wang
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.