Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / net / core / neighbour.c
index c815f285e5ab76e354dd7752f7ef1c1049154570..89a3a07d85fbd3318ff03c255a51cf0aaeacbe7b 100644 (file)
 #include <linux/string.h>
 #include <linux/log2.h>
 
+#define DEBUG
 #define NEIGH_DEBUG 1
-
-#define NEIGH_PRINTK(x...) printk(x)
-#define NEIGH_NOPRINTK(x...) do { ; } while(0)
-#define NEIGH_PRINTK1 NEIGH_NOPRINTK
-#define NEIGH_PRINTK2 NEIGH_NOPRINTK
-
-#if NEIGH_DEBUG >= 1
-#undef NEIGH_PRINTK1
-#define NEIGH_PRINTK1 NEIGH_PRINTK
-#endif
-#if NEIGH_DEBUG >= 2
-#undef NEIGH_PRINTK2
-#define NEIGH_PRINTK2 NEIGH_PRINTK
-#endif
+#define neigh_dbg(level, fmt, ...)             \
+do {                                           \
+       if (level <= NEIGH_DEBUG)               \
+               pr_debug(fmt, ##__VA_ARGS__);   \
+} while (0)
 
 #define PNEIGH_HASHMASK                0xF
 
@@ -246,7 +238,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev)
                                        n->nud_state = NUD_NOARP;
                                else
                                        n->nud_state = NUD_NONE;
-                               NEIGH_PRINTK2("neigh %p is stray.\n", n);
+                               neigh_dbg(2, "neigh %p is stray\n", n);
                        }
                        write_unlock(&n->lock);
                        neigh_cleanup_and_release(n);
@@ -290,15 +282,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl, struct net_device
                        goto out_entries;
        }
 
-       if (tbl->entry_size)
-               n = kzalloc(tbl->entry_size, GFP_ATOMIC);
-       else {
-               int sz = sizeof(*n) + tbl->key_len;
-
-               sz = ALIGN(sz, NEIGH_PRIV_ALIGN);
-               sz += dev->neigh_priv_len;
-               n = kzalloc(sz, GFP_ATOMIC);
-       }
+       n = kzalloc(tbl->entry_size + dev->neigh_priv_len, GFP_ATOMIC);
        if (!n)
                goto out_entries;
 
@@ -550,7 +534,7 @@ struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
                                                     lockdep_is_held(&tbl->lock)));
        rcu_assign_pointer(nht->hash_buckets[hash_val], n);
        write_unlock_bh(&tbl->lock);
-       NEIGH_PRINTK2("neigh %p is created.\n", n);
+       neigh_dbg(2, "neigh %p is created\n", n);
        rc = n;
 out:
        return rc;
@@ -733,7 +717,7 @@ void neigh_destroy(struct neighbour *neigh)
        dev_put(dev);
        neigh_parms_put(neigh->parms);
 
-       NEIGH_PRINTK2("neigh %p is destroyed.\n", neigh);
+       neigh_dbg(2, "neigh %p is destroyed\n", neigh);
 
        atomic_dec(&neigh->tbl->entries);
        kfree_rcu(neigh, rcu);
@@ -747,7 +731,7 @@ EXPORT_SYMBOL(neigh_destroy);
  */
 static void neigh_suspect(struct neighbour *neigh)
 {
-       NEIGH_PRINTK2("neigh %p is suspected.\n", neigh);
+       neigh_dbg(2, "neigh %p is suspected\n", neigh);
 
        neigh->output = neigh->ops->output;
 }
@@ -759,7 +743,7 @@ static void neigh_suspect(struct neighbour *neigh)
  */
 static void neigh_connect(struct neighbour *neigh)
 {
-       NEIGH_PRINTK2("neigh %p is connected.\n", neigh);
+       neigh_dbg(2, "neigh %p is connected\n", neigh);
 
        neigh->output = neigh->ops->connected_output;
 }
@@ -778,6 +762,9 @@ static void neigh_periodic_work(struct work_struct *work)
        nht = rcu_dereference_protected(tbl->nht,
                                        lockdep_is_held(&tbl->lock));
 
+       if (atomic_read(&tbl->entries) < tbl->gc_thresh1)
+               goto out;
+
        /*
         *      periodically recompute ReachableTime from random function
         */
@@ -832,6 +819,7 @@ next_elt:
                nht = rcu_dereference_protected(tbl->nht,
                                                lockdep_is_held(&tbl->lock));
        }
