This patch fixes an issue in skb_gso_network_seglen and similar functions where the calculated segment length includes the HBH headers of BIG TCP jumbograms despite these headers being removed before segmentation. These headers are added by GRO or by ip6_xmit for BIG TCP packets and are later removed by GSO. This bug causes MTU validation of BIG TCP jumbograms to fail. Signed-off-by: Mariusz Klimek --- net/core/gso.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/net/core/gso.c b/net/core/gso.c index bcd156372f4d..deacd32f644d 100644 --- a/net/core/gso.c +++ b/net/core/gso.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-or-later +#include #include #include #include @@ -177,8 +178,13 @@ static unsigned int skb_gso_transport_seglen(const struct sk_buff *skb) */ static unsigned int skb_gso_network_seglen(const struct sk_buff *skb) { - unsigned int hdr_len = skb_transport_header(skb) - - skb_network_header(skb); + unsigned int off = skb_network_offset(skb) + sizeof(struct ipv6hdr); + unsigned int hdr_len = skb_network_header_len(skb); + + /* Jumbogram HBH header is removed upon segmentation. */ + if (skb_protocol(skb, true) == htons(ETH_P_IPV6) && + skb->len - off > IPV6_MAXPLEN) + hdr_len -= sizeof(struct hop_jumbo_hdr); return hdr_len + skb_gso_transport_seglen(skb); } @@ -194,9 +200,7 @@ static unsigned int skb_gso_network_seglen(const struct sk_buff *skb) */ static unsigned int skb_gso_mac_seglen(const struct sk_buff *skb) { - unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb); - - return hdr_len + skb_gso_transport_seglen(skb); + return skb_mac_header_len(skb) + skb_gso_network_seglen(skb); } /** -- 2.47.3