Skip to content

Commit cbe99b6

Browse files
Jibin ZhangNipaLocal
authored andcommitted
net: fix segmentation of forwarding fraglist GRO
This patch enhances GSO segment checks by verifying the presence of frag_list and protocol consistency, addressing low throughput issues on IPv4 servers when used as hotspots Specifically, it fixes a bug in GSO segmentation when forwarding GRO packets with frag_list. The function skb_segment_list cannot correctly process GRO skbs converted by XLAT, because XLAT only converts the header of the head skb. As a result, skbs in the frag_list may remain unconverted, leading to protocol inconsistencies and reduced throughput. To resolve this, the patch uses skb_segment to handle forwarded packets converted by XLAT, ensuring that all fragments are properly converted and segmented. Signed-off-by: Jibin Zhang <jibin.zhang@mediatek.com> Signed-off-by: NipaLocal <nipa@local>
1 parent e10172b commit cbe99b6

File tree

2 files changed

+4
-2
lines changed

2 files changed

+4
-2
lines changed

net/ipv4/tcp_offload.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb,
104104
if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
105105
return ERR_PTR(-EINVAL);
106106

107-
if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) {
107+
if ((skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) && skb_has_frag_list(skb) &&
108+
(skb->protocol == skb_shinfo(skb)->frag_list->protocol)) {
108109
struct tcphdr *th = tcp_hdr(skb);
109110

110111
if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size)

net/ipv4/udp_offload.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,8 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
512512
return NULL;
513513
}
514514

515-
if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) {
515+
if ((skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) && skb_has_frag_list(gso_skb) &&
516+
(gso_skb->protocol == skb_shinfo(gso_skb)->frag_list->protocol)) {
516517
/* Detect modified geometry and pass those to skb_segment. */
517518
if (skb_pagelen(gso_skb) - sizeof(*uh) == skb_shinfo(gso_skb)->gso_size)
518519
return __udp_gso_segment_list(gso_skb, features, is_ipv6);

0 commit comments

Comments
 (0)