linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / core / neighbour.c
index fe2113f..e68700f 100644 (file)
@@ -15,6 +15,7 @@
  *     Harald Welte            Add neighbour cache statistics like rtstat
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -29,7 +30,6 @@
 #include <net/neighbour.h>
 #include <net/dst.h>
 #include <net/sock.h>
-#include <net/netevent.h>
 #include <linux/rtnetlink.h>
 #include <linux/random.h>
 #include <linux/string.h>
@@ -284,11 +284,14 @@ static struct neighbour **neigh_hash_alloc(unsigned int entries)
        struct neighbour **ret;
 
        if (size <= PAGE_SIZE) {
-               ret = kzalloc(size, GFP_ATOMIC);
+               ret = kmalloc(size, GFP_ATOMIC);
        } else {
                ret = (struct neighbour **)
-                     __get_free_pages(GFP_ATOMIC|__GFP_ZERO, get_order(size));
+                       __get_free_pages(GFP_ATOMIC, get_order(size));
        }
+       if (ret)
+               memset(ret, 0, size);
+
        return ret;
 }
 
@@ -583,8 +586,8 @@ void neigh_destroy(struct neighbour *neigh)
                        kfree(hh);
        }
 
-       if (neigh->parms->neigh_destructor)
-               (neigh->parms->neigh_destructor)(neigh);
+       if (neigh->ops && neigh->ops->destructor)
+               (neigh->ops->destructor)(neigh);
 
        skb_queue_purge(&neigh->arp_queue);
 
@@ -747,29 +750,23 @@ static void neigh_timer_handler(unsigned long arg)
                                          neigh->used + neigh->parms->delay_probe_time)) {
                        NEIGH_PRINTK2("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->nud_state = NUD_STALE;
-                       neigh->updated = jiffies;
                        neigh_suspect(neigh);
-                       notify = 1;
                }
        } 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->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->nud_state = NUD_PROBE;
-                       neigh->updated = jiffies;
                        atomic_set(&neigh->probes, 0);
                        next = now + neigh->parms->retrans_time;
                }
@@ -783,7 +780,6 @@ static void neigh_timer_handler(unsigned long arg)
                struct sk_buff *skb;
 
                neigh->nud_state = NUD_FAILED;
-               neigh->updated = jiffies;
                notify = 1;
                NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
                NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
@@ -822,8 +818,6 @@ static void neigh_timer_handler(unsigned long arg)
 out:
                write_unlock(&neigh->lock);
        }
-       if (notify)
-               call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
 
 #ifdef CONFIG_ARPD
        if (notify && neigh->parms->app_probes)
@@ -849,12 +843,10 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
                if (neigh->parms->mcast_probes + neigh->parms->app_probes) {
                        atomic_set(&neigh->probes, neigh->parms->ucast_probes);
                        neigh->nud_state     = NUD_INCOMPLETE;
-                       neigh->updated = jiffies;
                        neigh_hold(neigh);
                        neigh_add_timer(neigh, now + 1);
                } else {
                        neigh->nud_state = NUD_FAILED;
-                       neigh->updated = jiffies;
                        write_unlock_bh(&neigh->lock);
 
                        if (skb)
@@ -865,7 +857,6 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
                NEIGH_PRINTK2("neigh %p is delayed.\n", neigh);
                neigh_hold(neigh);
                neigh->nud_state = NUD_DELAY;
-               neigh->updated = jiffies;
                neigh_add_timer(neigh,
                                jiffies + neigh->parms->delay_probe_time);
        }
@@ -931,7 +922,9 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
 {
        u8 old;
        int err;
+#ifdef CONFIG_ARPD
        int notify = 0;
+#endif
        struct net_device *dev;
        int update_isrouter = 0;
 
@@ -951,7 +944,9 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                        neigh_suspect(neigh);
                neigh->nud_state = new;
                err = 0;
+#ifdef CONFIG_ARPD
                notify = old & NUD_VALID;
+#endif
                goto out;
        }
 
