[PATCH] net: gro: mark frag_list GRO packets as SKB_GSO_DODGY when a list element exceeds gso_size
From: Shiming Cheng
Date: Tue Sep 29 2026 - 06:09:00 EST
When RX LRO (or similar offload) is enabled, the TCP/IPv4 GRO path may
aggregate traffic using frag_list. The resulting skb is later segmented
via the frag_list segmentation path (skb_segment_list()).
However, some drivers can hand GRO/LRO-aggregated frames to the stack
where individual frag_list elements are already larger than skb_shinfo(p)
->gso_size (i.e., an element itself contains multiple MSS worth of
payload) and may be non-linear (nr_frags > 0). This shape is not
naturally produced by the software GRO aggregation logic for devices
without LRO, and can lead to unexpected behavior in the frag_list
segmentation path.
Detect this condition during frag_list aggregation and mark the
aggregated packet as SKB_GSO_DODGY when a list element’s length exceeds
gso_size. This forces a more conservative segmentation/linearization
behavior downstream and avoids relying on assumptions that do not hold
for LRO-produced aggregates.
No change for normal software GRO aggregation: the new check only
triggers when skb_shinfo(p)->gso_size is set and a frag_list element
length exceeds that size.
Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.")
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Shiming Cheng <shiming.cheng@xxxxxxxxxxxx>
---
net/core/gro.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/core/gro.c b/net/core/gro.c
index 29b4d02bf519..e70ecf19b0a7 100644
--- a/net/core/gro.c
+++ b/net/core/gro.c
@@ -259,6 +259,9 @@ int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
skb_shinfo(p)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
NAPI_GRO_CB(skb)->same_flow = 1;
+ /* frag_list element larger than gso_size (already coalesced before list-append) */
+ if (skb_shinfo(p)->gso_size && skb->len > skb_shinfo(p)->gso_size)
+ skb_shinfo(p)->gso_type |= SKB_GSO_DODGY;
return 0;
}
--
2.45.2