Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[firefly-linux-kernel-4.4.55.git] / include / net / arp.h
index 4a1f3fb562eb500ec0739f64f1fc7e4cb9f28a2e..7f7df93f37cd0d3b3259775ebf6ab23743b3c564 100644 (file)
@@ -15,24 +15,31 @@ static inline u32 arp_hashfn(u32 key, const struct net_device *dev, u32 hash_rnd
        return val * hash_rnd;
 }
 
-static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 key)
+static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key)
 {
-       struct neigh_hash_table *nht;
+       struct neigh_hash_table *nht = rcu_dereference_bh(arp_tbl.nht);
        struct neighbour *n;
        u32 hash_val;
 
-       rcu_read_lock_bh();
-       nht = rcu_dereference_bh(arp_tbl.nht);
        hash_val = arp_hashfn(key, dev, nht->hash_rnd[0]) >> (32 - nht->hash_shift);
        for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
             n != NULL;
             n = rcu_dereference_bh(n->next)) {
-               if (n->dev == dev && *(u32 *)n->primary_key == key) {
-                       if (!atomic_inc_not_zero(&n->refcnt))
-                               n = NULL;
-                       break;
-               }
+               if (n->dev == dev && *(u32 *)n->primary_key == key)
+                       return n;
        }
+
+       return NULL;
+}
+
+static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 key)
+{
+       struct neighbour *n;
+
+       rcu_read_lock_bh();
+       n = __ipv4_neigh_lookup_noref(dev, key);
+       if (n && !atomic_inc_not_zero(&n->refcnt))
+               n = NULL;
        rcu_read_unlock_bh();
 
        return n;