LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

[PATCH nf v2 2/3] ipvs: use parsed transport offset in TCP state lookup

To: netdev@xxxxxxxxxxxxxxx
Subject: [PATCH nf v2 2/3] ipvs: use parsed transport offset in TCP state lookup
Cc: coreteam@xxxxxxxxxxxxx, davem@xxxxxxxxxxxxx, edumazet@xxxxxxxxxx, fengxw06@xxxxxxx, fw@xxxxxxxxx, horms@xxxxxxxxxxxx, ja@xxxxxx, kuba@xxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx, lvs-devel@xxxxxxxxxxxxxxx, netfilter-devel@xxxxxxxxxxxxxxx, pabeni@xxxxxxxxxx, pablo@xxxxxxxxxxxxx, phil@xxxxxx, qli01@xxxxxxxxxxxxxxx, stable@xxxxxxxxxxxxxxx, wangao@xxxxxxxxxx, xuke@xxxxxxxxxxxxxxx, yangyx22@xxxxxxxxxxxxxxxxxxxxx, Yizhou Zhao <zhaoyz24@xxxxxxxxxxxxxxxxxxxxx>
From: Yizhou Zhao <zhaoyz24@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 6 Jul 2026 18:16:23 +0800
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@xxxxxxxxxxxxxxxxxxxxx/
Reported-by: Yizhou Zhao <zhaoyz24@xxxxxxxxxxxxxxxxxxxxx>
Reported-by: Yuxiang Yang <yangyx22@xxxxxxxxxxxxxxxxxxxxx>
Reported-by: Ao Wang <wangao@xxxxxxxxxx>
Reported-by: Xuewei Feng <fengxw06@xxxxxxx>
Reported-by: Qi Li <qli01@xxxxxxxxxxxxxxx>
Reported-by: Ke Xu <xuke@xxxxxxxxxxxxxxx>
Assisted-by: Claude Code:GLM-5.2
Signed-off-by: Yizhou Zhao <zhaoyz24@xxxxxxxxxxxxxxxxxxxxx>
---
 net/netfilter/ipvs/ip_vs_proto_tcp.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c 
b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index 2d3f6aeafe52..f86b763efcc4 100644
--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -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;
 
-- 
2.34.1



<Prev in Thread] Current Thread [Next in Thread>