@@ -1023,7 +1018,9 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                if (!(new & NUD_CONNECTED))
                        neigh->confirmed = jiffies -
                                      (neigh->parms->base_reachable_time << 1);
+#ifdef CONFIG_ARPD
                notify = 1;
+#endif
        }
        if (new == old)
                goto out;
@@ -1055,9 +1052,6 @@ out:
                        (neigh->flags & ~NTF_ROUTER);
        }
        write_unlock_bh(&neigh->lock);
-
-       if (notify)
-               call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
 #ifdef CONFIG_ARPD
        if (notify && neigh->parms->app_probes)
                neigh_app_notify(neigh);
@@ -1087,7 +1081,8 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst,
                if (hh->hh_type == protocol)
                        break;
 
-       if (!hh && (hh = kzalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) {
+       if (!hh && (hh = kmalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) {
+               memset(hh, 0, sizeof(struct hh_cache));
                rwlock_init(&hh->hh_lock);
                hh->hh_type = protocol;
                atomic_set(&hh->hh_refcnt, 0);
@@ -1327,7 +1322,8 @@ void neigh_parms_destroy(struct neigh_parms *parms)
        kfree(parms);
 }
 
-void neigh_table_init_no_netlink(struct neigh_table *tbl)
+
+void neigh_table_init(struct neigh_table *tbl)
 {
        unsigned long now = jiffies;
        unsigned long phsize;
@@ -1362,11 +1358,13 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
        tbl->hash_buckets = neigh_hash_alloc(tbl->hash_mask + 1);
 
        phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *);
-       tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL);
+       tbl->phash_buckets = kmalloc(phsize, GFP_KERNEL);
 
        if (!tbl->hash_buckets || !tbl->phash_buckets)
                panic("cannot allocate neighbour cache hashes");
 
+       memset(tbl->phash_buckets, 0, phsize);
+
        get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd));
 
        rwlock_init(&tbl->lock);
@@ -1383,27 +1381,10 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
 
        tbl->last_flush = now;
        tbl->last_rand  = now + tbl->parms.reachable_time * 20;
-}
-
-void neigh_table_init(struct neigh_table *tbl)
-{
-       struct neigh_table *tmp;
-
-       neigh_table_init_no_netlink(tbl);
        write_lock(&neigh_tbl_lock);
-       for (tmp = neigh_tables; tmp; tmp = tmp->next) {
-               if (tmp->family == tbl->family)
-                       break;
-       }
        tbl->next       = neigh_tables;
        neigh_tables    = tbl;
        write_unlock(&neigh_tbl_lock);
-
-       if (unlikely(tmp)) {
-               printk(KERN_ERR "NEIGH: Registering multiple tables for "
-                      "family %d\n", tbl->family);
-               dump_stack();
-       }
 }
 
 int neigh_table_clear(struct neigh_table *tbl)
@@ -1432,9 +1413,6 @@ int neigh_table_clear(struct neigh_table *tbl)
        kfree(tbl->phash_buckets);
        tbl->phash_buckets = NULL;
 
-       free_percpu(tbl->stats);
-       tbl->stats = NULL;
-
        return 0;
 }
 
@@ -1647,7 +1625,7 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb,
 
                memset(&ndst, 0, sizeof(ndst));
 
-               for_each_possible_cpu(cpu) {
+               for_each_cpu(cpu) {
                        struct neigh_statistics *st;
 
                        st = per_cpu_ptr(tbl->stats, cpu);
@@ -2677,7 +2655,6 @@ EXPORT_SYMBOL(neigh_rand_reach_time);
 EXPORT_SYMBOL(neigh_resolve_output);
 EXPORT_SYMBOL(neigh_table_clear);
 EXPORT_SYMBOL(neigh_table_init);
-EXPORT_SYMBOL(neigh_table_init_no_netlink);
 EXPORT_SYMBOL(neigh_update);
 EXPORT_SYMBOL(neigh_update_hhs);
 EXPORT_SYMBOL(pneigh_enqueue);