]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
tcp/dccp: add tw->tw_bslot
authorEric Dumazet <edumazet@google.com>
Mon, 24 Jan 2022 20:24:52 +0000 (12:24 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 25 Jan 2022 11:25:21 +0000 (11:25 +0000)
We want to allow inet_twsk_kill() working even if netns
has been dismantled/freed, to get rid of inet_twsk_purge().

This patch adds tw->tw_bslot to cache the bind bucket slot
so that inet_twsk_kill() no longer needs to dereference twsk_net(tw)

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/inet_timewait_sock.h
net/ipv4/inet_timewait_sock.c

index dfd919b3119e8efcbc436a67e3e6fbd02091db10..c221fe2b77dd24d8e0d13db9819cdf3ac13fe742 100644 (file)
@@ -72,6 +72,7 @@ struct inet_timewait_sock {
                                tw_tos          : 8;
        u32                     tw_txhash;
        u32                     tw_priority;
+       u32                     tw_bslot; /* bind bucket slot */
        struct timer_list       tw_timer;
        struct inet_bind_bucket *tw_tb;
 };
index 437afe392e667c7c54509920d1e624f759f9215b..6e8f4a6cd222e89b1c7f9fdd73b10d336ff026a1 100644 (file)
@@ -52,8 +52,7 @@ static void inet_twsk_kill(struct inet_timewait_sock *tw)
        spin_unlock(lock);
 
        /* Disassociate with bind bucket. */
-       bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), tw->tw_num,
-                       hashinfo->bhash_size)];
+       bhead = &hashinfo->bhash[tw->tw_bslot];
 
        spin_lock(&bhead->lock);
        inet_twsk_bind_unhash(tw, hashinfo);
@@ -110,8 +109,12 @@ void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
           Note, that any socket with inet->num != 0 MUST be bound in
           binding cache, even if it is closed.
         */
-       bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), inet->inet_num,
-                       hashinfo->bhash_size)];
+       /* Cache inet_bhashfn(), because 'struct net' might be no longer
+        * available later in inet_twsk_kill().
+        */
+       tw->tw_bslot = inet_bhashfn(twsk_net(tw), inet->inet_num,
+                                   hashinfo->bhash_size);
+       bhead = &hashinfo->bhash[tw->tw_bslot];
        spin_lock(&bhead->lock);
        tw->tw_tb = icsk->icsk_bind_hash;
        WARN_ON(!icsk->icsk_bind_hash);