> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> index de9f68a9c0cf..3b6565a53b96 100644
> --- a/net/ipv4/tcp_input.c
> +++ b/net/ipv4/tcp_input.c

[ ... ]

> @@ -7633,6 +7635,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
>       tcp_rsk(req)->af_specific = af_ops;
>       tcp_rsk(req)->ts_off = 0;
>       tcp_rsk(req)->req_usec_ts = false;
> +     tcp_rsk(req)->txhash = net_tx_rndhash();

[ ... ]

> @@ -7656,7 +7659,12 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
>       /* Note: tcp_v6_init_req() might override ir_iif for link locals */
>       inet_rsk(req)->ir_iif = inet_request_bound_dev_if(sk, skb);
>
> -     dst = af_ops->route_req(sk, skb, &fl, req, isn);
> +     if (want_cookie) {
> +             isn = cookie_init_sequence(af_ops, skb, &req->mss);
> +             tcp_rsk(req)->txhash = isn;
> +     }

Should this txhash assignment be guarded so it only applies to IPv6?

For the want_cookie path here, isn is the SYN cookie.  For IPv4 that
cookie comes from __cookie_v4_init_sequence() -> secure_tcp_syn_cookie(),
whose low bits encode the mss index (mssind).  tcp_make_synack() then
does:

net/ipv4/tcp_output.c:tcp_make_synack()
        skb_set_hash(skb, READ_ONCE(tcp_rsk(req)->txhash),
                     PKT_HASH_TYPE_L4);

so for IPv4 the SYN-ACK skb->hash becomes the mssind-biased cookie value
instead of the uniformly-random net_tx_rndhash() the old code assigned
below.  skb->hash drives TX queue selection (netdev_pick_tx/XPS), so
under an IPv4 SYN flood the SYN-ACK transmit-queue distribution would be
biased by mssind.

This seems to be the same bias the commit message says the v4 path
should avoid:

  IPv4 sockets retain net_tx_rndhash() since IPv4 ECMP does not use
  sk_txhash and the v4 cookie has mssind bits that would bias queue
  distribution.

That net_tx_rndhash() guard was applied in cookie_tcp_reqsk_init() (the
full-socket path), but the parallel assignment here in tcp_conn_request()
is not guarded by sk_family / AF_INET6.  For IPv6 the cookie-as-txhash
looks intentional (it keeps the SYN-ACK on the same ECMP path that
cookie_v6_check() later picks), so only the IPv4 case appears affected.

> +
> +     dst = af_ops->route_req(sk, skb, &fl, req, want_cookie ? 0 : isn);
>       if (!dst)
>               goto drop_and_free;
>

[ ... ]

> @@ -7714,7 +7722,6 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
>       }
>  #endif
>       tcp_rsk(req)->snt_isn = isn;
> -     tcp_rsk(req)->txhash = net_tx_rndhash();
>       tcp_rsk(req)->syn_tos = TCP_SKB_CB(skb)->ip_dsfield;


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/26839485409

Reply via email to