From: Julian Anastasov <ja@ssi.bg>
To: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Cc: netdev@vger.kernel.org, Simon Horman <horms@verge.net.au>,
Pablo Neira Ayuso <pablo@netfilter.org>,
Florian Westphal <fw@strlen.de>, Phil Sutter <phil@nwl.cc>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
lvs-devel@vger.kernel.org, netfilter-devel@vger.kernel.org,
coreteam@netfilter.org, linux-kernel@vger.kernel.org,
Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>,
Ao Wang <wangao@seu.edu.cn>, Xuewei Feng <fengxw06@126.com>,
Qi Li <qli01@tsinghua.edu.cn>, Ke Xu <xuke@tsinghua.edu.cn>,
stable@vger.kernel.org
Subject: Re: [PATCH nf] ipvs: skip IPv6 extension headers in SCTP state lookup
Date: Sun, 5 Jul 2026 20:35:00 +0300 (EEST) [thread overview]
Message-ID: <92783c87-7e6a-e90a-b2fc-e5d1332139e0@ssi.bg> (raw)
In-Reply-To: <20260705123040.35755-1-zhaoyz24@mails.tsinghua.edu.cn>
Hello,
On Sun, 5 Jul 2026, Yizhou Zhao wrote:
> set_sctp_state() reads the SCTP chunk header again in order to drive the
> IPVS SCTP state table. For IPv6 it computes the offset with
> sizeof(struct ipv6hdr), while the surrounding IPVS code uses iph->len from
> ip_vs_fill_iph_skb(), where ipv6_find_hdr() has already skipped extension
> headers and found the real transport header.
>
> This makes the state machine read from the wrong offset for IPv6 SCTP
> packets that carry extension headers. For example, an INIT packet with an
> 8-byte destination options header can be scheduled correctly by
> sctp_conn_schedule(), but set_sctp_state() reads the first byte of the SCTP
> verification tag as a DATA chunk type. The connection then moves from NONE
> to ESTABLISHED instead of INIT1, gets the longer established timeout, and
> updates the active/inactive destination counters incorrectly. This happens
> even though the SCTP handshake has not completed.
>
> Use ip_vs_fill_iph_skb() in set_sctp_state() and base the chunk-header
> offset on iph.len, matching sctp_conn_schedule() and the SCTP NAT handlers.
> For IPv4 and IPv6 packets without extension headers this preserves the
> existing offset.
>
> Fixes: 2906f66a5682 ("ipvs: SCTP Trasport Loadbalancing Support")
> Cc: stable@vger.kernel.org
> 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>
> ---
> net/netfilter/ipvs/ip_vs_proto_sctp.c | 12 +++++-------
> 1 file changed, 5 insertions(+), 7 deletions(-)
>
> diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
> index 63c78a1f3918..6e0fc23be305 100644
> --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
> +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
> @@ -375,17 +375,15 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
> int direction, const struct sk_buff *skb)
> {
> struct sctp_chunkhdr _sctpch, *sch;
> unsigned char chunk_type;
> + struct ip_vs_iphdr iph;
> int event, next_state;
> - int ihl, cofs;
> + int cofs;
>
> -#ifdef CONFIG_IP_VS_IPV6
> - ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
> -#else
> - ihl = ip_hdrlen(skb);
> -#endif
> + if (!ip_vs_fill_iph_skb(cp->af, skb, false, &iph))
> + return;
May be it is better starting from ip_vs_set_state()
to provide new arg 'int iph_len/offset' (set to iph.len), down to
state_transition(), sctp_state_transition() and set_sctp_state().
Same for all protos. It should cost less stack and ipv6_find_hdr()
calls and what matters most, correct iph context in case we
have IP+ICMP+TCP (with just two ports or even with TCP flags)
and are scheduling ICMP, i.e. not IP+TCP as usually.
But what I see is that ip_vs_in_icmp*() are missing
the ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pd) call just
after ip_vs_in_stats() and before ip_vs_icmp_xmit() where
we should provide ciph.len. That is why we don't reach the
set_tcp_state() calls to set correct cp->state and timeout
when scheduling related ICMP. So, this should be fixed too.
> - cofs = ihl + sizeof(struct sctphdr);
> + cofs = iph.len + sizeof(struct sctphdr);
> sch = skb_header_pointer(skb, cofs, sizeof(_sctpch), &_sctpch);
> if (sch == NULL)
> return;
> --
> 2.47.3
Regards
--
Julian Anastasov <ja@ssi.bg>
next prev parent reply other threads:[~2026-07-05 17:35 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-05 12:30 [PATCH nf] ipvs: skip IPv6 extension headers in SCTP state lookup Yizhou Zhao
2026-07-05 17:35 ` Julian Anastasov [this message]
2026-07-06 8:22 ` Yizhou Zhao
2026-07-06 14:17 ` Julian Anastasov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=92783c87-7e6a-e90a-b2fc-e5d1332139e0@ssi.bg \
--to=ja@ssi.bg \
--cc=coreteam@netfilter.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=fengxw06@126.com \
--cc=fw@strlen.de \
--cc=horms@verge.net.au \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lvs-devel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pablo@netfilter.org \
--cc=phil@nwl.cc \
--cc=qli01@tsinghua.edu.cn \
--cc=stable@vger.kernel.org \
--cc=wangao@seu.edu.cn \
--cc=xuke@tsinghua.edu.cn \
--cc=yangyx22@mails.tsinghua.edu.cn \
--cc=zhaoyz24@mails.tsinghua.edu.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox