From: Greg Kroah-Hartman Date: Tue, 16 Jun 2026 07:02:02 +0000 (+0530) Subject: 6.6-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1ebe0cd24eb2b998a759ec2c7a06559a6890ecc3;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: ipvs-skip-ipv6-extension-headers-for-csum-checks.patch --- diff --git a/queue-6.6/ipvs-skip-ipv6-extension-headers-for-csum-checks.patch b/queue-6.6/ipvs-skip-ipv6-extension-headers-for-csum-checks.patch new file mode 100644 index 0000000000..f82fb0b42b --- /dev/null +++ b/queue-6.6/ipvs-skip-ipv6-extension-headers-for-csum-checks.patch @@ -0,0 +1,195 @@ +From 05cfe9863ef049d98141dc2969eefde72fb07625 Mon Sep 17 00:00:00 2001 +From: Julian Anastasov +Date: Sat, 14 Feb 2026 16:58:49 +0200 +Subject: ipvs: skip ipv6 extension headers for csum checks + +From: Julian Anastasov + +commit 05cfe9863ef049d98141dc2969eefde72fb07625 upstream. + +Protocol checksum validation fails for IPv6 if there are extension +headers before the protocol header. iph->len already contains its +offset, so use it to fix the problem. + +Fixes: 2906f66a5682 ("ipvs: SCTP Trasport Loadbalancing Support") +Fixes: 0bbdd42b7efa ("IPVS: Extend protocol DNAT/SNAT and state handlers") +Signed-off-by: Julian Anastasov +Signed-off-by: Florian Westphal +Signed-off-by: Nazar Kalashnikov +Signed-off-by: Greg Kroah-Hartman +--- + net/netfilter/ipvs/ip_vs_proto_sctp.c | 18 ++++++------------ + net/netfilter/ipvs/ip_vs_proto_tcp.c | 21 +++++++-------------- + net/netfilter/ipvs/ip_vs_proto_udp.c | 20 +++++++------------- + 3 files changed, 20 insertions(+), 39 deletions(-) + +--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c ++++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c +@@ -10,7 +10,8 @@ + #include + + static int +-sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp); ++sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int sctphoff); + + static int + sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, +@@ -108,7 +109,7 @@ sctp_snat_handler(struct sk_buff *skb, s + int ret; + + /* Some checks before mangling */ +- if (!sctp_csum_check(cp->af, skb, pp)) ++ if (!sctp_csum_check(cp->af, skb, pp, sctphoff)) + return 0; + + /* Call application helper if needed */ +@@ -156,7 +157,7 @@ sctp_dnat_handler(struct sk_buff *skb, s + int ret; + + /* Some checks before mangling */ +- if (!sctp_csum_check(cp->af, skb, pp)) ++ if (!sctp_csum_check(cp->af, skb, pp, sctphoff)) + return 0; + + /* Call application helper if needed */ +@@ -185,19 +186,12 @@ sctp_dnat_handler(struct sk_buff *skb, s + } + + static int +-sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) ++sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int sctphoff) + { +- unsigned int sctphoff; + struct sctphdr *sh; + __le32 cmp, val; + +-#ifdef CONFIG_IP_VS_IPV6 +- if (af == AF_INET6) +- sctphoff = sizeof(struct ipv6hdr); +- else +-#endif +- sctphoff = ip_hdrlen(skb); +- + sh = (struct sctphdr *)(skb->data + sctphoff); + cmp = sh->checksum; + val = sctp_compute_cksum(skb, sctphoff); +--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c ++++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c +@@ -29,7 +29,8 @@ + #include + + static int +-tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp); ++tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int tcphoff); + + static int + tcp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, +@@ -166,7 +167,7 @@ tcp_snat_handler(struct sk_buff *skb, st + int ret; + + /* Some checks before mangling */ +- if (!tcp_csum_check(cp->af, skb, pp)) ++ if (!tcp_csum_check(cp->af, skb, pp, tcphoff)) + return 0; + + /* Call application helper if needed */ +@@ -244,7 +245,7 @@ tcp_dnat_handler(struct sk_buff *skb, st + int ret; + + /* Some checks before mangling */ +- if (!tcp_csum_check(cp->af, skb, pp)) ++ if (!tcp_csum_check(cp->af, skb, pp, tcphoff)) + return 0; + + /* +@@ -301,17 +302,9 @@ tcp_dnat_handler(struct sk_buff *skb, st + + + static int +-tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) ++tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int tcphoff) + { +- unsigned int tcphoff; +- +-#ifdef CONFIG_IP_VS_IPV6 +- if (af == AF_INET6) +- tcphoff = sizeof(struct ipv6hdr); +- else +-#endif +- tcphoff = ip_hdrlen(skb); +- + switch (skb->ip_summed) { + case CHECKSUM_NONE: + skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0); +@@ -322,7 +315,7 @@ tcp_csum_check(int af, struct sk_buff *s + if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + skb->len - tcphoff, +- ipv6_hdr(skb)->nexthdr, ++ IPPROTO_TCP, + skb->csum)) { + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, + "Failed checksum for"); +--- a/net/netfilter/ipvs/ip_vs_proto_udp.c ++++ b/net/netfilter/ipvs/ip_vs_proto_udp.c +@@ -25,7 +25,8 @@ + #include + + static int +-udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp); ++udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int udphoff); + + static int + udp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, +@@ -155,7 +156,7 @@ udp_snat_handler(struct sk_buff *skb, st + int ret; + + /* Some checks before mangling */ +- if (!udp_csum_check(cp->af, skb, pp)) ++ if (!udp_csum_check(cp->af, skb, pp, udphoff)) + return 0; + + /* +@@ -238,7 +239,7 @@ udp_dnat_handler(struct sk_buff *skb, st + int ret; + + /* Some checks before mangling */ +- if (!udp_csum_check(cp->af, skb, pp)) ++ if (!udp_csum_check(cp->af, skb, pp, udphoff)) + return 0; + + /* +@@ -297,17 +298,10 @@ udp_dnat_handler(struct sk_buff *skb, st + + + static int +-udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) ++udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ++ unsigned int udphoff) + { + struct udphdr _udph, *uh; +- unsigned int udphoff; +- +-#ifdef CONFIG_IP_VS_IPV6 +- if (af == AF_INET6) +- udphoff = sizeof(struct ipv6hdr); +- else +-#endif +- udphoff = ip_hdrlen(skb); + + uh = skb_header_pointer(skb, udphoff, sizeof(_udph), &_udph); + if (uh == NULL) +@@ -325,7 +319,7 @@ udp_csum_check(int af, struct sk_buff *s + if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + skb->len - udphoff, +- ipv6_hdr(skb)->nexthdr, ++ IPPROTO_UDP, + skb->csum)) { + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, + "Failed checksum for"); diff --git a/queue-6.6/series b/queue-6.6/series index 8988e9410f..c825f4a317 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -436,3 +436,4 @@ rdma-umem-fix-kernel-doc-warnings.patch rdma-move-dma-block-iterator-logic-into-dedicated-files.patch rdma-umem-fix-truncation-for-block-sizes-4g.patch net-bonding-fix-use-after-free-in-bond_xmit_broadcast.patch +ipvs-skip-ipv6-extension-headers-for-csum-checks.patch