[PATCH net v4 2/7] net: don't fragment decrypted skbs

From
Todd Freed <hidden>
Date
2026-11-03 00:12:01
Also in
linux-kselftest
Reply to
Todd Freed, 2026-11-03
on transmit, skb->decrypted means the device must encrypt the skb.
if it can't do that, then the packet should be dropped, not transmitted
unencrypted.

ip_do_fragment() on a decrypted skb produces fragments which have
skb->decrypted unset, and can be sent out unencrypted.

tx of individually encrypted fragments would not work anyway, because
encrypting needs the L4 header, which non-initial fragments do not have.

ktls could encrypt in sw before fragmenting. that would not work for psp
which doesn't have a software fallback path.

tcp sizes segments to the mtu, so psp and ktls socket packets normally
won't reach this path. it can be arranged for an ipv4 connection by
manipulating the route mtu and disabling pmtu on the socket
(IP_PMTUDISC_OMIT). the selftest later in the series does this.

an ipv6 tcp socket does not ever emit fragments. ip6_fragment() refuses
skbs bigger than the mtu unless ignore_df is set, which tcp doesn't set.

tested with tls tx offload on mlx5 (connectx-7). without this patch
some fragments after the first go out in cleartext, with it they're
dropped (IpFragFails) and the connection stalls.

Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure")
Fixes: 659a2899a57d ("tcp: add datapath logic for PSP with inline key exchange")
Signed-off-by: Todd Freed <redacted>
---
 net/ipv4/ip_output.c | 8 ++++++++
 1 file changed, 8 insertions(+)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index eaa6fabda347..415bc4d524b5 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -770,6 +770,14 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 	struct ip_frag_state state;
 	int err = 0;
 
+	/* psp and tls offload need the packet's l4 header, which non-initial
+	 * fragments do not have
+	 */
+	if (unlikely(skb_is_decrypted(skb))) {
+		err = -EMSGSIZE;
+		goto fail;
+	}
+
 	/* for offloaded checksums cleanup checksum before fragmentation */
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		err = ip_check_csum_start(skb);
-- 
2.53.0-Meta
Thread (14 messages) 14 messages, 2 authors, 6h ago
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help