diff --git a/net/core/sock.c b/net/core/sock.c index 5e711b42898f..d6804685f17f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1452,7 +1452,8 @@ int sock_setsockopt(struct socket *sock, int level, int optname, ret = -EINVAL; break; } - sk->sk_txrehash = (u8)val; + /* Paired with READ_ONCE() in tcp_rtx_synack() */ + WRITE_ONCE(sk->sk_txrehash, (u8)val); break; default: diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 11c06b9db801..e76bf1e9251e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -4092,7 +4092,9 @@ int tcp_rtx_synack(const struct sock *sk, struct request_sock *req) struct flowi fl; int res; - tcp_rsk(req)->txhash = net_tx_rndhash(); + /* Paired with WRITE_ONCE() in sock_setsockopt() */ + if (READ_ONCE(sk->sk_txrehash) == SOCK_TXREHASH_ENABLED) + tcp_rsk(req)->txhash = net_tx_rndhash(); res = af_ops->send_synack(sk, NULL, &fl, req, NULL, TCP_SYNACK_NORMAL, NULL); if (!res) {