]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
tcp: Rearrange tests in inet_csk_bind_conflict().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Tue, 19 Dec 2023 00:18:28 +0000 (09:18 +0900)
committerDavid S. Miller <davem@davemloft.net>
Fri, 22 Dec 2023 22:15:35 +0000 (22:15 +0000)
The following patch adds code in the !inet_use_bhash2_on_bind(sk)
case in inet_csk_bind_conflict().

To avoid adding nest and make the change cleaner, this patch
rearranges tests in inet_csk_bind_conflict().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/inet_connection_sock.c

index 8b29056f454dc5f1d2abc00fc682e643790a5930..0b49778b425f0aa80995c556635cc004a8e8ddae 100644 (file)
@@ -242,9 +242,10 @@ static int inet_csk_bind_conflict(const struct sock *sk,
                                  const struct inet_bind2_bucket *tb2, /* may be null */
                                  bool relax, bool reuseport_ok)
 {
-       bool reuseport_cb_ok;
-       struct sock_reuseport *reuseport_cb;
        kuid_t uid = sock_i_uid((struct sock *)sk);
+       struct sock_reuseport *reuseport_cb;
+       bool reuseport_cb_ok;
+       struct sock *sk2;
 
        rcu_read_lock();
        reuseport_cb = rcu_dereference(sk->sk_reuseport_cb);
@@ -252,32 +253,29 @@ static int inet_csk_bind_conflict(const struct sock *sk,
        reuseport_cb_ok = !reuseport_cb || READ_ONCE(reuseport_cb->num_closed_socks);
        rcu_read_unlock();
 
-       /*
-        * Unlike other sk lookup places we do not check
+       /* Conflicts with an existing IPV6_ADDR_ANY (if ipv6) or INADDR_ANY (if
+        * ipv4) should have been checked already. We need to do these two
+        * checks separately because their spinlocks have to be acquired/released
+        * independently of each other, to prevent possible deadlocks
+        */
+       if (inet_use_bhash2_on_bind(sk))
+               return tb2 && inet_bhash2_conflict(sk, tb2, uid, relax,
+                                                  reuseport_cb_ok, reuseport_ok);
+
+       /* Unlike other sk lookup places we do not check
         * for sk_net here, since _all_ the socks listed
         * in tb->owners and tb2->owners list belong
         * to the same net - the one this bucket belongs to.
         */
+       sk_for_each_bound(sk2, &tb->owners) {
+               if (!inet_bind_conflict(sk, sk2, uid, relax, reuseport_cb_ok, reuseport_ok))
+                       continue;
 
-       if (!inet_use_bhash2_on_bind(sk)) {
-               struct sock *sk2;
-
-               sk_for_each_bound(sk2, &tb->owners)
-                       if (inet_bind_conflict(sk, sk2, uid, relax,
-                                              reuseport_cb_ok, reuseport_ok) &&
-                           inet_rcv_saddr_equal(sk, sk2, true))
-                               return true;
-
-               return false;
+               if (inet_rcv_saddr_equal(sk, sk2, true))
+                       return true;
        }
 
-       /* Conflicts with an existing IPV6_ADDR_ANY (if ipv6) or INADDR_ANY (if
-        * ipv4) should have been checked already. We need to do these two
-        * checks separately because their spinlocks have to be acquired/released
-        * independently of each other, to prevent possible deadlocks
-        */
-       return tb2 && inet_bhash2_conflict(sk, tb2, uid, relax, reuseport_cb_ok,
-                                          reuseport_ok);
+       return false;
 }
 
 /* Determine if there is a bind conflict with an existing IPV6_ADDR_ANY (if ipv6) or