aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/neighbour.h10
-rw-r--r--net/atm/clip.c15
-rw-r--r--net/core/neighbour.c116
-rw-r--r--net/decnet/dn_neigh.c6
-rw-r--r--net/decnet/dn_route.c2
-rw-r--r--net/ipv4/arp.c12
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/ndisc.c4
8 files changed, 106 insertions, 61 deletions
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index a4f26187fc1a..11590f23d99d 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -34,6 +34,7 @@ struct neighbour;
34 34
35struct neigh_parms 35struct neigh_parms
36{ 36{
37 struct net *net;
37 struct net_device *dev; 38 struct net_device *dev;
38 struct neigh_parms *next; 39 struct neigh_parms *next;
39 int (*neigh_setup)(struct neighbour *); 40 int (*neigh_setup)(struct neighbour *);
@@ -126,7 +127,8 @@ struct neigh_ops
126struct pneigh_entry 127struct pneigh_entry
127{ 128{
128 struct pneigh_entry *next; 129 struct pneigh_entry *next;
129 struct net_device *dev; 130 struct net *net;
131 struct net_device *dev;
130 u8 flags; 132 u8 flags;
131 u8 key[0]; 133 u8 key[0];
132}; 134};
@@ -187,6 +189,7 @@ extern struct neighbour * neigh_lookup(struct neigh_table *tbl,
187 const void *pkey, 189 const void *pkey,
188 struct net_device *dev); 190 struct net_device *dev);
189extern struct neighbour * neigh_lookup_nodev(struct neigh_table *tbl, 191extern struct neighbour * neigh_lookup_nodev(struct neigh_table *tbl,
192 struct net *net,
190 const void *pkey); 193 const void *pkey);
191extern struct neighbour * neigh_create(struct neigh_table *tbl, 194extern struct neighbour * neigh_create(struct neigh_table *tbl,
192 const void *pkey, 195 const void *pkey,
@@ -211,8 +214,8 @@ extern unsigned long neigh_rand_reach_time(unsigned long base);
211 214
212extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, 215extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
213 struct sk_buff *skb); 216 struct sk_buff *skb);
214extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, const void *key, struct net_device *dev, int creat); 217extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat);
215extern int pneigh_delete(struct neigh_table *tbl, const void *key, struct net_device *dev); 218extern int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev);
216 219
217extern void neigh_app_ns(struct neighbour *n); 220extern void neigh_app_ns(struct neighbour *n);
218extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie); 221extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
@@ -220,6 +223,7 @@ extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct n
220extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *)); 223extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
221 224
222struct neigh_seq_state { 225struct neigh_seq_state {
226 struct net *net;
223 struct neigh_table *tbl; 227 struct neigh_table *tbl;
224 void *(*neigh_sub_iter)(struct neigh_seq_state *state, 228 void *(*neigh_sub_iter)(struct neigh_seq_state *state,
225 struct neighbour *n, loff_t *pos); 229 struct neighbour *n, loff_t *pos);
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 741742f00797..47fbdc0c5f72 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -949,6 +949,11 @@ static int arp_seq_open(struct inode *inode, struct file *file)
949 949
950 seq = file->private_data; 950 seq = file->private_data;
951 seq->private = state; 951 seq->private = state;
952 state->ns.net = get_proc_net(inode);
953 if (!state->ns.net) {
954 seq_release_private(inode, file);
955 rc = -ENXIO;
956 }
952out: 957out:
953 return rc; 958 return rc;
954 959
@@ -957,11 +962,19 @@ out_kfree:
957 goto out; 962 goto out;
958} 963}
959 964
965static int arp_seq_release(struct inode *inode, struct file *file)
966{
967 struct seq_file *seq = file->private_data;
968 struct clip_seq_state *state = seq->private;
969 put_net(state->ns.net);
970 return seq_release_private(inode, file);
971}
972
960static const struct file_operations arp_seq_fops = { 973static const struct file_operations arp_seq_fops = {
961 .open = arp_seq_open, 974 .open = arp_seq_open,
962 .read = seq_read, 975 .read = seq_read,
963 .llseek = seq_lseek, 976 .llseek = seq_lseek,
964 .release = seq_release_private, 977 .release = arp_seq_release,
965 .owner = THIS_MODULE 978 .owner = THIS_MODULE
966}; 979};
967#endif 980#endif
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 9a283fcde9a6..bd899d557737 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -375,7 +375,8 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
375 return n; 375 return n;
376} 376}
377 377
378struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, const void *pkey) 378struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
379 const void *pkey)
379{ 380{
380 struct neighbour *n; 381 struct neighbour *n;
381 int key_len = tbl->key_len; 382 int key_len = tbl->key_len;
@@ -385,7 +386,8 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, const void *pkey)
385 386
386 read_lock_bh(&tbl->lock); 387 read_lock_bh(&tbl->lock);
387 for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { 388 for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
388 if (!memcmp(n->primary_key, pkey, key_len)) { 389 if (!memcmp(n->primary_key, pkey, key_len) &&
390 (net == n->dev->nd_net)) {
389 neigh_hold(n); 391 neigh_hold(n);
390 NEIGH_CACHE_STAT_INC(tbl, hits); 392 NEIGH_CACHE_STAT_INC(tbl, hits);
391 break; 393 break;
@@ -463,7 +465,8 @@ out_neigh_release:
463 goto out; 465 goto out;
464} 466}
465 467
466struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey, 468struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
469 struct net *net, const void *pkey,
467 struct net_device *dev, int creat) 470 struct net_device *dev, int creat)
468{ 471{
469 struct pneigh_entry *n; 472 struct pneigh_entry *n;
@@ -479,6 +482,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey,
479 482
480 for (n = tbl->phash_buckets[hash_val]; n; n = n->next) { 483 for (n = tbl->phash_buckets[hash_val]; n; n = n->next) {
481 if (!memcmp(n->key, pkey, key_len) && 484 if (!memcmp(n->key, pkey, key_len) &&
485 (n->net == net) &&
482 (n->dev == dev || !n->dev)) { 486 (n->dev == dev || !n->dev)) {
483 read_unlock_bh(&tbl->lock); 487 read_unlock_bh(&tbl->lock);
484 goto out; 488 goto out;
@@ -495,6 +499,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey,
495 if (!n) 499 if (!n)
496 goto out; 500 goto out;
497 501
502 n->net = hold_net(net);
498 memcpy(n->key, pkey, key_len); 503 memcpy(n->key, pkey, key_len);
499 n->dev = dev; 504 n->dev = dev;
500 if (dev) 505 if (dev)
@@ -517,7 +522,7 @@ out:
517} 522}
518 523
519 524
520int pneigh_delete(struct neigh_table *tbl, const void *pkey, 525int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey,
521 struct net_device *dev) 526 struct net_device *dev)
522{ 527{
523 struct pneigh_entry *n, **np; 528 struct pneigh_entry *n, **np;
@@ -532,13 +537,15 @@ int pneigh_delete(struct neigh_table *tbl, const void *pkey,
532 write_lock_bh(&tbl->lock); 537 write_lock_bh(&tbl->lock);
533 for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL; 538 for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL;
534 np = &n->next) { 539 np = &n->next) {
535 if (!memcmp(n->key, pkey, key_len) && n->dev == dev) { 540 if (!memcmp(n->key, pkey, key_len) && n->dev == dev &&
541 (n->net == net)) {
536 *np = n->next; 542 *np = n->next;
537 write_unlock_bh(&tbl->lock); 543 write_unlock_bh(&tbl->lock);
538 if (tbl->pdestructor) 544 if (tbl->pdestructor)
539 tbl->pdestructor(n); 545 tbl->pdestructor(n);
540 if (n->dev) 546 if (n->dev)
541 dev_put(n->dev); 547 dev_put(n->dev);
548 release_net(n->net);
542 kfree(n); 549 kfree(n);
543 return 0; 550 return 0;
544 } 551 }
@@ -561,6 +568,7 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
561 tbl->pdestructor(n); 568 tbl->pdestructor(n);
562 if (n->dev) 569 if (n->dev)
563 dev_put(n->dev); 570 dev_put(n->dev);
571 release_net(n->net);
564 kfree(n); 572 kfree(n);
565 continue; 573 continue;
566 } 574 }
@@ -1261,12 +1269,37 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
1261 spin_unlock(&tbl->proxy_queue.lock); 1269 spin_unlock(&tbl->proxy_queue.lock);
1262} 1270}
1263 1271
1272static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
1273 struct net *net, int ifindex)
1274{
1275 struct neigh_parms *p;
1276
1277 for (p = &tbl->parms; p; p = p->next) {
1278 if (p->net != net)
1279 continue;
1280 if ((p->dev && p->dev->ifindex == ifindex) ||
1281 (!p->dev && !ifindex))
1282 return p;
1283 }
1284
1285 return NULL;
1286}
1264 1287
1265struct neigh_parms *neigh_parms_alloc(struct net_device *dev, 1288struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
1266 struct neigh_table *tbl) 1289 struct neigh_table *tbl)
1267{ 1290{
1268 struct neigh_parms *p = kmemdup(&tbl->parms, sizeof(*p), GFP_KERNEL); 1291 struct neigh_parms *p, *ref;
1292 struct net *net;
1293
1294 net = &init_net;
1295 if (dev)
1296 net = dev->nd_net;
1297
1298 ref = lookup_neigh_params(tbl, net, 0);
1299 if (!ref)
1300 return NULL;
1269 1301
1302 p = kmemdup(ref, sizeof(*p), GFP_KERNEL);
1270 if (p) { 1303 if (p) {
1271 p->tbl = tbl; 1304 p->tbl = tbl;
1272 atomic_set(&p->refcnt, 1); 1305 atomic_set(&p->refcnt, 1);
@@ -1282,6 +1315,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
1282 dev_hold(dev); 1315 dev_hold(dev);
1283 p->dev = dev; 1316 p->dev = dev;
1284 } 1317 }
1318 p->net = hold_net(net);
1285 p->sysctl_table = NULL; 1319 p->sysctl_table = NULL;
1286 write_lock_bh(&tbl->lock); 1320 write_lock_bh(&tbl->lock);
1287 p->next = tbl->parms.next; 1321 p->next = tbl->parms.next;
@@ -1323,6 +1357,7 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
1323 1357
1324void neigh_parms_destroy(struct neigh_parms *parms) 1358void neigh_parms_destroy(struct neigh_parms *parms)
1325{ 1359{
1360 release_net(parms->net);
1326 kfree(parms); 1361 kfree(parms);
1327} 1362}
1328 1363
@@ -1333,6 +1368,7 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
1333 unsigned long now = jiffies; 1368 unsigned long now = jiffies;
1334 unsigned long phsize; 1369 unsigned long phsize;
1335 1370
1371 tbl->parms.net = &init_net;
1336 atomic_set(&tbl->parms.refcnt, 1); 1372 atomic_set(&tbl->parms.refcnt, 1);
1337 INIT_RCU_HEAD(&tbl->parms.rcu_head); 1373 INIT_RCU_HEAD(&tbl->parms.rcu_head);
1338 tbl->parms.reachable_time = 1374 tbl->parms.reachable_time =
@@ -1446,9 +1482,6 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1446 struct net_device *dev = NULL; 1482 struct net_device *dev = NULL;
1447 int err = -EINVAL; 1483 int err = -EINVAL;
1448 1484
1449 if (net != &init_net)
1450 return -EINVAL;
1451
1452 if (nlmsg_len(nlh) < sizeof(*ndm)) 1485 if (nlmsg_len(nlh) < sizeof(*ndm))
1453 goto out; 1486 goto out;
1454 1487
@@ -1477,7 +1510,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1477 goto out_dev_put; 1510 goto out_dev_put;
1478 1511
1479 if (ndm->ndm_flags & NTF_PROXY) { 1512 if (ndm->ndm_flags & NTF_PROXY) {
1480 err = pneigh_delete(tbl, nla_data(dst_attr), dev); 1513 err = pneigh_delete(tbl, net, nla_data(dst_attr), dev);
1481 goto out_dev_put; 1514 goto out_dev_put;
1482 } 1515 }
1483 1516
@@ -1515,9 +1548,6 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1515 struct net_device *dev = NULL; 1548 struct net_device *dev = NULL;
1516 int err; 1549 int err;
1517 1550
1518 if (net != &init_net)
1519 return -EINVAL;
1520
1521 err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); 1551 err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
1522 if (err < 0) 1552 if (err < 0)
1523 goto out; 1553 goto out;
@@ -1557,7 +1587,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1557 struct pneigh_entry *pn; 1587 struct pneigh_entry *pn;
1558 1588
1559 err = -ENOBUFS; 1589 err = -ENOBUFS;
1560 pn = pneigh_lookup(tbl, dst, dev, 1); 1590 pn = pneigh_lookup(tbl, net, dst, dev, 1);
1561 if (pn) { 1591 if (pn) {
1562 pn->flags = ndm->ndm_flags; 1592 pn->flags = ndm->ndm_flags;
1563 err = 0; 1593 err = 0;
@@ -1752,19 +1782,6 @@ errout:
1752 return -EMSGSIZE; 1782 return -EMSGSIZE;
1753} 1783}
1754 1784
1755static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
1756 int ifindex)
1757{
1758 struct neigh_parms *p;
1759
1760 for (p = &tbl->parms; p; p = p->next)
1761 if ((p->dev && p->dev->ifindex == ifindex) ||
1762 (!p->dev && !ifindex))
1763 return p;
1764
1765 return NULL;
1766}
1767
1768static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = { 1785static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
1769 [NDTA_NAME] = { .type = NLA_STRING }, 1786 [NDTA_NAME] = { .type = NLA_STRING },
1770 [NDTA_THRESH1] = { .type = NLA_U32 }, 1787 [NDTA_THRESH1] = { .type = NLA_U32 },
@@ -1798,9 +1815,6 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1798 struct nlattr *tb[NDTA_MAX+1]; 1815 struct nlattr *tb[NDTA_MAX+1];
1799 int err; 1816 int err;
1800 1817
1801 if (net != &init_net)
1802 return -EINVAL;
1803
1804 err = nlmsg_parse(nlh, sizeof(*ndtmsg), tb, NDTA_MAX, 1818 err = nlmsg_parse(nlh, sizeof(*ndtmsg), tb, NDTA_MAX,
1805 nl_neightbl_policy); 1819 nl_neightbl_policy);
1806 if (err < 0) 1820 if (err < 0)
@@ -1845,7 +1859,7 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1845 if (tbp[NDTPA_IFINDEX]) 1859 if (tbp[NDTPA_IFINDEX])
1846 ifindex = nla_get_u32(tbp[NDTPA_IFINDEX]); 1860 ifindex = nla_get_u32(tbp[NDTPA_IFINDEX]);
1847 1861
1848 p = lookup_neigh_params(tbl, ifindex); 1862 p = lookup_neigh_params(tbl, net, ifindex);
1849 if (p == NULL) { 1863 if (p == NULL) {
1850 err = -ENOENT; 1864 err = -ENOENT;
1851 goto errout_tbl_lock; 1865 goto errout_tbl_lock;
@@ -1926,9 +1940,6 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
1926 int neigh_skip = cb->args[1]; 1940 int neigh_skip = cb->args[1];
1927 struct neigh_table *tbl; 1941 struct neigh_table *tbl;
1928 1942
1929 if (net != &init_net)
1930 return 0;
1931
1932 family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family; 1943 family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family;
1933 1944
1934 read_lock(&neigh_tbl_lock); 1945 read_lock(&neigh_tbl_lock);
@@ -1943,8 +1954,11 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
1943 NLM_F_MULTI) <= 0) 1954 NLM_F_MULTI) <= 0)
1944 break; 1955 break;
1945 1956
1946 for (nidx = 0, p = tbl->parms.next; p; p = p->next, nidx++) { 1957 for (nidx = 0, p = tbl->parms.next; p; p = p->next) {
1947 if (nidx < neigh_skip) 1958 if (net != p->net)
1959 continue;
1960
1961 if (nidx++ < neigh_skip)
1948 continue; 1962 continue;
1949 1963
1950 if (neightbl_fill_param_info(skb, tbl, p, 1964 if (neightbl_fill_param_info(skb, tbl, p,
@@ -2020,6 +2034,7 @@ static void neigh_update_notify(struct neighbour *neigh)
2020static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, 2034static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
2021 struct netlink_callback *cb) 2035 struct netlink_callback *cb)
2022{ 2036{
2037 struct net * net = skb->sk->sk_net;
2023 struct neighbour *n; 2038 struct neighbour *n;
2024 int rc, h, s_h = cb->args[1]; 2039 int rc, h, s_h = cb->args[1];
2025 int idx, s_idx = idx = cb->args[2]; 2040 int idx, s_idx = idx = cb->args[2];
@@ -2030,8 +2045,12 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
2030 continue; 2045 continue;
2031 if (h > s_h) 2046 if (h > s_h)
2032 s_idx = 0; 2047 s_idx = 0;
2033 for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next, idx++) { 2048 for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) {
2034 if (idx < s_idx) 2049 int lidx;
2050 if (n->dev->nd_net != net)
2051 continue;
2052 lidx = idx++;
2053 if (lidx < s_idx)
2035 continue; 2054 continue;
2036 if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid, 2055 if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
2037 cb->nlh->nlmsg_seq, 2056 cb->nlh->nlmsg_seq,
@@ -2053,13 +2072,9 @@ out:
2053 2072
2054static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) 2073static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
2055{ 2074{
2056 struct net *net = skb->sk->sk_net;
2057 struct neigh_table *tbl; 2075 struct neigh_table *tbl;
2058 int t, family, s_t; 2076 int t, family, s_t;
2059 2077
2060 if (net != &init_net)
2061 return 0;
2062
2063 read_lock(&neigh_tbl_lock); 2078 read_lock(&neigh_tbl_lock);
2064 family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family; 2079 family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family;
2065 s_t = cb->args[0]; 2080 s_t = cb->args[0];
@@ -2127,6 +2142,7 @@ EXPORT_SYMBOL(__neigh_for_each_release);
2127static struct neighbour *neigh_get_first(struct seq_file *seq) 2142static struct neighbour *neigh_get_first(struct seq_file *seq)
2128{ 2143{
2129 struct neigh_seq_state *state = seq->private; 2144 struct neigh_seq_state *state = seq->private;
2145 struct net *net = state->net;
2130 struct neigh_table *tbl = state->tbl; 2146 struct neigh_table *tbl = state->tbl;
2131 struct neighbour *n = NULL; 2147 struct neighbour *n = NULL;
2132 int bucket = state->bucket; 2148 int bucket = state->bucket;
@@ -2136,6 +2152,8 @@ static struct neighbour *neigh_get_first(struct seq_file *seq)
2136 n = tbl->hash_buckets[bucket]; 2152 n = tbl->hash_buckets[bucket];
2137 2153
2138 while (n) { 2154 while (n) {
2155 if (n->dev->nd_net != net)
2156 goto next;
2139 if (state->neigh_sub_iter) { 2157 if (state->neigh_sub_iter) {
2140 loff_t fakep = 0; 2158 loff_t fakep = 0;
2141 void *v; 2159 void *v;
@@ -2165,6 +2183,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
2165 loff_t *pos) 2183 loff_t *pos)
2166{ 2184{
2167 struct neigh_seq_state *state = seq->private; 2185 struct neigh_seq_state *state = seq->private;
2186 struct net *net = state->net;
2168 struct neigh_table *tbl = state->tbl; 2187 struct neigh_table *tbl = state->tbl;
2169 2188
2170 if (state->neigh_sub_iter) { 2189 if (state->neigh_sub_iter) {
@@ -2176,6 +2195,8 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
2176 2195
2177 while (1) { 2196 while (1) {
2178 while (n) { 2197 while (n) {
2198 if (n->dev->nd_net != net)
2199 goto next;
2179 if (state->neigh_sub_iter) { 2200 if (state->neigh_sub_iter) {
2180 void *v = state->neigh_sub_iter(state, n, pos); 2201 void *v = state->neigh_sub_iter(state, n, pos);
2181 if (v) 2202 if (v)
@@ -2222,6 +2243,7 @@ static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos)
2222static struct pneigh_entry *pneigh_get_first(struct seq_file *seq) 2243static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
2223{ 2244{
2224 struct neigh_seq_state *state = seq->private; 2245 struct neigh_seq_state *state = seq->private;
2246 struct net * net = state->net;
2225 struct neigh_table *tbl = state->tbl; 2247 struct neigh_table *tbl = state->tbl;
2226 struct pneigh_entry *pn = NULL; 2248 struct pneigh_entry *pn = NULL;
2227 int bucket = state->bucket; 2249 int bucket = state->bucket;
@@ -2229,6 +2251,8 @@ static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
2229 state->flags |= NEIGH_SEQ_IS_PNEIGH; 2251 state->flags |= NEIGH_SEQ_IS_PNEIGH;
2230 for (bucket = 0; bucket <= PNEIGH_HASHMASK; bucket++) { 2252 for (bucket = 0; bucket <= PNEIGH_HASHMASK; bucket++) {
2231 pn = tbl->phash_buckets[bucket]; 2253 pn = tbl->phash_buckets[bucket];
2254 while (pn && (pn->net != net))
2255 pn = pn->next;
2232 if (pn) 2256 if (pn)
2233 break; 2257 break;
2234 } 2258 }
@@ -2242,6 +2266,7 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
2242 loff_t *pos) 2266 loff_t *pos)
2243{ 2267{
2244 struct neigh_seq_state *state = seq->private; 2268 struct neigh_seq_state *state = seq->private;
2269 struct net * net = state->net;
2245 struct neigh_table *tbl = state->tbl; 2270 struct neigh_table *tbl = state->tbl;
2246 2271
2247 pn = pn->next; 2272 pn = pn->next;
@@ -2249,6 +2274,8 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
2249 if (++state->bucket > PNEIGH_HASHMASK) 2274 if (++state->bucket > PNEIGH_HASHMASK)
2250 break; 2275 break;
2251 pn = tbl->phash_buckets[state->bucket]; 2276 pn = tbl->phash_buckets[state->bucket];
2277 while (pn && (pn->net != net))
2278 pn = pn->next;
2252 if (pn) 2279 if (pn)
2253 break; 2280 break;
2254 } 2281 }
@@ -2450,6 +2477,7 @@ static inline size_t neigh_nlmsg_size(void)
2450 2477
2451static void __neigh_notify(struct neighbour *n, int type, int flags) 2478static void __neigh_notify(struct neighbour *n, int type, int flags)
2452{ 2479{
2480 struct net *net = n->dev->nd_net;
2453 struct sk_buff *skb; 2481 struct sk_buff *skb;
2454 int err = -ENOBUFS; 2482 int err = -ENOBUFS;
2455 2483
@@ -2464,10 +2492,10 @@ static void __neigh_notify(struct neighbour *n, int type, int flags)
2464 kfree_skb(skb); 2492 kfree_skb(skb);
2465 goto errout; 2493 goto errout;
2466 } 2494 }
2467 err = rtnl_notify(skb, &init_net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); 2495 err = rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
2468errout: 2496errout:
2469 if (err < 0) 2497 if (err < 0)
2470 rtnl_set_sk_err(&init_net, RTNLGRP_NEIGH, err); 2498 rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
2471} 2499}
2472 2500
2473#ifdef CONFIG_ARPD 2501#ifdef CONFIG_ARPD
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index e851b143cca3..1ca13b17974d 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -580,8 +580,8 @@ static const struct seq_operations dn_neigh_seq_ops = {
580 580
581static int dn_neigh_seq_open(struct inode *inode, struct file *file) 581static int dn_neigh_seq_open(struct inode *inode, struct file *file)
582{ 582{
583 return seq_open_private(file, &dn_neigh_seq_ops, 583 return seq_open_net(inode, file, &dn_neigh_seq_ops,
584 sizeof(struct neigh_seq_state)); 584 sizeof(struct neigh_seq_state));
585} 585}
586 586
587static const struct file_operations dn_neigh_seq_fops = { 587static const struct file_operations dn_neigh_seq_fops = {
@@ -589,7 +589,7 @@ static const struct file_operations dn_neigh_seq_fops = {
589 .open = dn_neigh_seq_open, 589 .open = dn_neigh_seq_open,
590 .read = seq_read, 590 .read = seq_read,
591 .llseek = seq_lseek, 591 .llseek = seq_lseek,
592 .release = seq_release_private, 592 .release = seq_release_net,
593}; 593};
594 594
595#endif 595#endif
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 1ae5efcdbd5f..938ba7da217c 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -984,7 +984,7 @@ source_ok:
984 * here 984 * here
985 */ 985 */
986 if (!try_hard) { 986 if (!try_hard) {
987 neigh = neigh_lookup_nodev(&dn_neigh_table, &fl.fld_dst); 987 neigh = neigh_lookup_nodev(&dn_neigh_table, &init_net, &fl.fld_dst);
988 if (neigh) { 988 if (neigh) {
989 if ((oldflp->oif && 989 if ((oldflp->oif &&
990 (neigh->dev->ifindex != oldflp->oif)) || 990 (neigh->dev->ifindex != oldflp->oif)) ||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index fdf12d1c350e..9eb6d3ab2977 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -837,7 +837,7 @@ static int arp_process(struct sk_buff *skb)
837 } else if (IN_DEV_FORWARD(in_dev)) { 837 } else if (IN_DEV_FORWARD(in_dev)) {
838 if ((rt->rt_flags&RTCF_DNAT) || 838 if ((rt->rt_flags&RTCF_DNAT) ||
839 (addr_type == RTN_UNICAST && rt->u.dst.dev != dev && 839 (addr_type == RTN_UNICAST && rt->u.dst.dev != dev &&
840 (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) { 840 (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &init_net, &tip, dev, 0)))) {
841 n = neigh_event_ns(&arp_tbl, sha, &sip, dev); 841 n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
842 if (n) 842 if (n)
843 neigh_release(n); 843 neigh_release(n);
@@ -980,7 +980,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
980 return -ENODEV; 980 return -ENODEV;
981 } 981 }
982 if (mask) { 982 if (mask) {
983 if (pneigh_lookup(&arp_tbl, &ip, dev, 1) == NULL) 983 if (pneigh_lookup(&arp_tbl, &init_net, &ip, dev, 1) == NULL)
984 return -ENOBUFS; 984 return -ENOBUFS;
985 return 0; 985 return 0;
986 } 986 }
@@ -1089,7 +1089,7 @@ static int arp_req_delete_public(struct net *net, struct arpreq *r,
1089 __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr; 1089 __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
1090 1090
1091 if (mask == htonl(0xFFFFFFFF)) 1091 if (mask == htonl(0xFFFFFFFF))
1092 return pneigh_delete(&arp_tbl, &ip, dev); 1092 return pneigh_delete(&arp_tbl, &init_net, &ip, dev);
1093 1093
1094 if (mask) 1094 if (mask)
1095 return -EINVAL; 1095 return -EINVAL;
@@ -1375,8 +1375,8 @@ static const struct seq_operations arp_seq_ops = {
1375 1375
1376static int arp_seq_open(struct inode *inode, struct file *file) 1376static int arp_seq_open(struct inode *inode, struct file *file)
1377{ 1377{
1378 return seq_open_private(file, &arp_seq_ops, 1378 return seq_open_net(inode, file, &arp_seq_ops,
1379 sizeof(struct neigh_seq_state)); 1379 sizeof(struct neigh_seq_state));
1380} 1380}
1381 1381
1382static const struct file_operations arp_seq_fops = { 1382static const struct file_operations arp_seq_fops = {
@@ -1384,7 +1384,7 @@ static const struct file_operations arp_seq_fops = {
1384 .open = arp_seq_open, 1384 .open = arp_seq_open,
1385 .read = seq_read, 1385 .read = seq_read,
1386 .llseek = seq_lseek, 1386 .llseek = seq_lseek,
1387 .release = seq_release_private, 1387 .release = seq_release_net,
1388}; 1388};
1389 1389
1390static int __init arp_proc_init(void) 1390static int __init arp_proc_init(void)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 4686646058d3..ba7c8aaf2782 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -449,7 +449,7 @@ int ip6_forward(struct sk_buff *skb)
449 449
450 /* XXX: idev->cnf.proxy_ndp? */ 450 /* XXX: idev->cnf.proxy_ndp? */
451 if (ipv6_devconf.proxy_ndp && 451 if (ipv6_devconf.proxy_ndp &&
452 pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) { 452 pneigh_lookup(&nd_tbl, &init_net, &hdr->daddr, skb->dev, 0)) {
453 int proxied = ip6_forward_proxy_check(skb); 453 int proxied = ip6_forward_proxy_check(skb);
454 if (proxied > 0) 454 if (proxied > 0)
455 return ip6_input(skb); 455 return ip6_input(skb);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index b87f9d245e2e..b66a1f81bd83 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -789,7 +789,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
789 if (ipv6_chk_acast_addr(dev, &msg->target) || 789 if (ipv6_chk_acast_addr(dev, &msg->target) ||
790 (idev->cnf.forwarding && 790 (idev->cnf.forwarding &&
791 (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && 791 (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
792 (pneigh = pneigh_lookup(&nd_tbl, 792 (pneigh = pneigh_lookup(&nd_tbl, &init_net,
793 &msg->target, dev, 0)) != NULL)) { 793 &msg->target, dev, 0)) != NULL)) {
794 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && 794 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
795 skb->pkt_type != PACKET_HOST && 795 skb->pkt_type != PACKET_HOST &&
@@ -930,7 +930,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
930 */ 930 */
931 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && 931 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
932 ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp && 932 ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
933 pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) { 933 pneigh_lookup(&nd_tbl, &init_net, &msg->target, dev, 0)) {
934 /* XXX: idev->cnf.prixy_ndp */ 934 /* XXX: idev->cnf.prixy_ndp */
935 goto out; 935 goto out;
936 } 936 }