]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - net/netfilter/nf_conntrack_core.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[mirror_ubuntu-jammy-kernel.git] / net / netfilter / nf_conntrack_core.c
index 2a714527cde17aee1152f33bc7f9b041cd5eb087..bdfeacee081771023bb734dc465915a74f062a01 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /* Connection state tracking for netfilter.  This is separated from,
    but required by, the NAT layer; it can also be used by an iptables
    extension. */
@@ -6,10 +7,6 @@
  * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
  * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
  * (C) 2005-2012 Patrick McHardy <kaber@trash.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -752,9 +749,6 @@ begin:
                        continue;
                }
 
-               if (nf_ct_is_dying(ct))
-                       continue;
-
                if (nf_ct_key_equal(h, tuple, zone, net))
                        return h;
        }
@@ -780,20 +774,24 @@ __nf_conntrack_find_get(struct net *net, const struct nf_conntrack_zone *zone,
        struct nf_conn *ct;
 
        rcu_read_lock();
-begin:
+
        h = ____nf_conntrack_find(net, zone, tuple, hash);
        if (h) {
+               /* We have a candidate that matches the tuple we're interested
+                * in, try to obtain a reference and re-check tuple
+                */
                ct = nf_ct_tuplehash_to_ctrack(h);
-               if (unlikely(nf_ct_is_dying(ct) ||
-                            !atomic_inc_not_zero(&ct->ct_general.use)))
-                       h = NULL;
-               else {
-                       if (unlikely(!nf_ct_key_equal(h, tuple, zone, net))) {
-                               nf_ct_put(ct);
-                               goto begin;
-                       }
+               if (likely(atomic_inc_not_zero(&ct->ct_general.use))) {
+                       if (likely(nf_ct_key_equal(h, tuple, zone, net)))
+                               goto found;
+
+                       /* TYPESAFE_BY_RCU recycled the candidate */
+                       nf_ct_put(ct);
                }
+
+               h = NULL;
        }
+found:
        rcu_read_unlock();
 
        return h;