[NET] NETNS: Omit sock->sk_net without CONFIG_NET_NS.
[deliverable/linux.git] / net / core / neighbour.c
index bd899d557737294f10470d236ca050c9fe93fdfd..065fbac7ecd38356fdff4157858f3cdca3445015 100644 (file)
@@ -59,7 +59,6 @@ static void neigh_timer_handler(unsigned long arg);
 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);
 
 static struct neigh_table *neigh_tables;
 #ifdef CONFIG_PROC_FS
@@ -359,11 +358,12 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
 {
        struct neighbour *n;
        int key_len = tbl->key_len;
-       u32 hash_val = tbl->hash(pkey, dev);
+       u32 hash_val;
 
        NEIGH_CACHE_STAT_INC(tbl, lookups);
 
        read_lock_bh(&tbl->lock);
+       hash_val = tbl->hash(pkey, dev);
        for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
                if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) {
                        neigh_hold(n);
@@ -380,14 +380,15 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
 {
        struct neighbour *n;
        int key_len = tbl->key_len;
-       u32 hash_val = tbl->hash(pkey, NULL);
+       u32 hash_val;
 
        NEIGH_CACHE_STAT_INC(tbl, lookups);
 
        read_lock_bh(&tbl->lock);
+       hash_val = tbl->hash(pkey, NULL);
        for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
                if (!memcmp(n->primary_key, pkey, key_len) &&
-                   (net == n->dev->nd_net)) {
+                   dev_net(n->dev) == net) {
                        neigh_hold(n);
                        NEIGH_CACHE_STAT_INC(tbl, hits);
                        break;
@@ -508,6 +509,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
        if (tbl->pconstructor && tbl->pconstructor(n)) {
                if (dev)
                        dev_put(dev);
+               release_net(net);
                kfree(n);
                n = NULL;
                goto out;
@@ -578,6 +580,13 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
        return -ENOENT;
 }
 
+static void neigh_parms_destroy(struct neigh_parms *parms);
+
+static inline void neigh_parms_put(struct neigh_parms *parms)
+{
+       if (atomic_dec_and_test(&parms->refcnt))
+               neigh_parms_destroy(parms);
+}
 
 /*
  *     neighbour must already be out of the table;
@@ -830,7 +839,7 @@ static void neigh_timer_handler(unsigned long arg)
                struct sk_buff *skb = skb_peek(&neigh->arp_queue);
                /* keep skb alive even if arp_queue overflows */
                if (skb)
-                       skb_get(skb);
+                       skb = skb_copy(skb, GFP_ATOMIC);
                write_unlock(&neigh->lock);
                neigh->ops->solicit(neigh, skb);
                atomic_inc(&neigh->probes);
@@ -1275,9 +1284,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
        struct neigh_parms *p;
 
        for (p = &tbl->parms; p; p = p->next) {
-               if (p->net != net)
-                       continue;
-               if ((p->dev && p->dev->ifindex == ifindex) ||
+               if ((p->dev && p->dev->ifindex == ifindex && p->net == net) ||
                    (!p->dev && !ifindex))
                        return p;
        }
@@ -1291,10 +1298,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
        struct neigh_parms *p, *ref;
        struct net *net;
 
-       net = &init_net;
-       if (dev)
-               net = dev->nd_net;
-
+       net = dev_net(dev);
        ref = lookup_neigh_params(tbl, net, 0);
        if (!ref)
                return NULL;
@@ -1306,15 +1310,14 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
                INIT_RCU_HEAD(&p->rcu_head);
                p->reachable_time =
                                neigh_rand_reach_time(p->base_reachable_time);
-               if (dev) {
-                       if (dev->neigh_setup && dev->neigh_setup(dev, p)) {
-                               kfree(p);
-                               return NULL;
-                       }
 
-                       dev_hold(dev);
-                       p->dev = dev;
+               if (dev->neigh_setup && dev->neigh_setup(dev, p)) {
+                       kfree(p);
+                       return NULL;
                }
+
+               dev_hold(dev);
+               p->dev = dev;
                p->net = hold_net(net);
                p->sysctl_table = NULL;
                write_lock_bh(&tbl->lock);
@@ -1355,7 +1358,7 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
        NEIGH_PRINTK1("neigh_parms_release: not found\n");
 }
 
-void neigh_parms_destroy(struct neigh_parms *parms)
+static void neigh_parms_destroy(struct neigh_parms *parms)
 {
        release_net(parms->net);
        kfree(parms);
@@ -1384,10 +1387,10 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
                panic("cannot create neighbour cache statistics");
 
 #ifdef CONFIG_PROC_FS
-       tbl->pde = create_proc_entry(tbl->id, 0, init_net.proc_net_stat);
+       tbl->pde = proc_create(tbl->id, 0, init_net.proc_net_stat,
+                              &neigh_stat_seq_fops);
        if (!tbl->pde)
                panic("cannot create neighbour proc dir entry");
-       tbl->pde->proc_fops = &neigh_stat_seq_fops;
        tbl->pde->data = tbl;
 #endif
 
@@ -1475,7 +1478,7 @@ int neigh_table_clear(struct neigh_table *tbl)
 
 static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
-       struct net *net = skb->sk->sk_net;
+       struct net *net = sock_net(skb->sk);
        struct ndmsg *ndm;
        struct nlattr *dst_attr;
        struct neigh_table *tbl;
@@ -1541,7 +1544,7 @@ out:
 
 static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
-       struct net *net = skb->sk->sk_net;
+       struct net *net = sock_net(skb->sk);
        struct ndmsg *ndm;
        struct nlattr *tb[NDA_MAX+1];
        struct neigh_table *tbl;
@@ -1809,7 +1812,7 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
 
 static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
-       struct net *net = skb->sk->sk_net;
+       struct net *net = sock_net(skb->sk);
        struct neigh_table *tbl;
        struct ndtmsg *ndtmsg;
        struct nlattr *tb[NDTA_MAX+1];
@@ -1934,7 +1937,7 @@ errout:
 
 static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 {
-       struct net *net = skb->sk->sk_net;
+       struct net *net = sock_net(skb->sk);
        int family, tidx, nidx = 0;
        int tbl_skip = cb->args[0];
        int neigh_skip = cb->args[1];
@@ -2034,7 +2037,7 @@ static void neigh_update_notify(struct neighbour *neigh)
 static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                            struct netlink_callback *cb)
 {
-       struct net * net = skb->sk->sk_net;
+       struct net * net = sock_net(skb->sk);
        struct neighbour *n;
        int rc, h, s_h = cb->args[1];
        int idx, s_idx = idx = cb->args[2];
@@ -2047,7 +2050,7 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                        s_idx = 0;
                for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) {
                        int lidx;
-                       if (n->dev->nd_net != net)
+                       if (dev_net(n->dev) != net)
                                continue;
                        lidx = idx++;
                        if (lidx < s_idx)
@@ -2142,7 +2145,7 @@ EXPORT_SYMBOL(__neigh_for_each_release);
 static struct neighbour *neigh_get_first(struct seq_file *seq)
 {
        struct neigh_seq_state *state = seq->private;
-       struct net *net = state->net;
+       struct net *net = state->p.net;
        struct neigh_table *tbl = state->tbl;
        struct neighbour *n = NULL;
        int bucket = state->bucket;
@@ -2152,7 +2155,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq)
                n = tbl->hash_buckets[bucket];
 
                while (n) {
-                       if (n->dev->nd_net != net)
+                       if (dev_net(n->dev) != net)
                                goto next;
                        if (state->neigh_sub_iter) {
                                loff_t fakep = 0;
@@ -2183,7 +2186,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
                                        loff_t *pos)
 {
        struct neigh_seq_state *state = seq->private;
-       struct net *net = state->net;
+       struct net *net = state->p.net;
        struct neigh_table *tbl = state->tbl;
 
        if (state->neigh_sub_iter) {
@@ -2195,7 +2198,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
 
        while (1) {
                while (n) {
-                       if (n->dev->nd_net != net)
+                       if (dev_net(n->dev) != net)
                                goto next;
                        if (state->neigh_sub_iter) {
                                void *v = state->neigh_sub_iter(state, n, pos);
@@ -2243,7 +2246,7 @@ static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos)
 static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
 {
        struct neigh_seq_state *state = seq->private;
-       struct net * net = state->net;
+       struct net * net = state->p.net;
        struct neigh_table *tbl = state->tbl;
        struct pneigh_entry *pn = NULL;
        int bucket = state->bucket;
@@ -2266,7 +2269,7 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
                                            loff_t *pos)
 {
        struct neigh_seq_state *state = seq->private;
-       struct net * net = state->net;
+       struct net * net = state->p.net;
        struct neigh_table *tbl = state->tbl;
 
        pn = pn->next;
@@ -2313,6 +2316,7 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
 }
 
 void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags)
+       __acquires(tbl->lock)
 {
        struct neigh_seq_state *state = seq->private;
        loff_t pos_minus_one;
@@ -2356,6 +2360,7 @@ out:
 EXPORT_SYMBOL(neigh_seq_next);
 
 void neigh_seq_stop(struct seq_file *seq, void *v)
+       __releases(tbl->lock)
 {
        struct neigh_seq_state *state = seq->private;
        struct neigh_table *tbl = state->tbl;
@@ -2477,7 +2482,7 @@ static inline size_t neigh_nlmsg_size(void)
 
 static void __neigh_notify(struct neighbour *n, int type, int flags)
 {
-       struct net *net = n->dev->nd_net;
+       struct net *net = dev_net(n->dev);
        struct sk_buff *skb;
        int err = -ENOBUFS;
 
@@ -2734,7 +2739,8 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
        neigh_path[NEIGH_CTL_PATH_PROTO].procname = p_name;
        neigh_path[NEIGH_CTL_PATH_PROTO].ctl_name = p_id;
 
-       t->sysctl_header = register_sysctl_paths(neigh_path, t->neigh_vars);
+       t->sysctl_header =
+               register_net_sysctl_table(p->net, neigh_path, t->neigh_vars);
        if (!t->sysctl_header)
                goto free_procname;
 
This page took 0.029653 seconds and 5 git commands to generate.