]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-6.1/udp-do-not-transition-udp-gro-fraglist-partial-checksums-to-unnecessary.patch
6.1-stable patches
[thirdparty/kernel/stable-queue.git] / queue-6.1 / udp-do-not-transition-udp-gro-fraglist-partial-checksums-to-unnecessary.patch
1 From f0b8c30345565344df2e33a8417a27503589247d Mon Sep 17 00:00:00 2001
2 From: Antoine Tenart <atenart@kernel.org>
3 Date: Tue, 26 Mar 2024 12:34:00 +0100
4 Subject: udp: do not transition UDP GRO fraglist partial checksums to unnecessary
5
6 From: Antoine Tenart <atenart@kernel.org>
7
8 commit f0b8c30345565344df2e33a8417a27503589247d upstream.
9
10 UDP GRO validates checksums and in udp4/6_gro_complete fraglist packets
11 are converted to CHECKSUM_UNNECESSARY to avoid later checks. However
12 this is an issue for CHECKSUM_PARTIAL packets as they can be looped in
13 an egress path and then their partial checksums are not fixed.
14
15 Different issues can be observed, from invalid checksum on packets to
16 traces like:
17
18 gen01: hw csum failure
19 skb len=3008 headroom=160 headlen=1376 tailroom=0
20 mac=(106,14) net=(120,40) trans=160
21 shinfo(txflags=0 nr_frags=0 gso(size=0 type=0 segs=0))
22 csum(0xffff232e ip_summed=2 complete_sw=0 valid=0 level=0)
23 hash(0x77e3d716 sw=1 l4=1) proto=0x86dd pkttype=0 iif=12
24 ...
25
26 Fix this by only converting CHECKSUM_NONE packets to
27 CHECKSUM_UNNECESSARY by reusing __skb_incr_checksum_unnecessary. All
28 other checksum types are kept as-is, including CHECKSUM_COMPLETE as
29 fraglist packets being segmented back would have their skb->csum valid.
30
31 Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")
32 Signed-off-by: Antoine Tenart <atenart@kernel.org>
33 Reviewed-by: Willem de Bruijn <willemb@google.com>
34 Signed-off-by: David S. Miller <davem@davemloft.net>
35 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
36 ---
37 net/ipv4/udp_offload.c | 8 +-------
38 net/ipv6/udp_offload.c | 8 +-------
39 2 files changed, 2 insertions(+), 14 deletions(-)
40
41 --- a/net/ipv4/udp_offload.c
42 +++ b/net/ipv4/udp_offload.c
43 @@ -710,13 +710,7 @@ INDIRECT_CALLABLE_SCOPE int udp4_gro_com
44 skb_shinfo(skb)->gso_type |= (SKB_GSO_FRAGLIST|SKB_GSO_UDP_L4);
45 skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
46
47 - if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
48 - if (skb->csum_level < SKB_MAX_CSUM_LEVEL)
49 - skb->csum_level++;
50 - } else {
51 - skb->ip_summed = CHECKSUM_UNNECESSARY;
52 - skb->csum_level = 0;
53 - }
54 + __skb_incr_checksum_unnecessary(skb);
55
56 return 0;
57 }
58 --- a/net/ipv6/udp_offload.c
59 +++ b/net/ipv6/udp_offload.c
60 @@ -169,13 +169,7 @@ INDIRECT_CALLABLE_SCOPE int udp6_gro_com
61 skb_shinfo(skb)->gso_type |= (SKB_GSO_FRAGLIST|SKB_GSO_UDP_L4);
62 skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
63
64 - if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
65 - if (skb->csum_level < SKB_MAX_CSUM_LEVEL)
66 - skb->csum_level++;
67 - } else {
68 - skb->ip_summed = CHECKSUM_UNNECESSARY;
69 - skb->csum_level = 0;
70 - }
71 + __skb_incr_checksum_unnecessary(skb);
72
73 return 0;
74 }