LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

[PATCH nf] ipvs: fix more places with wrong ipv6 transport offsets

To: Simon Horman <horms@xxxxxxxxxxxx>
Subject: [PATCH nf] ipvs: fix more places with wrong ipv6 transport offsets
Cc: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>, Florian Westphal <fw@xxxxxxxxx>, lvs-devel@xxxxxxxxxxxxxxx, netfilter-devel@xxxxxxxxxxxxxxx
From: Julian Anastasov <ja@xxxxxx>
Date: Wed, 8 Jul 2026 21:03:15 +0300
Sashiko reports for more incorrect IPv6 transport offsets.

The app code for TCP was assuming IPv4 network header
even after the ipvsh argument was provided. This can
cause problems with apps over IPv6. As for the only
official app in the kernel tree (FTP) this problem is
harmless because we use Netfilter to mangle the FTP
ports and we do not adjust the TCP seq numbers.

Also, provide correct offset of the ICMPV6 header in
ip_vs_out_icmp_v6() for correct checksum checks when
the IPv6 packet has extension headers.

Fixes: d12e12299a69 ("ipvs: add ipv6 support to ftp")
Fixes: 2a3b791e6e11 ("IPVS: Add/adjust Netfilter hook functions and helpers for 
v6")
Link: 
https://sashiko.dev/#/patchset/20260706101624.69471-1-zhaoyz24%40mails.tsinghua.edu.cn
Signed-off-by: Julian Anastasov <ja@xxxxxx>
---
 net/netfilter/ipvs/ip_vs_app.c  | 10 ++++------
 net/netfilter/ipvs/ip_vs_core.c |  3 +--
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index d54d7da58334..b0e00be85cb1 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -361,14 +361,13 @@ static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, 
struct sk_buff *skb,
                                  struct ip_vs_iphdr *ipvsh)
 {
        int diff;
-       const unsigned int tcp_offset = ip_hdrlen(skb);
        struct tcphdr *th;
        __u32 seq;
 
-       if (skb_ensure_writable(skb, tcp_offset + sizeof(*th)))
+       if (skb_ensure_writable(skb, ipvsh->len + sizeof(*th)))
                return 0;
 
-       th = (struct tcphdr *)(skb_network_header(skb) + tcp_offset);
+       th = (struct tcphdr *)(skb_network_header(skb) + ipvsh->len);
 
        /*
         *      Remember seq number in case this pkt gets resized
@@ -438,14 +437,13 @@ static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, 
struct sk_buff *skb,
                                 struct ip_vs_iphdr *ipvsh)
 {
        int diff;
-       const unsigned int tcp_offset = ip_hdrlen(skb);
        struct tcphdr *th;
        __u32 seq;
 
-       if (skb_ensure_writable(skb, tcp_offset + sizeof(*th)))
+       if (skb_ensure_writable(skb, ipvsh->len + sizeof(*th)))
                return 0;
 
-       th = (struct tcphdr *)(skb_network_header(skb) + tcp_offset);
+       th = (struct tcphdr *)(skb_network_header(skb) + ipvsh->len);
 
        /*
         *      Remember seq number in case this pkt gets resized
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 5b427349a257..c9c88c99d07b 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1219,8 +1219,7 @@ static int ip_vs_out_icmp_v6(struct netns_ipvs *ipvs, 
struct sk_buff *skb,
        snet.in6 = ciph.saddr.in6;
        offset = ciph.len;
        return handle_response_icmp(AF_INET6, skb, &snet, ciph.protocol, cp,
-                                   pp, offset, sizeof(struct ipv6hdr),
-                                   hooknum);
+                                   pp, offset, ipvsh->len, hooknum);
 }
 #endif
 
-- 
2.55.0




<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH nf] ipvs: fix more places with wrong ipv6 transport offsets, Julian Anastasov <=