diff options
Diffstat (limited to 'net/core/neighbour.c')
-rw-r--r-- | net/core/neighbour.c | 171 |
1 files changed, 84 insertions, 87 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 19b8e003f150..75075c303c44 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -123,6 +123,7 @@ unsigned long neigh_rand_reach_time(unsigned long base) | |||
123 | { | 123 | { |
124 | return (base ? (net_random() % base) + (base >> 1) : 0); | 124 | return (base ? (net_random() % base) + (base >> 1) : 0); |
125 | } | 125 | } |
126 | EXPORT_SYMBOL(neigh_rand_reach_time); | ||
126 | 127 | ||
127 | 128 | ||
128 | static int neigh_forced_gc(struct neigh_table *tbl) | 129 | static int neigh_forced_gc(struct neigh_table *tbl) |
@@ -241,6 +242,7 @@ void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev) | |||
241 | neigh_flush_dev(tbl, dev); | 242 | neigh_flush_dev(tbl, dev); |
242 | write_unlock_bh(&tbl->lock); | 243 | write_unlock_bh(&tbl->lock); |
243 | } | 244 | } |
245 | EXPORT_SYMBOL(neigh_changeaddr); | ||
244 | 246 | ||
245 | int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev) | 247 | int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev) |
246 | { | 248 | { |
@@ -253,6 +255,7 @@ int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev) | |||
253 | pneigh_queue_purge(&tbl->proxy_queue); | 255 | pneigh_queue_purge(&tbl->proxy_queue); |
254 | return 0; | 256 | return 0; |
255 | } | 257 | } |
258 | EXPORT_SYMBOL(neigh_ifdown); | ||
256 | 259 | ||
257 | static struct neighbour *neigh_alloc(struct neigh_table *tbl) | 260 | static struct neighbour *neigh_alloc(struct neigh_table *tbl) |
258 | { | 261 | { |
@@ -374,6 +377,7 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, | |||
374 | read_unlock_bh(&tbl->lock); | 377 | read_unlock_bh(&tbl->lock); |
375 | return n; | 378 | return n; |
376 | } | 379 | } |
380 | EXPORT_SYMBOL(neigh_lookup); | ||
377 | 381 | ||
378 | struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, | 382 | struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, |
379 | const void *pkey) | 383 | const void *pkey) |
@@ -388,7 +392,7 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, | |||
388 | hash_val = tbl->hash(pkey, NULL); | 392 | hash_val = tbl->hash(pkey, NULL); |
389 | for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { | 393 | for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { |
390 | if (!memcmp(n->primary_key, pkey, key_len) && | 394 | if (!memcmp(n->primary_key, pkey, key_len) && |
391 | (net == n->dev->nd_net)) { | 395 | net_eq(dev_net(n->dev), net)) { |
392 | neigh_hold(n); | 396 | neigh_hold(n); |
393 | NEIGH_CACHE_STAT_INC(tbl, hits); | 397 | NEIGH_CACHE_STAT_INC(tbl, hits); |
394 | break; | 398 | break; |
@@ -397,6 +401,7 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, | |||
397 | read_unlock_bh(&tbl->lock); | 401 | read_unlock_bh(&tbl->lock); |
398 | return n; | 402 | return n; |
399 | } | 403 | } |
404 | EXPORT_SYMBOL(neigh_lookup_nodev); | ||
400 | 405 | ||
401 | struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, | 406 | struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, |
402 | struct net_device *dev) | 407 | struct net_device *dev) |
@@ -465,28 +470,44 @@ out_neigh_release: | |||
465 | neigh_release(n); | 470 | neigh_release(n); |
466 | goto out; | 471 | goto out; |
467 | } | 472 | } |
473 | EXPORT_SYMBOL(neigh_create); | ||
468 | 474 | ||
469 | struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl, | 475 | static u32 pneigh_hash(const void *pkey, int key_len) |
470 | struct net *net, const void *pkey, struct net_device *dev) | ||
471 | { | 476 | { |
472 | struct pneigh_entry *n; | ||
473 | int key_len = tbl->key_len; | ||
474 | u32 hash_val = *(u32 *)(pkey + key_len - 4); | 477 | u32 hash_val = *(u32 *)(pkey + key_len - 4); |
475 | |||
476 | hash_val ^= (hash_val >> 16); | 478 | hash_val ^= (hash_val >> 16); |
477 | hash_val ^= hash_val >> 8; | 479 | hash_val ^= hash_val >> 8; |
478 | hash_val ^= hash_val >> 4; | 480 | hash_val ^= hash_val >> 4; |
479 | hash_val &= PNEIGH_HASHMASK; | 481 | hash_val &= PNEIGH_HASHMASK; |
482 | return hash_val; | ||
483 | } | ||
480 | 484 | ||
481 | for (n = tbl->phash_buckets[hash_val]; n; n = n->next) { | 485 | static struct pneigh_entry *__pneigh_lookup_1(struct pneigh_entry *n, |
486 | struct net *net, | ||
487 | const void *pkey, | ||
488 | int key_len, | ||
489 | struct net_device *dev) | ||
490 | { | ||
491 | while (n) { | ||
482 | if (!memcmp(n->key, pkey, key_len) && | 492 | if (!memcmp(n->key, pkey, key_len) && |
483 | (n->net == net) && | 493 | net_eq(pneigh_net(n), net) && |
484 | (n->dev == dev || !n->dev)) | 494 | (n->dev == dev || !n->dev)) |
485 | break; | 495 | return n; |
496 | n = n->next; | ||
486 | } | 497 | } |
498 | return NULL; | ||
499 | } | ||
487 | 500 | ||
488 | return n; | 501 | struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl, |
502 | struct net *net, const void *pkey, struct net_device *dev) | ||
503 | { | ||
504 | int key_len = tbl->key_len; | ||
505 | u32 hash_val = pneigh_hash(pkey, key_len); | ||
506 | |||
507 | return __pneigh_lookup_1(tbl->phash_buckets[hash_val], | ||
508 | net, pkey, key_len, dev); | ||
489 | } | 509 | } |
510 | EXPORT_SYMBOL_GPL(__pneigh_lookup); | ||
490 | 511 | ||
491 | struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, | 512 | struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, |
492 | struct net *net, const void *pkey, | 513 | struct net *net, const void *pkey, |
@@ -494,26 +515,14 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, | |||
494 | { | 515 | { |
495 | struct pneigh_entry *n; | 516 | struct pneigh_entry *n; |
496 | int key_len = tbl->key_len; | 517 | int key_len = tbl->key_len; |
497 | u32 hash_val = *(u32 *)(pkey + key_len - 4); | 518 | u32 hash_val = pneigh_hash(pkey, key_len); |
498 | |||
499 | hash_val ^= (hash_val >> 16); | ||
500 | hash_val ^= hash_val >> 8; | ||
501 | hash_val ^= hash_val >> 4; | ||
502 | hash_val &= PNEIGH_HASHMASK; | ||
503 | 519 | ||
504 | read_lock_bh(&tbl->lock); | 520 | read_lock_bh(&tbl->lock); |
505 | 521 | n = __pneigh_lookup_1(tbl->phash_buckets[hash_val], | |
506 | for (n = tbl->phash_buckets[hash_val]; n; n = n->next) { | 522 | net, pkey, key_len, dev); |
507 | if (!memcmp(n->key, pkey, key_len) && | ||
508 | (n->net == net) && | ||
509 | (n->dev == dev || !n->dev)) { | ||
510 | read_unlock_bh(&tbl->lock); | ||
511 | goto out; | ||
512 | } | ||
513 | } | ||
514 | read_unlock_bh(&tbl->lock); | 523 | read_unlock_bh(&tbl->lock); |
515 | n = NULL; | 524 | |
516 | if (!creat) | 525 | if (n || !creat) |
517 | goto out; | 526 | goto out; |
518 | 527 | ||
519 | ASSERT_RTNL(); | 528 | ASSERT_RTNL(); |
@@ -522,7 +531,9 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, | |||
522 | if (!n) | 531 | if (!n) |
523 | goto out; | 532 | goto out; |
524 | 533 | ||
534 | #ifdef CONFIG_NET_NS | ||
525 | n->net = hold_net(net); | 535 | n->net = hold_net(net); |
536 | #endif | ||
526 | memcpy(n->key, pkey, key_len); | 537 | memcpy(n->key, pkey, key_len); |
527 | n->dev = dev; | 538 | n->dev = dev; |
528 | if (dev) | 539 | if (dev) |
@@ -544,6 +555,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, | |||
544 | out: | 555 | out: |
545 | return n; | 556 | return n; |
546 | } | 557 | } |
558 | EXPORT_SYMBOL(pneigh_lookup); | ||
547 | 559 | ||
548 | 560 | ||
549 | int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey, | 561 | int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey, |
@@ -551,25 +563,20 @@ int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey, | |||
551 | { | 563 | { |
552 | struct pneigh_entry *n, **np; | 564 | struct pneigh_entry *n, **np; |
553 | int key_len = tbl->key_len; | 565 | int key_len = tbl->key_len; |
554 | u32 hash_val = *(u32 *)(pkey + key_len - 4); | 566 | u32 hash_val = pneigh_hash(pkey, key_len); |
555 | |||
556 | hash_val ^= (hash_val >> 16); | ||
557 | hash_val ^= hash_val >> 8; | ||
558 | hash_val ^= hash_val >> 4; | ||
559 | hash_val &= PNEIGH_HASHMASK; | ||
560 | 567 | ||
561 | write_lock_bh(&tbl->lock); | 568 | write_lock_bh(&tbl->lock); |
562 | for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL; | 569 | for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL; |
563 | np = &n->next) { | 570 | np = &n->next) { |
564 | if (!memcmp(n->key, pkey, key_len) && n->dev == dev && | 571 | if (!memcmp(n->key, pkey, key_len) && n->dev == dev && |
565 | (n->net == net)) { | 572 | net_eq(pneigh_net(n), net)) { |
566 | *np = n->next; | 573 | *np = n->next; |
567 | write_unlock_bh(&tbl->lock); | 574 | write_unlock_bh(&tbl->lock); |
568 | if (tbl->pdestructor) | 575 | if (tbl->pdestructor) |
569 | tbl->pdestructor(n); | 576 | tbl->pdestructor(n); |
570 | if (n->dev) | 577 | if (n->dev) |
571 | dev_put(n->dev); | 578 | dev_put(n->dev); |
572 | release_net(n->net); | 579 | release_net(pneigh_net(n)); |
573 | kfree(n); | 580 | kfree(n); |
574 | return 0; | 581 | return 0; |
575 | } | 582 | } |
@@ -592,7 +599,7 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev) | |||
592 | tbl->pdestructor(n); | 599 | tbl->pdestructor(n); |
593 | if (n->dev) | 600 | if (n->dev) |
594 | dev_put(n->dev); | 601 | dev_put(n->dev); |
595 | release_net(n->net); | 602 | release_net(pneigh_net(n)); |
596 | kfree(n); | 603 | kfree(n); |
597 | continue; | 604 | continue; |
598 | } | 605 | } |
@@ -651,6 +658,7 @@ void neigh_destroy(struct neighbour *neigh) | |||
651 | atomic_dec(&neigh->tbl->entries); | 658 | atomic_dec(&neigh->tbl->entries); |
652 | kmem_cache_free(neigh->tbl->kmem_cachep, neigh); | 659 | kmem_cache_free(neigh->tbl->kmem_cachep, neigh); |
653 | } | 660 | } |
661 | EXPORT_SYMBOL(neigh_destroy); | ||
654 | 662 | ||
655 | /* Neighbour state is suspicious; | 663 | /* Neighbour state is suspicious; |
656 | disable fast path. | 664 | disable fast path. |
@@ -931,6 +939,7 @@ out_unlock_bh: | |||
931 | write_unlock_bh(&neigh->lock); | 939 | write_unlock_bh(&neigh->lock); |
932 | return rc; | 940 | return rc; |
933 | } | 941 | } |
942 | EXPORT_SYMBOL(__neigh_event_send); | ||
934 | 943 | ||
935 | static void neigh_update_hhs(struct neighbour *neigh) | 944 | static void neigh_update_hhs(struct neighbour *neigh) |
936 | { | 945 | { |
@@ -1103,6 +1112,7 @@ out: | |||
1103 | 1112 | ||
1104 | return err; | 1113 | return err; |
1105 | } | 1114 | } |
1115 | EXPORT_SYMBOL(neigh_update); | ||
1106 | 1116 | ||
1107 | struct neighbour *neigh_event_ns(struct neigh_table *tbl, | 1117 | struct neighbour *neigh_event_ns(struct neigh_table *tbl, |
1108 | u8 *lladdr, void *saddr, | 1118 | u8 *lladdr, void *saddr, |
@@ -1115,6 +1125,7 @@ struct neighbour *neigh_event_ns(struct neigh_table *tbl, | |||
1115 | NEIGH_UPDATE_F_OVERRIDE); | 1125 | NEIGH_UPDATE_F_OVERRIDE); |
1116 | return neigh; | 1126 | return neigh; |
1117 | } | 1127 | } |
1128 | EXPORT_SYMBOL(neigh_event_ns); | ||
1118 | 1129 | ||
1119 | static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, | 1130 | static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, |
1120 | __be16 protocol) | 1131 | __be16 protocol) |
@@ -1169,6 +1180,7 @@ int neigh_compat_output(struct sk_buff *skb) | |||
1169 | 1180 | ||
1170 | return dev_queue_xmit(skb); | 1181 | return dev_queue_xmit(skb); |
1171 | } | 1182 | } |
1183 | EXPORT_SYMBOL(neigh_compat_output); | ||
1172 | 1184 | ||
1173 | /* Slow and careful. */ | 1185 | /* Slow and careful. */ |
1174 | 1186 | ||
@@ -1214,6 +1226,7 @@ out_kfree_skb: | |||
1214 | kfree_skb(skb); | 1226 | kfree_skb(skb); |
1215 | goto out; | 1227 | goto out; |
1216 | } | 1228 | } |
1229 | EXPORT_SYMBOL(neigh_resolve_output); | ||
1217 | 1230 | ||
1218 | /* As fast as possible without hh cache */ | 1231 | /* As fast as possible without hh cache */ |
1219 | 1232 | ||
@@ -1238,6 +1251,7 @@ int neigh_connected_output(struct sk_buff *skb) | |||
1238 | } | 1251 | } |
1239 | return err; | 1252 | return err; |
1240 | } | 1253 | } |
1254 | EXPORT_SYMBOL(neigh_connected_output); | ||
1241 | 1255 | ||
1242 | static void neigh_proxy_process(unsigned long arg) | 1256 | static void neigh_proxy_process(unsigned long arg) |
1243 | { | 1257 | { |
@@ -1299,6 +1313,7 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, | |||
1299 | mod_timer(&tbl->proxy_timer, sched_next); | 1313 | mod_timer(&tbl->proxy_timer, sched_next); |
1300 | spin_unlock(&tbl->proxy_queue.lock); | 1314 | spin_unlock(&tbl->proxy_queue.lock); |
1301 | } | 1315 | } |
1316 | EXPORT_SYMBOL(pneigh_enqueue); | ||
1302 | 1317 | ||
1303 | static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, | 1318 | static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, |
1304 | struct net *net, int ifindex) | 1319 | struct net *net, int ifindex) |
@@ -1306,9 +1321,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, | |||
1306 | struct neigh_parms *p; | 1321 | struct neigh_parms *p; |
1307 | 1322 | ||
1308 | for (p = &tbl->parms; p; p = p->next) { | 1323 | for (p = &tbl->parms; p; p = p->next) { |
1309 | if (p->net != net) | 1324 | if ((p->dev && p->dev->ifindex == ifindex && net_eq(neigh_parms_net(p), net)) || |
1310 | continue; | ||
1311 | if ((p->dev && p->dev->ifindex == ifindex) || | ||
1312 | (!p->dev && !ifindex)) | 1325 | (!p->dev && !ifindex)) |
1313 | return p; | 1326 | return p; |
1314 | } | 1327 | } |
@@ -1322,7 +1335,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, | |||
1322 | struct neigh_parms *p, *ref; | 1335 | struct neigh_parms *p, *ref; |
1323 | struct net *net; | 1336 | struct net *net; |
1324 | 1337 | ||
1325 | net = dev->nd_net; | 1338 | net = dev_net(dev); |
1326 | ref = lookup_neigh_params(tbl, net, 0); | 1339 | ref = lookup_neigh_params(tbl, net, 0); |
1327 | if (!ref) | 1340 | if (!ref) |
1328 | return NULL; | 1341 | return NULL; |
@@ -1342,7 +1355,9 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, | |||
1342 | 1355 | ||
1343 | dev_hold(dev); | 1356 | dev_hold(dev); |
1344 | p->dev = dev; | 1357 | p->dev = dev; |
1358 | #ifdef CONFIG_NET_NS | ||
1345 | p->net = hold_net(net); | 1359 | p->net = hold_net(net); |
1360 | #endif | ||
1346 | p->sysctl_table = NULL; | 1361 | p->sysctl_table = NULL; |
1347 | write_lock_bh(&tbl->lock); | 1362 | write_lock_bh(&tbl->lock); |
1348 | p->next = tbl->parms.next; | 1363 | p->next = tbl->parms.next; |
@@ -1351,6 +1366,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, | |||
1351 | } | 1366 | } |
1352 | return p; | 1367 | return p; |
1353 | } | 1368 | } |
1369 | EXPORT_SYMBOL(neigh_parms_alloc); | ||
1354 | 1370 | ||
1355 | static void neigh_rcu_free_parms(struct rcu_head *head) | 1371 | static void neigh_rcu_free_parms(struct rcu_head *head) |
1356 | { | 1372 | { |
@@ -1381,10 +1397,11 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) | |||
1381 | write_unlock_bh(&tbl->lock); | 1397 | write_unlock_bh(&tbl->lock); |
1382 | NEIGH_PRINTK1("neigh_parms_release: not found\n"); | 1398 | NEIGH_PRINTK1("neigh_parms_release: not found\n"); |
1383 | } | 1399 | } |
1400 | EXPORT_SYMBOL(neigh_parms_release); | ||
1384 | 1401 | ||
1385 | static void neigh_parms_destroy(struct neigh_parms *parms) | 1402 | static void neigh_parms_destroy(struct neigh_parms *parms) |
1386 | { | 1403 | { |
1387 | release_net(parms->net); | 1404 | release_net(neigh_parms_net(parms)); |
1388 | kfree(parms); | 1405 | kfree(parms); |
1389 | } | 1406 | } |
1390 | 1407 | ||
@@ -1395,7 +1412,9 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) | |||
1395 | unsigned long now = jiffies; | 1412 | unsigned long now = jiffies; |
1396 | unsigned long phsize; | 1413 | unsigned long phsize; |
1397 | 1414 | ||
1415 | #ifdef CONFIG_NET_NS | ||
1398 | tbl->parms.net = &init_net; | 1416 | tbl->parms.net = &init_net; |
1417 | #endif | ||
1399 | atomic_set(&tbl->parms.refcnt, 1); | 1418 | atomic_set(&tbl->parms.refcnt, 1); |
1400 | INIT_RCU_HEAD(&tbl->parms.rcu_head); | 1419 | INIT_RCU_HEAD(&tbl->parms.rcu_head); |
1401 | tbl->parms.reachable_time = | 1420 | tbl->parms.reachable_time = |
@@ -1441,6 +1460,7 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) | |||
1441 | tbl->last_flush = now; | 1460 | tbl->last_flush = now; |
1442 | tbl->last_rand = now + tbl->parms.reachable_time * 20; | 1461 | tbl->last_rand = now + tbl->parms.reachable_time * 20; |
1443 | } | 1462 | } |
1463 | EXPORT_SYMBOL(neigh_table_init_no_netlink); | ||
1444 | 1464 | ||
1445 | void neigh_table_init(struct neigh_table *tbl) | 1465 | void neigh_table_init(struct neigh_table *tbl) |
1446 | { | 1466 | { |
@@ -1462,6 +1482,7 @@ void neigh_table_init(struct neigh_table *tbl) | |||
1462 | dump_stack(); | 1482 | dump_stack(); |
1463 | } | 1483 | } |
1464 | } | 1484 | } |
1485 | EXPORT_SYMBOL(neigh_table_init); | ||
1465 | 1486 | ||
1466 | int neigh_table_clear(struct neigh_table *tbl) | 1487 | int neigh_table_clear(struct neigh_table *tbl) |
1467 | { | 1488 | { |
@@ -1499,10 +1520,11 @@ int neigh_table_clear(struct neigh_table *tbl) | |||
1499 | 1520 | ||
1500 | return 0; | 1521 | return 0; |
1501 | } | 1522 | } |
1523 | EXPORT_SYMBOL(neigh_table_clear); | ||
1502 | 1524 | ||
1503 | static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1525 | static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
1504 | { | 1526 | { |
1505 | struct net *net = skb->sk->sk_net; | 1527 | struct net *net = sock_net(skb->sk); |
1506 | struct ndmsg *ndm; | 1528 | struct ndmsg *ndm; |
1507 | struct nlattr *dst_attr; | 1529 | struct nlattr *dst_attr; |
1508 | struct neigh_table *tbl; | 1530 | struct neigh_table *tbl; |
@@ -1568,7 +1590,7 @@ out: | |||
1568 | 1590 | ||
1569 | static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1591 | static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
1570 | { | 1592 | { |
1571 | struct net *net = skb->sk->sk_net; | 1593 | struct net *net = sock_net(skb->sk); |
1572 | struct ndmsg *ndm; | 1594 | struct ndmsg *ndm; |
1573 | struct nlattr *tb[NDA_MAX+1]; | 1595 | struct nlattr *tb[NDA_MAX+1]; |
1574 | struct neigh_table *tbl; | 1596 | struct neigh_table *tbl; |
@@ -1836,7 +1858,7 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = { | |||
1836 | 1858 | ||
1837 | static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1859 | static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
1838 | { | 1860 | { |
1839 | struct net *net = skb->sk->sk_net; | 1861 | struct net *net = sock_net(skb->sk); |
1840 | struct neigh_table *tbl; | 1862 | struct neigh_table *tbl; |
1841 | struct ndtmsg *ndtmsg; | 1863 | struct ndtmsg *ndtmsg; |
1842 | struct nlattr *tb[NDTA_MAX+1]; | 1864 | struct nlattr *tb[NDTA_MAX+1]; |
@@ -1961,7 +1983,7 @@ errout: | |||
1961 | 1983 | ||
1962 | static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) | 1984 | static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) |
1963 | { | 1985 | { |
1964 | struct net *net = skb->sk->sk_net; | 1986 | struct net *net = sock_net(skb->sk); |
1965 | int family, tidx, nidx = 0; | 1987 | int family, tidx, nidx = 0; |
1966 | int tbl_skip = cb->args[0]; | 1988 | int tbl_skip = cb->args[0]; |
1967 | int neigh_skip = cb->args[1]; | 1989 | int neigh_skip = cb->args[1]; |
@@ -1982,7 +2004,7 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) | |||
1982 | break; | 2004 | break; |
1983 | 2005 | ||
1984 | for (nidx = 0, p = tbl->parms.next; p; p = p->next) { | 2006 | for (nidx = 0, p = tbl->parms.next; p; p = p->next) { |
1985 | if (net != p->net) | 2007 | if (!net_eq(neigh_parms_net(p), net)) |
1986 | continue; | 2008 | continue; |
1987 | 2009 | ||
1988 | if (nidx++ < neigh_skip) | 2010 | if (nidx++ < neigh_skip) |
@@ -2061,7 +2083,7 @@ static void neigh_update_notify(struct neighbour *neigh) | |||
2061 | static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, | 2083 | static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, |
2062 | struct netlink_callback *cb) | 2084 | struct netlink_callback *cb) |
2063 | { | 2085 | { |
2064 | struct net * net = skb->sk->sk_net; | 2086 | struct net * net = sock_net(skb->sk); |
2065 | struct neighbour *n; | 2087 | struct neighbour *n; |
2066 | int rc, h, s_h = cb->args[1]; | 2088 | int rc, h, s_h = cb->args[1]; |
2067 | int idx, s_idx = idx = cb->args[2]; | 2089 | int idx, s_idx = idx = cb->args[2]; |
@@ -2074,7 +2096,7 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, | |||
2074 | s_idx = 0; | 2096 | s_idx = 0; |
2075 | for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) { | 2097 | for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) { |
2076 | int lidx; | 2098 | int lidx; |
2077 | if (n->dev->nd_net != net) | 2099 | if (dev_net(n->dev) != net) |
2078 | continue; | 2100 | continue; |
2079 | lidx = idx++; | 2101 | lidx = idx++; |
2080 | if (lidx < s_idx) | 2102 | if (lidx < s_idx) |
@@ -2169,7 +2191,7 @@ EXPORT_SYMBOL(__neigh_for_each_release); | |||
2169 | static struct neighbour *neigh_get_first(struct seq_file *seq) | 2191 | static struct neighbour *neigh_get_first(struct seq_file *seq) |
2170 | { | 2192 | { |
2171 | struct neigh_seq_state *state = seq->private; | 2193 | struct neigh_seq_state *state = seq->private; |
2172 | struct net *net = state->p.net; | 2194 | struct net *net = seq_file_net(seq); |
2173 | struct neigh_table *tbl = state->tbl; | 2195 | struct neigh_table *tbl = state->tbl; |
2174 | struct neighbour *n = NULL; | 2196 | struct neighbour *n = NULL; |
2175 | int bucket = state->bucket; | 2197 | int bucket = state->bucket; |
@@ -2179,7 +2201,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq) | |||
2179 | n = tbl->hash_buckets[bucket]; | 2201 | n = tbl->hash_buckets[bucket]; |
2180 | 2202 | ||
2181 | while (n) { | 2203 | while (n) { |
2182 | if (n->dev->nd_net != net) | 2204 | if (!net_eq(dev_net(n->dev), net)) |
2183 | goto next; | 2205 | goto next; |
2184 | if (state->neigh_sub_iter) { | 2206 | if (state->neigh_sub_iter) { |
2185 | loff_t fakep = 0; | 2207 | loff_t fakep = 0; |
@@ -2210,7 +2232,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, | |||
2210 | loff_t *pos) | 2232 | loff_t *pos) |
2211 | { | 2233 | { |
2212 | struct neigh_seq_state *state = seq->private; | 2234 | struct neigh_seq_state *state = seq->private; |
2213 | struct net *net = state->p.net; | 2235 | struct net *net = seq_file_net(seq); |
2214 | struct neigh_table *tbl = state->tbl; | 2236 | struct neigh_table *tbl = state->tbl; |
2215 | 2237 | ||
2216 | if (state->neigh_sub_iter) { | 2238 | if (state->neigh_sub_iter) { |
@@ -2222,7 +2244,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, | |||
2222 | 2244 | ||
2223 | while (1) { | 2245 | while (1) { |
2224 | while (n) { | 2246 | while (n) { |
2225 | if (n->dev->nd_net != net) | 2247 | if (!net_eq(dev_net(n->dev), net)) |
2226 | goto next; | 2248 | goto next; |
2227 | if (state->neigh_sub_iter) { | 2249 | if (state->neigh_sub_iter) { |
2228 | void *v = state->neigh_sub_iter(state, n, pos); | 2250 | void *v = state->neigh_sub_iter(state, n, pos); |
@@ -2270,7 +2292,7 @@ static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos) | |||
2270 | static struct pneigh_entry *pneigh_get_first(struct seq_file *seq) | 2292 | static struct pneigh_entry *pneigh_get_first(struct seq_file *seq) |
2271 | { | 2293 | { |
2272 | struct neigh_seq_state *state = seq->private; | 2294 | struct neigh_seq_state *state = seq->private; |
2273 | struct net * net = state->p.net; | 2295 | struct net *net = seq_file_net(seq); |
2274 | struct neigh_table *tbl = state->tbl; | 2296 | struct neigh_table *tbl = state->tbl; |
2275 | struct pneigh_entry *pn = NULL; | 2297 | struct pneigh_entry *pn = NULL; |
2276 | int bucket = state->bucket; | 2298 | int bucket = state->bucket; |
@@ -2278,7 +2300,7 @@ static struct pneigh_entry *pneigh_get_first(struct seq_file *seq) | |||
2278 | state->flags |= NEIGH_SEQ_IS_PNEIGH; | 2300 | state->flags |= NEIGH_SEQ_IS_PNEIGH; |
2279 | for (bucket = 0; bucket <= PNEIGH_HASHMASK; bucket++) { | 2301 | for (bucket = 0; bucket <= PNEIGH_HASHMASK; bucket++) { |
2280 | pn = tbl->phash_buckets[bucket]; | 2302 | pn = tbl->phash_buckets[bucket]; |
2281 | while (pn && (pn->net != net)) | 2303 | while (pn && !net_eq(pneigh_net(pn), net)) |
2282 | pn = pn->next; | 2304 | pn = pn->next; |
2283 | if (pn) | 2305 | if (pn) |
2284 | break; | 2306 | break; |
@@ -2293,7 +2315,7 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq, | |||
2293 | loff_t *pos) | 2315 | loff_t *pos) |
2294 | { | 2316 | { |
2295 | struct neigh_seq_state *state = seq->private; | 2317 | struct neigh_seq_state *state = seq->private; |
2296 | struct net * net = state->p.net; | 2318 | struct net *net = seq_file_net(seq); |
2297 | struct neigh_table *tbl = state->tbl; | 2319 | struct neigh_table *tbl = state->tbl; |
2298 | 2320 | ||
2299 | pn = pn->next; | 2321 | pn = pn->next; |
@@ -2301,7 +2323,7 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq, | |||
2301 | if (++state->bucket > PNEIGH_HASHMASK) | 2323 | if (++state->bucket > PNEIGH_HASHMASK) |
2302 | break; | 2324 | break; |
2303 | pn = tbl->phash_buckets[state->bucket]; | 2325 | pn = tbl->phash_buckets[state->bucket]; |
2304 | while (pn && (pn->net != net)) | 2326 | while (pn && !net_eq(pneigh_net(pn), net)) |
2305 | pn = pn->next; | 2327 | pn = pn->next; |
2306 | if (pn) | 2328 | if (pn) |
2307 | break; | 2329 | break; |
@@ -2506,7 +2528,7 @@ static inline size_t neigh_nlmsg_size(void) | |||
2506 | 2528 | ||
2507 | static void __neigh_notify(struct neighbour *n, int type, int flags) | 2529 | static void __neigh_notify(struct neighbour *n, int type, int flags) |
2508 | { | 2530 | { |
2509 | struct net *net = n->dev->nd_net; | 2531 | struct net *net = dev_net(n->dev); |
2510 | struct sk_buff *skb; | 2532 | struct sk_buff *skb; |
2511 | int err = -ENOBUFS; | 2533 | int err = -ENOBUFS; |
2512 | 2534 | ||
@@ -2532,6 +2554,7 @@ void neigh_app_ns(struct neighbour *n) | |||
2532 | { | 2554 | { |
2533 | __neigh_notify(n, RTM_GETNEIGH, NLM_F_REQUEST); | 2555 | __neigh_notify(n, RTM_GETNEIGH, NLM_F_REQUEST); |
2534 | } | 2556 | } |
2557 | EXPORT_SYMBOL(neigh_app_ns); | ||
2535 | #endif /* CONFIG_ARPD */ | 2558 | #endif /* CONFIG_ARPD */ |
2536 | 2559 | ||
2537 | #ifdef CONFIG_SYSCTL | 2560 | #ifdef CONFIG_SYSCTL |
@@ -2763,7 +2786,8 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, | |||
2763 | neigh_path[NEIGH_CTL_PATH_PROTO].procname = p_name; | 2786 | neigh_path[NEIGH_CTL_PATH_PROTO].procname = p_name; |
2764 | neigh_path[NEIGH_CTL_PATH_PROTO].ctl_name = p_id; | 2787 | neigh_path[NEIGH_CTL_PATH_PROTO].ctl_name = p_id; |
2765 | 2788 | ||
2766 | t->sysctl_header = register_sysctl_paths(neigh_path, t->neigh_vars); | 2789 | t->sysctl_header = |
2790 | register_net_sysctl_table(neigh_parms_net(p), neigh_path, t->neigh_vars); | ||
2767 | if (!t->sysctl_header) | 2791 | if (!t->sysctl_header) |
2768 | goto free_procname; | 2792 | goto free_procname; |
2769 | 2793 | ||
@@ -2777,6 +2801,7 @@ free: | |||
2777 | err: | 2801 | err: |
2778 | return -ENOBUFS; | 2802 | return -ENOBUFS; |
2779 | } | 2803 | } |
2804 | EXPORT_SYMBOL(neigh_sysctl_register); | ||
2780 | 2805 | ||
2781 | void neigh_sysctl_unregister(struct neigh_parms *p) | 2806 | void neigh_sysctl_unregister(struct neigh_parms *p) |
2782 | { | 2807 | { |
@@ -2788,6 +2813,7 @@ void neigh_sysctl_unregister(struct neigh_parms *p) | |||
2788 | kfree(t); | 2813 | kfree(t); |
2789 | } | 2814 | } |
2790 | } | 2815 | } |
2816 | EXPORT_SYMBOL(neigh_sysctl_unregister); | ||
2791 | 2817 | ||
2792 | #endif /* CONFIG_SYSCTL */ | 2818 | #endif /* CONFIG_SYSCTL */ |
2793 | 2819 | ||
@@ -2805,32 +2831,3 @@ static int __init neigh_init(void) | |||
2805 | 2831 | ||
2806 | subsys_initcall(neigh_init); | 2832 | subsys_initcall(neigh_init); |
2807 | 2833 | ||
2808 | EXPORT_SYMBOL(__neigh_event_send); | ||
2809 | EXPORT_SYMBOL(neigh_changeaddr); | ||
2810 | EXPORT_SYMBOL(neigh_compat_output); | ||
2811 | EXPORT_SYMBOL(neigh_connected_output); | ||
2812 | EXPORT_SYMBOL(neigh_create); | ||
2813 | EXPORT_SYMBOL(neigh_destroy); | ||
2814 | EXPORT_SYMBOL(neigh_event_ns); | ||
2815 | EXPORT_SYMBOL(neigh_ifdown); | ||
2816 | EXPORT_SYMBOL(neigh_lookup); | ||
2817 | EXPORT_SYMBOL(neigh_lookup_nodev); | ||
2818 | EXPORT_SYMBOL(neigh_parms_alloc); | ||
2819 | EXPORT_SYMBOL(neigh_parms_release); | ||
2820 | EXPORT_SYMBOL(neigh_rand_reach_time); | ||
2821 | EXPORT_SYMBOL(neigh_resolve_output); | ||
2822 | EXPORT_SYMBOL(neigh_table_clear); | ||
2823 | EXPORT_SYMBOL(neigh_table_init); | ||
2824 | EXPORT_SYMBOL(neigh_table_init_no_netlink); | ||
2825 | EXPORT_SYMBOL(neigh_update); | ||
2826 | EXPORT_SYMBOL(pneigh_enqueue); | ||
2827 | EXPORT_SYMBOL(pneigh_lookup); | ||
2828 | EXPORT_SYMBOL_GPL(__pneigh_lookup); | ||
2829 | |||
2830 | #ifdef CONFIG_ARPD | ||
2831 | EXPORT_SYMBOL(neigh_app_ns); | ||
2832 | #endif | ||
2833 | #ifdef CONFIG_SYSCTL | ||
2834 | EXPORT_SYMBOL(neigh_sysctl_register); | ||
2835 | EXPORT_SYMBOL(neigh_sysctl_unregister); | ||
2836 | #endif | ||