From: Greg Kroah-Hartman Date: Thu, 19 Jun 2025 04:27:22 +0000 (+0200) Subject: drop net-fix-checksum-update-for-ila-adj-transport.patch from a few branches X-Git-Tag: v6.6.94~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e125d1771a99cbf0e3f774db8d19a74a6ee54060;p=thirdparty%2Fkernel%2Fstable-queue.git drop net-fix-checksum-update-for-ila-adj-transport.patch from a few branches --- diff --git a/queue-6.1/net-fix-checksum-update-for-ila-adj-transport.patch b/queue-6.1/net-fix-checksum-update-for-ila-adj-transport.patch deleted file mode 100644 index 95270413e0..0000000000 --- a/queue-6.1/net-fix-checksum-update-for-ila-adj-transport.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 67586a97ed89a18cf0032c2ea9fa094760422662 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 29 May 2025 12:28:05 +0200 -Subject: net: Fix checksum update for ILA adj-transport - -From: Paul Chaignon - -[ Upstream commit 6043b794c7668c19dabc4a93c75b924a19474d59 ] - -During ILA address translations, the L4 checksums can be handled in -different ways. One of them, adj-transport, consist in parsing the -transport layer and updating any found checksum. This logic relies on -inet_proto_csum_replace_by_diff and produces an incorrect skb->csum when -in state CHECKSUM_COMPLETE. - -This bug can be reproduced with a simple ILA to SIR mapping, assuming -packets are received with CHECKSUM_COMPLETE: - - $ ip a show dev eth0 - 14: eth0@if15: mtu 1500 qdisc noqueue state UP group default qlen 1000 - link/ether 62:ae:35:9e:0f:8d brd ff:ff:ff:ff:ff:ff link-netnsid 0 - inet6 3333:0:0:1::c078/64 scope global - valid_lft forever preferred_lft forever - inet6 fd00:10:244:1::c078/128 scope global nodad - valid_lft forever preferred_lft forever - inet6 fe80::60ae:35ff:fe9e:f8d/64 scope link proto kernel_ll - valid_lft forever preferred_lft forever - $ ip ila add loc_match fd00:10:244:1 loc 3333:0:0:1 \ - csum-mode adj-transport ident-type luid dev eth0 - -Then I hit [fd00:10:244:1::c078]:8000 with a server listening only on -[3333:0:0:1::c078]:8000. With the bug, the SYN packet is dropped with -SKB_DROP_REASON_TCP_CSUM after inet_proto_csum_replace_by_diff changed -skb->csum. The translation and drop are visible on pwru [1] traces: - - IFACE TUPLE FUNC - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) ipv6_rcv - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) ip6_rcv_core - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) nf_hook_slow - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) inet_proto_csum_replace_by_diff - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) tcp_v6_early_demux - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_route_input - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_input - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_input_finish - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_protocol_deliver_rcu - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) raw6_local_deliver - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ipv6_raw_deliver - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) tcp_v6_rcv - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) __skb_checksum_complete - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) kfree_skb_reason(SKB_DROP_REASON_TCP_CSUM) - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_release_head_state - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_release_data - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_free_head - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) kfree_skbmem - -This is happening because inet_proto_csum_replace_by_diff is updating -skb->csum when it shouldn't. The L4 checksum is updated such that it -"cancels" the IPv6 address change in terms of checksum computation, so -the impact on skb->csum is null. - -Note this would be different for an IPv4 packet since three fields -would be updated: the IPv4 address, the IP checksum, and the L4 -checksum. Two would cancel each other and skb->csum would still need -to be updated to take the L4 checksum change into account. - -This patch fixes it by passing an ipv6 flag to -inet_proto_csum_replace_by_diff, to skip the skb->csum update if we're -in the IPv6 case. Note the behavior of the only other user of -inet_proto_csum_replace_by_diff, the BPF subsystem, is left as is in -this patch and fixed in the subsequent patch. - -With the fix, using the reproduction from above, I can confirm -skb->csum is not touched by inet_proto_csum_replace_by_diff and the TCP -SYN proceeds to the application after the ILA translation. - -Link: https://github.com/cilium/pwru [1] -Fixes: 65d7ab8de582 ("net: Identifier Locator Addressing module") -Signed-off-by: Paul Chaignon -Acked-by: Daniel Borkmann -Link: https://patch.msgid.link/b5539869e3550d46068504feb02d37653d939c0b.1748509484.git.paul.chaignon@gmail.com -Signed-off-by: Jakub Kicinski -Signed-off-by: Sasha Levin ---- - include/net/checksum.h | 2 +- - net/core/filter.c | 2 +- - net/core/utils.c | 4 ++-- - net/ipv6/ila/ila_common.c | 6 +++--- - 4 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/include/net/checksum.h b/include/net/checksum.h -index 6bc783b7a06c2..a3d1bde322c98 100644 ---- a/include/net/checksum.h -+++ b/include/net/checksum.h -@@ -156,7 +156,7 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, - const __be32 *from, const __be32 *to, - bool pseudohdr); - void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, -- __wsum diff, bool pseudohdr); -+ __wsum diff, bool pseudohdr, bool ipv6); - - static __always_inline - void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, -diff --git a/net/core/filter.c b/net/core/filter.c -index 497b41ac399da..e58cd1dfa6b19 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -1977,7 +1977,7 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset, - if (unlikely(from != 0)) - return -EINVAL; - -- inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo); -+ inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, false); - break; - case 2: - inet_proto_csum_replace2(ptr, skb, from, to, is_pseudo); -diff --git a/net/core/utils.c b/net/core/utils.c -index 938495bc1d348..1eeb9131e2cf7 100644 ---- a/net/core/utils.c -+++ b/net/core/utils.c -@@ -473,11 +473,11 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, - EXPORT_SYMBOL(inet_proto_csum_replace16); - - void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, -- __wsum diff, bool pseudohdr) -+ __wsum diff, bool pseudohdr, bool ipv6) - { - if (skb->ip_summed != CHECKSUM_PARTIAL) { - csum_replace_by_diff(sum, diff); -- if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) -+ if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr && !ipv6) - skb->csum = ~csum_sub(diff, skb->csum); - } else if (pseudohdr) { - *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum))); -diff --git a/net/ipv6/ila/ila_common.c b/net/ipv6/ila/ila_common.c -index 95e9146918cc6..b8d43ed4689db 100644 ---- a/net/ipv6/ila/ila_common.c -+++ b/net/ipv6/ila/ila_common.c -@@ -86,7 +86,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, - - diff = get_csum_diff(ip6h, p); - inet_proto_csum_replace_by_diff(&th->check, skb, -- diff, true); -+ diff, true, true); - } - break; - case NEXTHDR_UDP: -@@ -97,7 +97,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, - if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) { - diff = get_csum_diff(ip6h, p); - inet_proto_csum_replace_by_diff(&uh->check, skb, -- diff, true); -+ diff, true, true); - if (!uh->check) - uh->check = CSUM_MANGLED_0; - } -@@ -111,7 +111,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, - - diff = get_csum_diff(ip6h, p); - inet_proto_csum_replace_by_diff(&ih->icmp6_cksum, skb, -- diff, true); -+ diff, true, true); - } - break; - } --- -2.39.5 - diff --git a/queue-6.1/series b/queue-6.1/series index 67eed5d1c9..5acb9772d5 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -177,7 +177,6 @@ ice-create-new-tx-scheduler-nodes-for-new-queues-onl.patch ice-fix-rebuilding-the-tx-scheduler-tree-for-large-q.patch net-dsa-tag_brcm-legacy-fix-pskb_may_pull-length.patch net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch -net-fix-checksum-update-for-ila-adj-transport.patch net-fix-udp-gso-skb_segment-after-pull-from-frag_lis.patch vmxnet3-correctly-report-gso-type-for-udp-tunnels.patch pm-sleep-fix-power.is_suspended-cleanup-for-direct-c.patch diff --git a/queue-6.12/net-fix-checksum-update-for-ila-adj-transport.patch b/queue-6.12/net-fix-checksum-update-for-ila-adj-transport.patch deleted file mode 100644 index f1ef2adbce..0000000000 --- a/queue-6.12/net-fix-checksum-update-for-ila-adj-transport.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 3ca632ad4268007d16e3d4006f349ed9eff4d2a3 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 29 May 2025 12:28:05 +0200 -Subject: net: Fix checksum update for ILA adj-transport - -From: Paul Chaignon - -[ Upstream commit 6043b794c7668c19dabc4a93c75b924a19474d59 ] - -During ILA address translations, the L4 checksums can be handled in -different ways. One of them, adj-transport, consist in parsing the -transport layer and updating any found checksum. This logic relies on -inet_proto_csum_replace_by_diff and produces an incorrect skb->csum when -in state CHECKSUM_COMPLETE. - -This bug can be reproduced with a simple ILA to SIR mapping, assuming -packets are received with CHECKSUM_COMPLETE: - - $ ip a show dev eth0 - 14: eth0@if15: mtu 1500 qdisc noqueue state UP group default qlen 1000 - link/ether 62:ae:35:9e:0f:8d brd ff:ff:ff:ff:ff:ff link-netnsid 0 - inet6 3333:0:0:1::c078/64 scope global - valid_lft forever preferred_lft forever - inet6 fd00:10:244:1::c078/128 scope global nodad - valid_lft forever preferred_lft forever - inet6 fe80::60ae:35ff:fe9e:f8d/64 scope link proto kernel_ll - valid_lft forever preferred_lft forever - $ ip ila add loc_match fd00:10:244:1 loc 3333:0:0:1 \ - csum-mode adj-transport ident-type luid dev eth0 - -Then I hit [fd00:10:244:1::c078]:8000 with a server listening only on -[3333:0:0:1::c078]:8000. With the bug, the SYN packet is dropped with -SKB_DROP_REASON_TCP_CSUM after inet_proto_csum_replace_by_diff changed -skb->csum. The translation and drop are visible on pwru [1] traces: - - IFACE TUPLE FUNC - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) ipv6_rcv - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) ip6_rcv_core - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) nf_hook_slow - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) inet_proto_csum_replace_by_diff - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) tcp_v6_early_demux - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_route_input - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_input - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_input_finish - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_protocol_deliver_rcu - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) raw6_local_deliver - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ipv6_raw_deliver - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) tcp_v6_rcv - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) __skb_checksum_complete - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) kfree_skb_reason(SKB_DROP_REASON_TCP_CSUM) - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_release_head_state - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_release_data - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_free_head - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) kfree_skbmem - -This is happening because inet_proto_csum_replace_by_diff is updating -skb->csum when it shouldn't. The L4 checksum is updated such that it -"cancels" the IPv6 address change in terms of checksum computation, so -the impact on skb->csum is null. - -Note this would be different for an IPv4 packet since three fields -would be updated: the IPv4 address, the IP checksum, and the L4 -checksum. Two would cancel each other and skb->csum would still need -to be updated to take the L4 checksum change into account. - -This patch fixes it by passing an ipv6 flag to -inet_proto_csum_replace_by_diff, to skip the skb->csum update if we're -in the IPv6 case. Note the behavior of the only other user of -inet_proto_csum_replace_by_diff, the BPF subsystem, is left as is in -this patch and fixed in the subsequent patch. - -With the fix, using the reproduction from above, I can confirm -skb->csum is not touched by inet_proto_csum_replace_by_diff and the TCP -SYN proceeds to the application after the ILA translation. - -Link: https://github.com/cilium/pwru [1] -Fixes: 65d7ab8de582 ("net: Identifier Locator Addressing module") -Signed-off-by: Paul Chaignon -Acked-by: Daniel Borkmann -Link: https://patch.msgid.link/b5539869e3550d46068504feb02d37653d939c0b.1748509484.git.paul.chaignon@gmail.com -Signed-off-by: Jakub Kicinski -Signed-off-by: Sasha Levin ---- - include/net/checksum.h | 2 +- - net/core/filter.c | 2 +- - net/core/utils.c | 4 ++-- - net/ipv6/ila/ila_common.c | 6 +++--- - 4 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/include/net/checksum.h b/include/net/checksum.h -index 1338cb92c8e72..28b101f26636e 100644 ---- a/include/net/checksum.h -+++ b/include/net/checksum.h -@@ -158,7 +158,7 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, - const __be32 *from, const __be32 *to, - bool pseudohdr); - void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, -- __wsum diff, bool pseudohdr); -+ __wsum diff, bool pseudohdr, bool ipv6); - - static __always_inline - void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, -diff --git a/net/core/filter.c b/net/core/filter.c -index 99b23fd2f509c..e0d978c1a4cdc 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -1999,7 +1999,7 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset, - if (unlikely(from != 0)) - return -EINVAL; - -- inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo); -+ inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, false); - break; - case 2: - inet_proto_csum_replace2(ptr, skb, from, to, is_pseudo); -diff --git a/net/core/utils.c b/net/core/utils.c -index 27f4cffaae05d..b8c21a859e27b 100644 ---- a/net/core/utils.c -+++ b/net/core/utils.c -@@ -473,11 +473,11 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, - EXPORT_SYMBOL(inet_proto_csum_replace16); - - void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, -- __wsum diff, bool pseudohdr) -+ __wsum diff, bool pseudohdr, bool ipv6) - { - if (skb->ip_summed != CHECKSUM_PARTIAL) { - csum_replace_by_diff(sum, diff); -- if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) -+ if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr && !ipv6) - skb->csum = ~csum_sub(diff, skb->csum); - } else if (pseudohdr) { - *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum))); -diff --git a/net/ipv6/ila/ila_common.c b/net/ipv6/ila/ila_common.c -index 95e9146918cc6..b8d43ed4689db 100644 ---- a/net/ipv6/ila/ila_common.c -+++ b/net/ipv6/ila/ila_common.c -@@ -86,7 +86,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, - - diff = get_csum_diff(ip6h, p); - inet_proto_csum_replace_by_diff(&th->check, skb, -- diff, true); -+ diff, true, true); - } - break; - case NEXTHDR_UDP: -@@ -97,7 +97,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, - if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) { - diff = get_csum_diff(ip6h, p); - inet_proto_csum_replace_by_diff(&uh->check, skb, -- diff, true); -+ diff, true, true); - if (!uh->check) - uh->check = CSUM_MANGLED_0; - } -@@ -111,7 +111,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, - - diff = get_csum_diff(ip6h, p); - inet_proto_csum_replace_by_diff(&ih->icmp6_cksum, skb, -- diff, true); -+ diff, true, true); - } - break; - } --- -2.39.5 - diff --git a/queue-6.12/series b/queue-6.12/series index 8312124157..391e2c0413 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -357,7 +357,6 @@ idpf-avoid-mailbox-timeout-delays-during-reset.patch net-dsa-tag_brcm-legacy-fix-pskb_may_pull-length.patch net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch-7636 -net-fix-checksum-update-for-ila-adj-transport.patch drm-i915-guc-check-if-expecting-reply-before-decreme.patch drm-i915-psr-fix-using-wrong-mask-in-reg_field_prep.patch drm-i915-guc-handle-race-condition-where-wakeref-cou.patch diff --git a/queue-6.6/net-fix-checksum-update-for-ila-adj-transport.patch b/queue-6.6/net-fix-checksum-update-for-ila-adj-transport.patch deleted file mode 100644 index 881450c4e6..0000000000 --- a/queue-6.6/net-fix-checksum-update-for-ila-adj-transport.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 6bc7933214feb67e0ec69e745251d831e33ccff2 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 29 May 2025 12:28:05 +0200 -Subject: net: Fix checksum update for ILA adj-transport - -From: Paul Chaignon - -[ Upstream commit 6043b794c7668c19dabc4a93c75b924a19474d59 ] - -During ILA address translations, the L4 checksums can be handled in -different ways. One of them, adj-transport, consist in parsing the -transport layer and updating any found checksum. This logic relies on -inet_proto_csum_replace_by_diff and produces an incorrect skb->csum when -in state CHECKSUM_COMPLETE. - -This bug can be reproduced with a simple ILA to SIR mapping, assuming -packets are received with CHECKSUM_COMPLETE: - - $ ip a show dev eth0 - 14: eth0@if15: mtu 1500 qdisc noqueue state UP group default qlen 1000 - link/ether 62:ae:35:9e:0f:8d brd ff:ff:ff:ff:ff:ff link-netnsid 0 - inet6 3333:0:0:1::c078/64 scope global - valid_lft forever preferred_lft forever - inet6 fd00:10:244:1::c078/128 scope global nodad - valid_lft forever preferred_lft forever - inet6 fe80::60ae:35ff:fe9e:f8d/64 scope link proto kernel_ll - valid_lft forever preferred_lft forever - $ ip ila add loc_match fd00:10:244:1 loc 3333:0:0:1 \ - csum-mode adj-transport ident-type luid dev eth0 - -Then I hit [fd00:10:244:1::c078]:8000 with a server listening only on -[3333:0:0:1::c078]:8000. With the bug, the SYN packet is dropped with -SKB_DROP_REASON_TCP_CSUM after inet_proto_csum_replace_by_diff changed -skb->csum. The translation and drop are visible on pwru [1] traces: - - IFACE TUPLE FUNC - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) ipv6_rcv - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) ip6_rcv_core - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) nf_hook_slow - eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) inet_proto_csum_replace_by_diff - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) tcp_v6_early_demux - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_route_input - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_input - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_input_finish - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_protocol_deliver_rcu - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) raw6_local_deliver - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ipv6_raw_deliver - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) tcp_v6_rcv - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) __skb_checksum_complete - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) kfree_skb_reason(SKB_DROP_REASON_TCP_CSUM) - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_release_head_state - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_release_data - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_free_head - eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) kfree_skbmem - -This is happening because inet_proto_csum_replace_by_diff is updating -skb->csum when it shouldn't. The L4 checksum is updated such that it -"cancels" the IPv6 address change in terms of checksum computation, so -the impact on skb->csum is null. - -Note this would be different for an IPv4 packet since three fields -would be updated: the IPv4 address, the IP checksum, and the L4 -checksum. Two would cancel each other and skb->csum would still need -to be updated to take the L4 checksum change into account. - -This patch fixes it by passing an ipv6 flag to -inet_proto_csum_replace_by_diff, to skip the skb->csum update if we're -in the IPv6 case. Note the behavior of the only other user of -inet_proto_csum_replace_by_diff, the BPF subsystem, is left as is in -this patch and fixed in the subsequent patch. - -With the fix, using the reproduction from above, I can confirm -skb->csum is not touched by inet_proto_csum_replace_by_diff and the TCP -SYN proceeds to the application after the ILA translation. - -Link: https://github.com/cilium/pwru [1] -Fixes: 65d7ab8de582 ("net: Identifier Locator Addressing module") -Signed-off-by: Paul Chaignon -Acked-by: Daniel Borkmann -Link: https://patch.msgid.link/b5539869e3550d46068504feb02d37653d939c0b.1748509484.git.paul.chaignon@gmail.com -Signed-off-by: Jakub Kicinski -Signed-off-by: Sasha Levin ---- - include/net/checksum.h | 2 +- - net/core/filter.c | 2 +- - net/core/utils.c | 4 ++-- - net/ipv6/ila/ila_common.c | 6 +++--- - 4 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/include/net/checksum.h b/include/net/checksum.h -index 1338cb92c8e72..28b101f26636e 100644 ---- a/include/net/checksum.h -+++ b/include/net/checksum.h -@@ -158,7 +158,7 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, - const __be32 *from, const __be32 *to, - bool pseudohdr); - void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, -- __wsum diff, bool pseudohdr); -+ __wsum diff, bool pseudohdr, bool ipv6); - - static __always_inline - void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, -diff --git a/net/core/filter.c b/net/core/filter.c -index 5143c8a9e52ca..e92f3a9017bb4 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -1987,7 +1987,7 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset, - if (unlikely(from != 0)) - return -EINVAL; - -- inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo); -+ inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, false); - break; - case 2: - inet_proto_csum_replace2(ptr, skb, from, to, is_pseudo); -diff --git a/net/core/utils.c b/net/core/utils.c -index c994e95172acf..5895d034bf279 100644 ---- a/net/core/utils.c -+++ b/net/core/utils.c -@@ -473,11 +473,11 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, - EXPORT_SYMBOL(inet_proto_csum_replace16); - - void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, -- __wsum diff, bool pseudohdr) -+ __wsum diff, bool pseudohdr, bool ipv6) - { - if (skb->ip_summed != CHECKSUM_PARTIAL) { - csum_replace_by_diff(sum, diff); -- if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) -+ if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr && !ipv6) - skb->csum = ~csum_sub(diff, skb->csum); - } else if (pseudohdr) { - *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum))); -diff --git a/net/ipv6/ila/ila_common.c b/net/ipv6/ila/ila_common.c -index 95e9146918cc6..b8d43ed4689db 100644 ---- a/net/ipv6/ila/ila_common.c -+++ b/net/ipv6/ila/ila_common.c -@@ -86,7 +86,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, - - diff = get_csum_diff(ip6h, p); - inet_proto_csum_replace_by_diff(&th->check, skb, -- diff, true); -+ diff, true, true); - } - break; - case NEXTHDR_UDP: -@@ -97,7 +97,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, - if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) { - diff = get_csum_diff(ip6h, p); - inet_proto_csum_replace_by_diff(&uh->check, skb, -- diff, true); -+ diff, true, true); - if (!uh->check) - uh->check = CSUM_MANGLED_0; - } -@@ -111,7 +111,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb, - - diff = get_csum_diff(ip6h, p); - inet_proto_csum_replace_by_diff(&ih->icmp6_cksum, skb, -- diff, true); -+ diff, true, true); - } - break; - } --- -2.39.5 - diff --git a/queue-6.6/series b/queue-6.6/series index aa8347a9a3..63b76e15c0 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -251,7 +251,6 @@ ice-create-new-tx-scheduler-nodes-for-new-queues-onl.patch ice-fix-rebuilding-the-tx-scheduler-tree-for-large-q.patch net-dsa-tag_brcm-legacy-fix-pskb_may_pull-length.patch net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch -net-fix-checksum-update-for-ila-adj-transport.patch net-fix-udp-gso-skb_segment-after-pull-from-frag_lis.patch net-wwan-t7xx-fix-napi-rx-poll-issue.patch vmxnet3-correctly-report-gso-type-for-udp-tunnels.patch