On Tue, May 19, 2026 at 11:43 PM Neil Spring <[email protected]> wrote:
>
> Currently sk_rethink_txhash() re-rolls the socket's txhash on RTO, PLB,
> and spurious-retransmission events, but the cached route is reused and
> the new hash is not propagated into the ECMP path selection logic. Two
> changes are needed to make rehash select a different local ECMP path:
>
...
>
> Signed-off-by: Neil Spring <[email protected]>
> ---
> net/core/filter.c | 1 +
> net/ipv4/tcp_input.c | 6 ++++--
> net/ipv4/tcp_plb.c | 7 ++++++-
> net/ipv4/tcp_timer.c | 4 ++++
> net/ipv6/af_inet6.c | 3 +++
> net/ipv6/inet6_connection_sock.c | 7 +++++++
> net/ipv6/syncookies.c | 4 ++++
> net/ipv6/tcp_ipv6.c | 13 +++++++++++--
> 8 files changed, 40 insertions(+), 5 deletions(-)
>
>
...
> diff --git a/net/ipv4/tcp_plb.c b/net/ipv4/tcp_plb.c
> index c11a0cd3f8fe..accdd83dfc3d 100644
> --- a/net/ipv4/tcp_plb.c
> +++ b/net/ipv4/tcp_plb.c
> @@ -78,7 +78,12 @@ void tcp_plb_check_rehash(struct sock *sk, struct
> tcp_plb_state *plb)
> if (plb->pause_until)
> return;
>
> - sk_rethink_txhash(sk);
> + if (sk_rethink_txhash(sk)) {
> +#if IS_ENABLED(CONFIG_IPV6)
Please remove the #if IS_ENABLED(CONFIG_IPV6).
Code will compile just fine if IPV6 is not enabled, and is not
ultra-fast-path anyway.
if (sk_rethink_txhash(sk) && sk->sk_family == AF_INET6)
__sk_dst_reset(sk);
> + if (sk->sk_family == AF_INET6)
> + __sk_dst_reset(sk);
> +#endif
> + }
> plb->consec_cong_rounds = 0;
> WRITE_ONCE(tcp_sk(sk)->plb_rehash, tcp_sk(sk)->plb_rehash + 1);
> NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPPLBREHASH);
> diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
> index 322db13333c7..24c1c19eda6e 100644
> --- a/net/ipv4/tcp_timer.c
> +++ b/net/ipv4/tcp_timer.c
> @@ -300,6 +300,10 @@ static int tcp_write_timeout(struct sock *sk)
> if (sk_rethink_txhash(sk)) {
> WRITE_ONCE(tp->timeout_rehash, tp->timeout_rehash + 1);
> __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEOUTREHASH);
> +#if IS_ENABLED(CONFIG_IPV6)
Same remark here.
> + if (sk->sk_family == AF_INET6)
> + __sk_dst_reset(sk);
> +#endif
> }
>
> return 0;
>