ipvs: fix more places with wrong ipv6 transport offsets

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: d12e12299a ("ipvs: add ipv6 support to ftp")
Fixes: 2a3b791e6e ("IPVS: Add/adjust Netfilter hook functions and helpers for v6")
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260706101624.69471-1-zhaoyz24%40mails.tsinghua.edu.cn
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Florian Westphal <fw@strlen.de>
This commit is contained in:
Julian Anastasov 2026-07-08 21:03:15 +03:00 committed by Florian Westphal
parent a2f57827bf
commit b3fe4cbd58
2 changed files with 5 additions and 8 deletions

View File

@ -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

View File

@ -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