]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ipvs: use parsed transport offset in TCP state lookup
authorYizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Mon, 6 Jul 2026 10:16:23 +0000 (18:16 +0800)
committerFlorian Westphal <fw@strlen.de>
Wed, 8 Jul 2026 13:33:44 +0000 (15:33 +0200)
TCP state handling reparses the skb to find the TCP header. For IPv6 it
uses sizeof(struct ipv6hdr), while the surrounding IPVS code already
parsed the packet with ip_vs_fill_iph_skb() and has the real
transport-header offset in iph.len.

This makes TCP state handling look at the wrong bytes when an IPv6
packet carries extension headers. Use the parsed transport offset passed
down from ip_vs_set_state() when reading the TCP header.

For IPv4 and for IPv6 packets without extension headers, the passed
offset matches the previous value.

Fixes: 0bbdd42b7efa6 ("IPVS: Extend protocol DNAT/SNAT and state handlers")
Link: https://lore.kernel.org/netdev/20260705125659.37744-1-zhaoyz24@mails.tsinghua.edu.cn/
Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
Reported-by: Ao Wang <wangao@seu.edu.cn>
Reported-by: Xuewei Feng <fengxw06@126.com>
Reported-by: Qi Li <qli01@tsinghua.edu.cn>
Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
Assisted-by: Claude Code:GLM-5.2
Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/ipvs/ip_vs_proto_tcp.c

index 2d3f6aeafe522d35219eaf628ec77e3e3c89e8e8..f86b763efcc4dc12e1a294e35ca3986be5fad229 100644 (file)
@@ -584,13 +584,7 @@ tcp_state_transition(struct ip_vs_conn *cp, int direction,
 {
        struct tcphdr _tcph, *th;
 
-#ifdef CONFIG_IP_VS_IPV6
-       int ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
-#else
-       int ihl = ip_hdrlen(skb);
-#endif
-
-       th = skb_header_pointer(skb, ihl, sizeof(_tcph), &_tcph);
+       th = skb_header_pointer(skb, iph_len, sizeof(_tcph), &_tcph);
        if (th == NULL)
                return;