Netdev List
 help / color / mirror / Atom feed
* [PATCH net v2 0/2] udp: gso: Fix __udp_gso_segment() after GSO_PARTIAL UDP length change
@ 2026-05-18  6:22 Gal Pressman
  2026-05-18  6:22 ` [PATCH net v2 1/2] udp: gso: Fix handling checksum in __udp_gso_segment Gal Pressman
  2026-05-18  6:22 ` [PATCH net v2 2/2] udp: Fix UDP length on last GSO_PARTIAL segment Gal Pressman
  0 siblings, 2 replies; 3+ messages in thread
From: Gal Pressman @ 2026-05-18  6:22 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Andrew Lunn, netdev
  Cc: Simon Horman, Gal Pressman, Willem de Bruijn, Dragos Tatulea,
	Alice Mikityanska

This series fixes two issues introduced by commit b10b446ce7ad ("udp:
gso: Use single MSS length in UDP header for GSO_PARTIAL"), which
switched __udp_gso_segment() to write the single MSS length into the UDP
header for GSO_PARTIAL skbs.

Patch 1 (from Alice) fixes the UDP checksum adjustment in
__udp_gso_segment().
The patch adjusts the checksum by the correct delta, and since msslen
and newlen become equivalent before the loop, drops one of the two
variables to simplify the code.

Patch 2 handles the case where the last segment of a GSO_PARTIAL skb is
itself a GSO skb. This happens when the original packet size is an exact
multiple of MSS, so the post-loop segment is not a remainder skb but a
full GSO chunk and must also carry the single MSS length in its UDP
header.

Changelog -
v1->v2: Took patch #1 from Alice.
	https://lore.kernel.org/all/20260513074349.2152146-1-gal@nvidia.com/
	https://lore.kernel.org/all/20260512165648.386518-3-alice.kernel@fastmail.im/

Alice Mikityanska (1):
  udp: gso: Fix handling checksum in __udp_gso_segment

Gal Pressman (1):
  udp: Fix UDP length on last GSO_PARTIAL segment

 net/ipv4/udp_offload.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

-- 
2.52.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH net v2 1/2] udp: gso: Fix handling checksum in __udp_gso_segment
  2026-05-18  6:22 [PATCH net v2 0/2] udp: gso: Fix __udp_gso_segment() after GSO_PARTIAL UDP length change Gal Pressman
@ 2026-05-18  6:22 ` Gal Pressman
  2026-05-18  6:22 ` [PATCH net v2 2/2] udp: Fix UDP length on last GSO_PARTIAL segment Gal Pressman
  1 sibling, 0 replies; 3+ messages in thread
From: Gal Pressman @ 2026-05-18  6:22 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Andrew Lunn, netdev
  Cc: Simon Horman, Gal Pressman, Willem de Bruijn, Dragos Tatulea,
	Alice Mikityanska

From: Alice Mikityanska <alice@isovalent.com>

The cited commit started using msslen for uh->len, but still uses newlen
to adjust uh->check. Although the checksum is ignored in most cases due
to the hardware offload, __udp_gso_segment attempts to maintain the
correct one. Fix uh->check and adjust it by the right value.

Additionally, after the fix, newlen becomes assigned and unused before
the loop. The code can be simplified a bit if mss adjustment is dropped,
so that newlen becomes equal to msslen before the loop, and msslen can
be also dropped, saving a few lines of code.

This brings us back to one variable, drops an unneeded arithmetic for
mss, and fixes the UDP checksum.

Fixes: b10b446ce7ad ("udp: gso: Use single MSS length in UDP header for GSO_PARTIAL")
Signed-off-by: Alice Mikityanska <alice@isovalent.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Gal Pressman <gal@nvidia.com>
---
 net/ipv4/udp_offload.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index a0813d425b71..2578aa7f9ff9 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -482,11 +482,11 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
 	struct sock *sk = gso_skb->sk;
 	unsigned int sum_truesize = 0;
 	struct sk_buff *segs, *seg;
-	__be16 newlen, msslen;
 	struct udphdr *uh;
 	unsigned int mss;
 	bool copy_dtor;
 	__sum16 check;
+	__be16 newlen;
 	int ret = 0;
 
 	mss = skb_shinfo(gso_skb)->gso_size;
@@ -555,15 +555,6 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
 		return segs;
 	}
 
-	msslen = htons(sizeof(*uh) + mss);
-
-	/* GSO partial and frag_list segmentation only requires splitting
-	 * the frame into an MSS multiple and possibly a remainder, both
-	 * cases return a GSO skb. So update the mss now.
-	 */
-	if (skb_is_gso(segs))
-		mss *= skb_shinfo(segs)->gso_segs;
-
 	seg = segs;
 	uh = udp_hdr(seg);
 
@@ -586,7 +577,7 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
 		if (!seg->next)
 			break;
 
-		uh->len = msslen;
+		uh->len = newlen;
 		uh->check = check;
 
 		if (seg->ip_summed == CHECKSUM_PARTIAL)
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH net v2 2/2] udp: Fix UDP length on last GSO_PARTIAL segment
  2026-05-18  6:22 [PATCH net v2 0/2] udp: gso: Fix __udp_gso_segment() after GSO_PARTIAL UDP length change Gal Pressman
  2026-05-18  6:22 ` [PATCH net v2 1/2] udp: gso: Fix handling checksum in __udp_gso_segment Gal Pressman
@ 2026-05-18  6:22 ` Gal Pressman
  1 sibling, 0 replies; 3+ messages in thread
From: Gal Pressman @ 2026-05-18  6:22 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Andrew Lunn, netdev
  Cc: Simon Horman, Gal Pressman, Willem de Bruijn, Dragos Tatulea,
	Alice Mikityanska, Matthew Schwartz

Following the cited commit, __udp_gso_segment() writes single MSS length
in the UDP header.
The cited patch doesn't account for the fact that the last segment could
be a GSO skb by itself. This could happen when the size of the packet is
a multiple of MSS, hence the first segment is also the last one (there
is no need for a remainder skb).

When the post-loop segment is a GSO skb, assign the single MSS length in
the UDP header.

Fixes: b10b446ce7ad ("udp: gso: Use single MSS length in UDP header for GSO_PARTIAL")
Reported-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Closes: https://lore.kernel.org/all/6c3fb15e-711d-4b8d-b152-e03d9b05293f@linux.dev/
Tested-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Gal Pressman <gal@nvidia.com>
---
 net/ipv4/udp_offload.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 2578aa7f9ff9..815396fe97ad 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -590,9 +590,12 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
 		uh = udp_hdr(seg);
 	}
 
-	/* last packet can be partial gso_size, account for that in checksum */
-	newlen = htons(skb_tail_pointer(seg) - skb_transport_header(seg) +
-		       seg->data_len);
+	if (!skb_is_gso(seg))
+		/* last packet can be partial gso_size, account for that in
+		 * checksum.
+		 */
+		newlen = htons(skb_tail_pointer(seg) -
+			       skb_transport_header(seg) + seg->data_len);
 	check = csum16_add(csum16_sub(uh->check, uh->len), newlen);
 
 	uh->len = newlen;
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-05-18  6:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-18  6:22 [PATCH net v2 0/2] udp: gso: Fix __udp_gso_segment() after GSO_PARTIAL UDP length change Gal Pressman
2026-05-18  6:22 ` [PATCH net v2 1/2] udp: gso: Fix handling checksum in __udp_gso_segment Gal Pressman
2026-05-18  6:22 ` [PATCH net v2 2/2] udp: Fix UDP length on last GSO_PARTIAL segment Gal Pressman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox