Hi Julian,

> On Jul 6, 2026, at 22:17, Julian Anastasov <[email protected]> wrote:
> 
> 
> Hello,
> 
> On Mon, 6 Jul 2026, Yizhou Zhao wrote:
> 
>>> On Jul 6, 2026, at 01:35, Julian Anastasov <[email protected]> wrote:
>>> 
>>> 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.
>> 
>> I agree that the already parsed transport-header offset should be 
>> passed from ip_vs_set_state() down to the protocol state_transition() 
>> callbacks, instead of reparsing the skb in set_sctp_state(). We will 
>> send a v2 that does this for SCTP, TCP and the other IPVS protocols 
>> in one combined fix.
>> 
>>> 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.
>> 
>> For the ICMP path, I agree that the missing ip_vs_set_state() call is
>> worth looking at, but using ICMP errors to drive the upper L4 state 
>> needs some care, because spoofed ICMP packets can match an 
>> existing embedded tuple before the endpoint TCP/SCTP stack 
>> performs its own validation. Maybe this change needs further
>> discussion?
> 
> May be only for the schedule_icmp case while the other
> ICMP replies should not change it:
> 
> diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> index 7f93239898ff..05fdcf4ce2c0 100644
> --- a/net/netfilter/ipvs/ip_vs_core.c
> +++ b/net/netfilter/ipvs/ip_vs_core.c
> @@ -1971,6 +1971,8 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff 
> *skb, int *related,
> 
> /* do the statistics and put it back */
> ip_vs_in_stats(cp, skb);
> + if (new_cp)
> + ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pd, offset);
> if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol ||
>    IPPROTO_SCTP == cih->protocol)
> offset += 2 * sizeof(__u16);
> 
> Here is why schedule_icmp was added:
> 
> https://archive.linuxvirtualserver.org/html/lvs-devel/2015-08/msg00015.html
> 
> But the inner TCP header should be generated by the
> real server, not from the client, so things can go wrong. We can
> leave it as it is now - we will forward the ICMP to the right real 
> server by using short conn timeout...

I agree. The embedded TCP/SCTP header in this path may not have the same
meaning as a normal client packet reaching the virtual service, so I do not
see a good fix for the ICMP state update part at the moment.

BTW, we have kept the ICMP handling unchanged and submitted a v2 series
for the parsed transport-offset issue only, following your earlier suggestion
to pass the already parsed offset from ip_vs_set_state() down to the protocol
state handlers. The v2 also puts the TCP and SCTP fixes in the same thread:

https://lore.kernel.org/netdev/[email protected]/

Thanks for the review.

> 
> Regards
> 
> --
> Julian Anastasov <[email protected]>

Thanks,
Yizhou

Reply via email to