+out:
        /* Cycle through all hash buckets every base_reachable_time/2 ticks.
         * ARP entry timeouts range from 1/2 base_reachable_time to 3/2
         * base_reachable_time.
@@ -856,7 +844,7 @@ static void neigh_invalidate(struct neighbour *neigh)
        struct sk_buff *skb;
 
        NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
-       NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
+       neigh_dbg(2, "neigh %p is failed\n", neigh);
        neigh->updated = jiffies;
 
        /* It is very thin place. report_unreachable is very complicated
@@ -908,17 +896,17 @@ static void neigh_timer_handler(unsigned long arg)
        if (state & NUD_REACHABLE) {
                if (time_before_eq(now,
                                   neigh->confirmed + neigh->parms->reachable_time)) {
-                       NEIGH_PRINTK2("neigh %p is still alive.\n", neigh);
+                       neigh_dbg(2, "neigh %p is still alive\n", neigh);
                        next = neigh->confirmed + neigh->parms->reachable_time;
                } else if (time_before_eq(now,
                                          neigh->used + neigh->parms->delay_probe_time)) {
-                       NEIGH_PRINTK2("neigh %p is delayed.\n", neigh);
+                       neigh_dbg(2, "neigh %p is delayed\n", neigh);
                        neigh->nud_state = NUD_DELAY;
                        neigh->updated = jiffies;
                        neigh_suspect(neigh);
                        next = now + neigh->parms->delay_probe_time;
                } else {
-                       NEIGH_PRINTK2("neigh %p is suspected.\n", neigh);
+                       neigh_dbg(2, "neigh %p is suspected\n", neigh);
                        neigh->nud_state = NUD_STALE;
                        neigh->updated = jiffies;
                        neigh_suspect(neigh);
@@ -927,14 +915,14 @@ static void neigh_timer_handler(unsigned long arg)
        } else if (state & NUD_DELAY) {
                if (time_before_eq(now,
                                   neigh->confirmed + neigh->parms->delay_probe_time)) {
-                       NEIGH_PRINTK2("neigh %p is now reachable.\n", neigh);
+                       neigh_dbg(2, "neigh %p is now reachable\n", neigh);
                        neigh->nud_state = NUD_REACHABLE;
                        neigh->updated = jiffies;
                        neigh_connect(neigh);
                        notify = 1;
                        next = neigh->confirmed + neigh->parms->reachable_time;
                } else {
-                       NEIGH_PRINTK2("neigh %p is probed.\n", neigh);
+                       neigh_dbg(2, "neigh %p is probed\n", neigh);
                        neigh->nud_state = NUD_PROBE;
                        neigh->updated = jiffies;
                        atomic_set(&neigh->probes, 0);
@@ -1001,7 +989,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
                        return 1;
                }
        } else if (neigh->nud_state & NUD_STALE) {
-               NEIGH_PRINTK2("neigh %p is delayed.\n", neigh);
+               neigh_dbg(2, "neigh %p is delayed\n", neigh);
                neigh->nud_state = NUD_DELAY;
                neigh->updated = jiffies;
                neigh_add_timer(neigh,
@@ -1324,8 +1312,7 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb)
 out:
        return rc;
 discard:
-       NEIGH_PRINTK1("neigh_resolve_output: dst=%p neigh=%p\n",
-                     dst, neigh);
+       neigh_dbg(1, "%s: dst=%p neigh=%p\n", __func__, dst, neigh);
 out_kfree_skb:
        rc = -EINVAL;
        kfree_skb(skb);
@@ -1502,7 +1489,7 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
                }
        }
        write_unlock_bh(&tbl->lock);
-       NEIGH_PRINTK1("neigh_parms_release: not found\n");
+       neigh_dbg(1, "%s: not found\n", __func__);
 }
 EXPORT_SYMBOL(neigh_parms_release);
 
@@ -1542,6 +1529,12 @@ static void neigh_table_init_no_netlink(struct neigh_table *tbl)
        if (!tbl->nht || !tbl->phash_buckets)
                panic("cannot allocate neighbour cache hashes");
 
+       if (!tbl->entry_size)
+               tbl->entry_size = ALIGN(offsetof(struct neighbour, primary_key) +
+                                       tbl->key_len, NEIGH_PRIV_ALIGN);
+       else
+               WARN_ON(tbl->entry_size % NEIGH_PRIV_ALIGN);
+
        rwlock_init(&tbl->lock);
        INIT_DEFERRABLE_WORK(&tbl->gc_work, neigh_periodic_work);
        schedule_delayed_work(&tbl->gc_work, tbl->parms.reachable_time);
@@ -1611,7 +1604,7 @@ int neigh_table_clear(struct neigh_table *tbl)
 }
 EXPORT_SYMBOL(neigh_table_clear);
 
-static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
        struct net *net = sock_net(skb->sk);
        struct ndmsg *ndm;
@@ -1675,7 +1668,7 @@ out:
        return err;
 }
 
-static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
        struct net *net = sock_net(skb->sk);
        struct ndmsg *ndm;
@@ -1953,7 +1946,7 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
        [NDTPA_LOCKTIME]                = { .type = NLA_U64 },
 };
 
-static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
        struct net *net = sock_net(skb->sk);
        struct neigh_table *tbl;