]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/core/neighbour.c
[NET]: Make /proc/net per network namespace
[net-next-2.6.git] / net / core / neighbour.c
index 6f3bb73053c23fc6d4427957567d3a84c6033b62..5f25f4f79b8ceff86be9bce0013d9cc31515acb6 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/sysctl.h>
 #endif
 #include <linux/times.h>
+#include <net/net_namespace.h>
 #include <net/neighbour.h>
 #include <net/dst.h>
 #include <net/sock.h>
@@ -33,6 +34,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/random.h>
 #include <linux/string.h>
+#include <linux/log2.h>
 
 #define NEIGH_DEBUG 1
 
@@ -54,9 +56,8 @@
 #define PNEIGH_HASHMASK                0xF
 
 static void neigh_timer_handler(unsigned long arg);
-#ifdef CONFIG_ARPD
-static void neigh_app_notify(struct neighbour *n);
-#endif
+static void __neigh_notify(struct neighbour *n, int type, int flags);
+static void neigh_update_notify(struct neighbour *neigh);
 static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
 void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
 
@@ -104,6 +105,15 @@ static int neigh_blackhole(struct sk_buff *skb)
        return -ENETDOWN;
 }
 
+static void neigh_cleanup_and_release(struct neighbour *neigh)
+{
+       if (neigh->parms->neigh_cleanup)
+               neigh->parms->neigh_cleanup(neigh);
+
+       __neigh_notify(neigh, RTM_DELNEIGH, 0);
+       neigh_release(neigh);
+}
+
 /*
  * It is random distribution in the interval (1/2)*base...(3/2)*base.
  * It corresponds to default IPv6 settings and is not overridable,
@@ -140,9 +150,7 @@ static int neigh_forced_gc(struct neigh_table *tbl)
                                n->dead = 1;
                                shrunk  = 1;
                                write_unlock(&n->lock);
-                               if (n->parms->neigh_cleanup)
-                                       n->parms->neigh_cleanup(n);
-                               neigh_release(n);
+                               neigh_cleanup_and_release(n);
                                continue;
                        }
                        write_unlock(&n->lock);
@@ -213,9 +221,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev)
                                NEIGH_PRINTK2("neigh %p is stray.\n", n);
                        }
                        write_unlock(&n->lock);
-                       if (n->parms->neigh_cleanup)
-                               n->parms->neigh_cleanup(n);
-                       neigh_release(n);
+                       neigh_cleanup_and_release(n);
                }
        }
 }
@@ -311,7 +317,7 @@ static void neigh_hash_grow(struct neigh_table *tbl, unsigned long new_entries)
 
        NEIGH_CACHE_STAT_INC(tbl, hash_grows);
 
-       BUG_ON(new_entries & (new_entries - 1));
+       BUG_ON(!is_power_of_2(new_entries));
        new_hash = neigh_hash_alloc(new_entries);
        if (!new_hash)
                return;
@@ -676,9 +682,7 @@ static void neigh_periodic_timer(unsigned long arg)
                        *np = n->next;
                        n->dead = 1;
                        write_unlock(&n->lock);
-                       if (n->parms->neigh_cleanup)
-                               n->parms->neigh_cleanup(n);
-                       neigh_release(n);
+                       neigh_cleanup_and_release(n);
                        continue;
                }
                write_unlock(&n->lock);
@@ -827,13 +831,10 @@ static void neigh_timer_handler(unsigned long arg)
 out:
                write_unlock(&neigh->lock);
        }
+
        if (notify)
-               call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
+               neigh_update_notify(neigh);
 
-#ifdef CONFIG_ARPD
-       if (notify && neigh->parms->app_probes)
-               neigh_app_notify(neigh);
-#endif
        neigh_release(neigh);
 }
 
@@ -1062,11 +1063,8 @@ out:
        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);
-#endif
+               neigh_update_notify(neigh);
+
        return err;
 }
 
@@ -1347,13 +1345,13 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
                tbl->kmem_cachep =
                        kmem_cache_create(tbl->id, tbl->entry_size, 0,
                                          SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-                                         NULL, NULL);
+                                         NULL);
        tbl->stats = alloc_percpu(struct neigh_statistics);
        if (!tbl->stats)
                panic("cannot create neighbour cache statistics");
 
 #ifdef CONFIG_PROC_FS
-       tbl->pde = create_proc_entry(tbl->id, 0, proc_net_stat);
+       tbl->pde = create_proc_entry(tbl->id, 0, init_net.proc_net_stat);
        if (!tbl->pde)
                panic("cannot create neighbour proc dir entry");
        tbl->pde->proc_fops = &neigh_stat_seq_fops;
@@ -1761,7 +1759,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
        return NULL;
 }
 
-static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = {
+static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
        [NDTA_NAME]             = { .type = NLA_STRING },
        [NDTA_THRESH1]          = { .type = NLA_U32 },
        [NDTA_THRESH2]          = { .type = NLA_U32 },
@@ -1770,7 +1768,7 @@ static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = {
        [NDTA_PARMS]            = { .type = NLA_NESTED },
 };
 
-static struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] __read_mostly = {
+static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
        [NDTPA_IFINDEX]                 = { .type = NLA_U32 },
        [NDTPA_QUEUE_LEN]               = { .type = NLA_U32 },
        [NDTPA_PROXY_QLEN]              = { .type = NLA_U32 },
@@ -1999,6 +1997,11 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
+static void neigh_update_notify(struct neighbour *neigh)
+{
+       call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
+       __neigh_notify(neigh, RTM_NEWNEIGH, 0);
+}
 
 static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                            struct netlink_callback *cb)
@@ -2094,11 +2097,8 @@ void __neigh_for_each_release(struct neigh_table *tbl,
                        } else
                                np = &n->next;
                        write_unlock(&n->lock);
-                       if (release) {
-                               if (n->parms->neigh_cleanup)
-                                       n->parms->neigh_cleanup(n);
-                               neigh_release(n);
-                       }
+                       if (release)
+                               neigh_cleanup_and_release(n);
                }
        }
 }
@@ -2421,7 +2421,6 @@ static const struct file_operations neigh_stat_seq_fops = {
 
 #endif /* CONFIG_PROC_FS */
 
-#ifdef CONFIG_ARPD
 static inline size_t neigh_nlmsg_size(void)
 {
        return NLMSG_ALIGN(sizeof(struct ndmsg))
@@ -2453,16 +2452,11 @@ errout:
                rtnl_set_sk_err(RTNLGRP_NEIGH, err);
 }
 
+#ifdef CONFIG_ARPD
 void neigh_app_ns(struct neighbour *n)
 {
        __neigh_notify(n, RTM_GETNEIGH, NLM_F_REQUEST);
 }
-
-static void neigh_app_notify(struct neighbour *n)
-{
-       __neigh_notify(n, RTM_NEWNEIGH, 0);
-}
-
 #endif /* CONFIG_ARPD */
 
 #ifdef CONFIG_SYSCTL