Skip to content

Commit 00e4b23

Browse files
committed
kernel: fix IPv6 TCP GSO segmentation with NAT
Add missing checksum update Fixes: openwrt/openwrt#15857 Signed-off-by: Felix Fietkau <nbd@nbd.name>
1 parent 3a7467f commit 00e4b23

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
From: Felix Fietkau <nbd@nbd.name>
2+
Date: Mon, 24 Feb 2025 12:18:23 +0100
3+
Subject: [PATCH] net: ipv6: fix TCP GSO segmentation with NAT
4+
5+
When updating the source/destination address, the TCP/UDP checksum needs to
6+
be updated as well.
7+
8+
Fixes: bee88cd5bd83 ("net: add support for segmenting TCP fraglist GSO packets")
9+
Signed-off-by: Felix Fietkau <nbd@nbd.name>
10+
---
11+
12+
--- a/net/ipv6/tcpv6_offload.c
13+
+++ b/net/ipv6/tcpv6_offload.c
14+
@@ -112,24 +112,36 @@ static struct sk_buff *__tcpv6_gso_segme
15+
struct sk_buff *seg;
16+
struct tcphdr *th2;
17+
struct ipv6hdr *iph2;
18+
+ bool addr_equal;
19+
20+
seg = segs;
21+
th = tcp_hdr(seg);
22+
iph = ipv6_hdr(seg);
23+
th2 = tcp_hdr(seg->next);
24+
iph2 = ipv6_hdr(seg->next);
25+
+ addr_equal = ipv6_addr_equal(&iph->saddr, &iph2->saddr) &&
26+
+ ipv6_addr_equal(&iph->daddr, &iph2->daddr);
27+
28+
if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) &&
29+
- ipv6_addr_equal(&iph->saddr, &iph2->saddr) &&
30+
- ipv6_addr_equal(&iph->daddr, &iph2->daddr))
31+
+ addr_equal)
32+
return segs;
33+
34+
while ((seg = seg->next)) {
35+
th2 = tcp_hdr(seg);
36+
iph2 = ipv6_hdr(seg);
37+
38+
- iph2->saddr = iph->saddr;
39+
- iph2->daddr = iph->daddr;
40+
+ if (!addr_equal) {
41+
+ inet_proto_csum_replace16(&th2->check, seg,
42+
+ iph2->saddr.s6_addr32,
43+
+ iph->saddr.s6_addr32,
44+
+ true);
45+
+ inet_proto_csum_replace16(&th2->check, seg,
46+
+ iph2->daddr.s6_addr32,
47+
+ iph->daddr.s6_addr32,
48+
+ true);
49+
+ iph2->saddr = iph->saddr;
50+
+ iph2->daddr = iph->daddr;
51+
+ }
52+
__tcpv6_gso_segment_csum(seg, &th2->source, th->source);
53+
__tcpv6_gso_segment_csum(seg, &th2->dest, th->dest);
54+
}

0 commit comments

Comments
 (0)