From nobody Sat Oct 4 00:32:10 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2F577405A; Fri, 22 Aug 2025 04:56:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755838568; cv=none; b=fr3XEFqU4iVXk/qSykmeJH2IV/xbOLsOokMUX6gS+gR7JevVu3gyOiI0mWBKv/kCaJG75jWh+EetEAmO12DE5n62SOzUxN1RmgywoCYafQzFi4kq6AQoPiEakUSEeWiPpzRJ5StKhaPfDfUUR9MGlCB8iz+JccXHcVarNHc1A/U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755838568; c=relaxed/simple; bh=C0HjdWTfGl+YL75dV+5AtN/89cGtlHQAYQE0uY6HrKo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=P0+PSAAOiATxCtqkVnGuhutGV1OfMlQ+QvmCqWHwLPauRt3+elCMxo/5W2+mZlakrurd5GT2TMbZA0CLfgKSZhpPpzkUxuznjL/Vwmi5FaJP4I938iwE7EXsmSvAO+inpw49atQUiiiwWxTK3QAmMEqVGstA8fYgb8onknSMJDc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=T49yxcaG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="T49yxcaG" Received: by smtp.kernel.org (Postfix) with ESMTPS id 48383C113D0; Fri, 22 Aug 2025 04:56:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1755838568; bh=C0HjdWTfGl+YL75dV+5AtN/89cGtlHQAYQE0uY6HrKo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=T49yxcaGKITVJHsJPYObhtxco0B9wesCsOjwCdlJ/Ok9t0c1nqbaoO01Yl2q0osvI lJ9BcTG76K1tacRUuP70PTmIqGT1D4CrM7wTvoTbH0R1l8uHUDBzVu3HWYaGjxfKYm yJOsL/oc/nowb8pMhLo12BsEzBTkFQCq2y+nouuZZD+OgoduA9+fLfzjovDvumiXni qV2es+U3yOXvPN18BlNDi5MHe4Wt1QbNxhXt99RQBoWjMZ92YOz7GFc/KhyRS72wJF UsaL2JiJPOYsHAHoKagOuGmW8VKavt1LQ/PsevMOrNBfWV/47YSR4o0y/gdlkKJfIX uknUbvXXtn8IQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 38887CA0EED; Fri, 22 Aug 2025 04:56:08 +0000 (UTC) From: Dmitry Safonov via B4 Relay Date: Fri, 22 Aug 2025 05:55:36 +0100 Subject: [PATCH net-next 1/2] tcp: Destroy TCP-AO, TCP-MD5 keys in .sk_destruct() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250822-b4-tcp-ao-md5-rst-finwait2-v1-1-25825d085dcb@arista.com> References: <20250822-b4-tcp-ao-md5-rst-finwait2-v1-0-25825d085dcb@arista.com> In-Reply-To: <20250822-b4-tcp-ao-md5-rst-finwait2-v1-0-25825d085dcb@arista.com> To: Eric Dumazet , Neal Cardwell , Kuniyuki Iwashima , "David S. Miller" , David Ahern , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: Bob Gilligan , Salam Noureddine , Dmitry Safonov <0x7f454c46@gmail.com>, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Dmitry Safonov X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1755838557; l=6665; i=dima@arista.com; s=20250521; h=from:subject:message-id; bh=HqMPEN35ULZE014Z8tFG1ylMsDxBsN5cdcxh3D93Eec=; b=leTJLkPb0oAxUbaWe8syqJprpZS01zHtTN5Ug86KqiWvg2MrCR9D8ilx/gefqy+42mdvvTHlV bgMWlB6iKCCA8whgMjF5HbNbZMEsJ1szjTSPumKum/lVFf6aCH/4rxv X-Developer-Key: i=dima@arista.com; a=ed25519; pk=/z94x2T59rICwjRqYvDsBe0MkpbkkdYrSW2J1G2gIcU= X-Endpoint-Received: by B4 Relay for dima@arista.com/20250521 with auth_id=405 X-Original-From: Dmitry Safonov Reply-To: dima@arista.com From: Dmitry Safonov Currently there are a couple of minor issues with destroying the keys tcp_v4_destroy_sock(): 1. The socket is yet in TCP bind buckets, making it reachable for incoming segments [on another CPU core], potentially available to send late FIN/ACK/RST replies. 2. There is at least one code path, where tcp_done() is called before sending RST [kudos to Bob for investigation]. This is a case of a server, that finished sending its data and just called close(). The socket is in TCP_FIN_WAIT2 and has RCV_SHUTDOWN (set by __tcp_close()) tcp_v4_do_rcv()/tcp_v6_do_rcv() tcp_rcv_state_process() /* LINUX_MIB_TCPABORTONDATA */ tcp_reset() tcp_done_with_error() tcp_done() inet_csk_destroy_sock() /* Destroys AO/MD5 keys */ /* tcp_rcv_state_process() returns SKB_DROP_REASON_TCP_ABORT_ON_DATA */ tcp_v4_send_reset() /* Sends an unsigned RST segment */ tcpdump: > 22:53:15.399377 00:00:b2:1f:00:00 > 00:00:01:01:00:00, ethertype IPv4 (0x= 0800), length 74: (tos 0x0, ttl 64, id 33929, offset 0, flags [DF], proto T= CP (6), length 60) > 1.0.0.1.34567 > 1.0.0.2.49848: Flags [F.], seq 2185658590, ack 396964= 4355, win 502, options [nop,nop,md5 valid], length 0 > 22:53:15.399396 00:00:01:01:00:00 > 00:00:b2:1f:00:00, ethertype IPv4 (0x= 0800), length 86: (tos 0x0, ttl 64, id 51951, offset 0, flags [DF], proto T= CP (6), length 72) > 1.0.0.2.49848 > 1.0.0.1.34567: Flags [.], seq 3969644375, ack 2185658= 591, win 128, options [nop,nop,md5 valid,nop,nop,sack 1 {2185658590:2185658= 591}], length 0 > 22:53:16.429588 00:00:b2:1f:00:00 > 00:00:01:01:00:00, ethertype IPv4 (0x= 0800), length 60: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (= 6), length 40) > 1.0.0.1.34567 > 1.0.0.2.49848: Flags [R], seq 2185658590, win 0, leng= th 0 > 22:53:16.664725 00:00:b2:1f:00:00 > 00:00:01:01:00:00, ethertype IPv4 (0x= 0800), length 74: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (= 6), length 60) > 1.0.0.1.34567 > 1.0.0.2.49848: Flags [R], seq 2185658591, win 0, opti= ons [nop,nop,md5 valid], length 0 > 22:53:17.289832 00:00:b2:1f:00:00 > 00:00:01:01:00:00, ethertype IPv4 (0x= 0800), length 74: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (= 6), length 60) > 1.0.0.1.34567 > 1.0.0.2.49848: Flags [R], seq 2185658591, win 0, opti= ons [nop,nop,md5 valid], length 0 Note the signed RSTs later in the dump - those are sent by the server when the fin-wait socket gets removed from hash buckets, by the listener socket. Instead of destroying AO/MD5 info and their keys in inet_csk_destroy_sock(), slightly delay it until the actual socket .sk_destruct(). As shutdown'ed socket can yet send non-data replies, they should be signed in order for the peer to process them. Now it also matches how AO/MD5 gets destructed for TIME-WAIT sockets (in tcp_twsk_destructor()). This seems optimal for TCP-MD5, while for TCP-AO it seems to have an open problem: once RST get sent and socket gets actually destructed, there is no information on the initial sequence numbers. So, in case this last RST gets lost in the network, the server's listener socket won't be able to properly sign another RST. Nothing in RFC 1122 prescribes keeping any local state after non-graceful reset. Luckily, BGP are known to use keep alive(s). While the issue is quite minor/cosmetic, these days monitoring network counters is a common practice and getting invalid signed segments from a trusted BGP peer can get customers worried. Investigated-by: Bob Gilligan Signed-off-by: Dmitry Safonov --- net/ipv4/tcp.c | 31 +++++++++++++++++++++++++++++++ net/ipv4/tcp_ipv4.c | 25 ------------------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 71a956fbfc5533224ee00e792de2cfdccd4d40aa..4e996e937e8e5f0e75764caa242= 40e25006deece 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -412,6 +412,36 @@ static u64 tcp_compute_delivery_rate(const struct tcp_= sock *tp) return rate64; } =20 +#ifdef CONFIG_TCP_MD5SIG +static void tcp_md5sig_info_free_rcu(struct rcu_head *head) +{ + struct tcp_md5sig_info *md5sig; + + md5sig =3D container_of(head, struct tcp_md5sig_info, rcu); + kfree(md5sig); + static_branch_slow_dec_deferred(&tcp_md5_needed); + tcp_md5_release_sigpool(); +} +#endif + +static void tcp_destruct_sock(struct sock *sk) +{ + struct tcp_sock *tp =3D tcp_sk(sk); + +#ifdef CONFIG_TCP_MD5SIG + if (tp->md5sig_info) { + struct tcp_md5sig_info *md5sig; + + md5sig =3D rcu_dereference_protected(tp->md5sig_info, 1); + tcp_clear_md5_list(sk); + call_rcu(&md5sig->rcu, tcp_md5sig_info_free_rcu); + rcu_assign_pointer(tp->md5sig_info, NULL); + } +#endif + tcp_ao_destroy_sock(sk, false); + inet_sock_destruct(sk); +} + /* Address-family independent initialization for a tcp_sock. * * NOTE: A lot of things set to zero explicitly by call to @@ -464,6 +494,7 @@ void tcp_init_sock(struct sock *sk) tp->tsoffset =3D 0; tp->rack.reo_wnd_steps =3D 1; =20 + sk->sk_destruct =3D tcp_destruct_sock; sk->sk_write_space =3D sk_stream_write_space; sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); =20 diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 84d3d556ed8062d07fe7019bc0dadd90d3b80d96..32814f205fdfdcbd4be4765a4e1= 27c8f175d3b14 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2521,18 +2521,6 @@ static int tcp_v4_init_sock(struct sock *sk) return 0; } =20 -#ifdef CONFIG_TCP_MD5SIG -static void tcp_md5sig_info_free_rcu(struct rcu_head *head) -{ - struct tcp_md5sig_info *md5sig; - - md5sig =3D container_of(head, struct tcp_md5sig_info, rcu); - kfree(md5sig); - static_branch_slow_dec_deferred(&tcp_md5_needed); - tcp_md5_release_sigpool(); -} -#endif - static void tcp_release_user_frags(struct sock *sk) { #ifdef CONFIG_PAGE_POOL @@ -2569,19 +2557,6 @@ void tcp_v4_destroy_sock(struct sock *sk) /* Cleans up our, hopefully empty, out_of_order_queue. */ skb_rbtree_purge(&tp->out_of_order_queue); =20 -#ifdef CONFIG_TCP_MD5SIG - /* Clean up the MD5 key list, if any */ - if (tp->md5sig_info) { - struct tcp_md5sig_info *md5sig; - - md5sig =3D rcu_dereference_protected(tp->md5sig_info, 1); - tcp_clear_md5_list(sk); - call_rcu(&md5sig->rcu, tcp_md5sig_info_free_rcu); - rcu_assign_pointer(tp->md5sig_info, NULL); - } -#endif - tcp_ao_destroy_sock(sk, false); - /* Clean up a referenced TCP bind bucket. */ if (inet_csk(sk)->icsk_bind_hash) inet_put_port(sk); --=20 2.42.2 From nobody Sat Oct 4 00:32:10 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4718275B0D; Fri, 22 Aug 2025 04:56:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755838569; cv=none; b=tRkaN9OfJqzixbbdnlA99s8BFYryfK/A6/RBwkXnMk+gA9AzIgI6QXs3SRLZwRo9rWMLzIFguYioMLrY4B4S3J3j+j1Gb4DrKg9E8XVRJ+PeB0XFx/PxV/oygwdPmDicVpfj4Fain6IRCAu0ViVnwe9bzHohmRpHytSR3Md40F8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755838569; c=relaxed/simple; bh=+WRmkSfQGtmlo9na2It4vpTsg5vAymd2N8s4FQH9ZHE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qJIJL/Z7aG+KKS8ftB5ohsdbR1ZlxTYMc6wTLI9o6QbOUJHgzd2Qu9Uf2q5zYO0EaE6wXIpiXKivLBsFH4GnJ9fRfLxq/2fSQ+VVcivsiSZIHYt+PxAdhIdSHyl+gVGbX4IwLJjcri2uz0KImom/E5OwDpI+58n7Kah12bUkjHM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FYW36a0h; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FYW36a0h" Received: by smtp.kernel.org (Postfix) with ESMTPS id 553FBC116B1; Fri, 22 Aug 2025 04:56:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1755838568; bh=+WRmkSfQGtmlo9na2It4vpTsg5vAymd2N8s4FQH9ZHE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=FYW36a0hVe/L1EObW2wNr+Kb+a4bx4yDsUD423cKa0KLTdfXOuo3O+pRpoXJUVnzQ 42JYpIJlgYHpqtU1R1JSTr+k1EvFYMX7DdZvfBCdVlSP8HkodO0h3+YqBR12P1bbSo MoNp8Wk+IL2kGKDPNsKM4WFbIK1m0OmHhwEuxYl58ryhbyl7BssIJRQT1OD6e7TNoX QPoBMipd1i/FKs8PLgV2EbyUcAJszhhKTnmw+tXLJpqpVMRIqZguHc4h66671xMNWb 3jMJ4uoCZ3jhfEYBHJ+zlWkJYa505+UvJjW6/gaYweFjtqLOWc0cO8VIkO0nRxNRqy YNbU+bKooX9Nw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46292CA0EEB; Fri, 22 Aug 2025 04:56:08 +0000 (UTC) From: Dmitry Safonov via B4 Relay Date: Fri, 22 Aug 2025 05:55:37 +0100 Subject: [PATCH net-next 2/2] tcp: Free TCP-AO/TCP-MD5 info/keys without RCU Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250822-b4-tcp-ao-md5-rst-finwait2-v1-2-25825d085dcb@arista.com> References: <20250822-b4-tcp-ao-md5-rst-finwait2-v1-0-25825d085dcb@arista.com> In-Reply-To: <20250822-b4-tcp-ao-md5-rst-finwait2-v1-0-25825d085dcb@arista.com> To: Eric Dumazet , Neal Cardwell , Kuniyuki Iwashima , "David S. Miller" , David Ahern , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: Bob Gilligan , Salam Noureddine , Dmitry Safonov <0x7f454c46@gmail.com>, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Dmitry Safonov X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1755838557; l=4311; i=dima@arista.com; s=20250521; h=from:subject:message-id; bh=DTvDhQjie0nLc2vujkcuQmUlaLvJCsq+rW5VIp5uDdU=; b=BksfMbbtCwVQpxUCwvcI29WnXVacYK7bsGtS784QxTI5NoztdZ6jGs5sdQenKaqOmqV1hBK1B xs8S/UcQKpBAm7GEE849O6RzG06SBL1NeAXCVnca3CXCy9WSVGTr76k X-Developer-Key: i=dima@arista.com; a=ed25519; pk=/z94x2T59rICwjRqYvDsBe0MkpbkkdYrSW2J1G2gIcU= X-Endpoint-Received: by B4 Relay for dima@arista.com/20250521 with auth_id=405 X-Original-From: Dmitry Safonov Reply-To: dima@arista.com From: Dmitry Safonov Now that the destruction of info/keys is delayed until the socket destructor, it's safe to use kfree() without an RCU callback. As either socket was yet in TCP_CLOSE state or the socket refcounter is zero and no one can discover it anymore, it's safe to release memory straight away. Similar thing was possible for twsk already. Signed-off-by: Dmitry Safonov --- net/ipv4/tcp.c | 19 +++---------------- net/ipv4/tcp_ao.c | 5 ++--- net/ipv4/tcp_ipv4.c | 4 ++-- net/ipv4/tcp_minisocks.c | 19 +++++-------------- 4 files changed, 12 insertions(+), 35 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 4e996e937e8e5f0e75764caa24240e25006deece..de10d38116a205863c290470fa0= cbbddeb8d709e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -412,30 +412,17 @@ static u64 tcp_compute_delivery_rate(const struct tcp= _sock *tp) return rate64; } =20 -#ifdef CONFIG_TCP_MD5SIG -static void tcp_md5sig_info_free_rcu(struct rcu_head *head) -{ - struct tcp_md5sig_info *md5sig; - - md5sig =3D container_of(head, struct tcp_md5sig_info, rcu); - kfree(md5sig); - static_branch_slow_dec_deferred(&tcp_md5_needed); - tcp_md5_release_sigpool(); -} -#endif - static void tcp_destruct_sock(struct sock *sk) { struct tcp_sock *tp =3D tcp_sk(sk); =20 #ifdef CONFIG_TCP_MD5SIG if (tp->md5sig_info) { - struct tcp_md5sig_info *md5sig; =20 - md5sig =3D rcu_dereference_protected(tp->md5sig_info, 1); tcp_clear_md5_list(sk); - call_rcu(&md5sig->rcu, tcp_md5sig_info_free_rcu); - rcu_assign_pointer(tp->md5sig_info, NULL); + kfree(rcu_replace_pointer(tp->md5sig_info, NULL, 1)); + static_branch_slow_dec_deferred(&tcp_md5_needed); + tcp_md5_release_sigpool(); } #endif tcp_ao_destroy_sock(sk, false); diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c index bbb8d5f0eae7d3d8887da3fa4d68e248af9060ad..31302be78bc4450b56fa23a390b= 6d03b2262741d 100644 --- a/net/ipv4/tcp_ao.c +++ b/net/ipv4/tcp_ao.c @@ -268,9 +268,8 @@ static void tcp_ao_key_free_rcu(struct rcu_head *head) kfree_sensitive(key); } =20 -static void tcp_ao_info_free_rcu(struct rcu_head *head) +static void tcp_ao_info_free(struct tcp_ao_info *ao) { - struct tcp_ao_info *ao =3D container_of(head, struct tcp_ao_info, rcu); struct tcp_ao_key *key; struct hlist_node *n; =20 @@ -310,7 +309,7 @@ void tcp_ao_destroy_sock(struct sock *sk, bool twsk) =20 if (!twsk) tcp_ao_sk_omem_free(sk, ao); - call_rcu(&ao->rcu, tcp_ao_info_free_rcu); + tcp_ao_info_free(ao); } =20 void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw, struct tcp_sock *tp) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 32814f205fdfdcbd4be4765a4e127c8f175d3b14..185d16ff2d0ad7b20e2404ceff7= 1cccaff4ed4bc 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1505,9 +1505,9 @@ void tcp_clear_md5_list(struct sock *sk) md5sig =3D rcu_dereference_protected(tp->md5sig_info, 1); =20 hlist_for_each_entry_safe(key, n, &md5sig->head, node) { - hlist_del_rcu(&key->node); + hlist_del(&key->node); atomic_sub(sizeof(*key), &sk->sk_omem_alloc); - kfree_rcu(key, rcu); + kfree(key); } } =20 diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 2994c9222c9cb5ee86b60bdb553f92130e52c70e..c93812b19893742b071b0f7a49c= 4293a781e8de4 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -377,26 +377,17 @@ void tcp_time_wait(struct sock *sk, int state, int ti= meo) } EXPORT_SYMBOL(tcp_time_wait); =20 -#ifdef CONFIG_TCP_MD5SIG -static void tcp_md5_twsk_free_rcu(struct rcu_head *head) -{ - struct tcp_md5sig_key *key; - - key =3D container_of(head, struct tcp_md5sig_key, rcu); - kfree(key); - static_branch_slow_dec_deferred(&tcp_md5_needed); - tcp_md5_release_sigpool(); -} -#endif - void tcp_twsk_destructor(struct sock *sk) { #ifdef CONFIG_TCP_MD5SIG if (static_branch_unlikely(&tcp_md5_needed.key)) { struct tcp_timewait_sock *twsk =3D tcp_twsk(sk); =20 - if (twsk->tw_md5_key) - call_rcu(&twsk->tw_md5_key->rcu, tcp_md5_twsk_free_rcu); + if (twsk->tw_md5_key) { + kfree(twsk->tw_md5_key); + static_branch_slow_dec_deferred(&tcp_md5_needed); + tcp_md5_release_sigpool(); + } } #endif tcp_ao_destroy_sock(sk, true); --=20 2.42.2