diff options
author | Benjamin Thery <benjamin.thery@bull.net> | 2008-12-10 19:30:15 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-10 19:30:15 -0500 |
commit | 8229efdaef1e7913ae1712c0ba752f267e5fcd5e (patch) | |
tree | ba85dabf90f17b1b735fb8dda4b9bb11c5cd445d | |
parent | 8b90fc7e5b43aaef941044a4785a42439015b539 (diff) |
netns: ip6mr: enable namespace support in ipv6 multicast forwarding code
This last patch makes the appropriate changes to use and propagate the
network namespace where needed in IPv6 multicast forwarding code.
This consists mainly in replacing all the remaining init_net occurences
with current netns pointer retrieved from sockets, net devices or
mfc6_caches depending on the routines' contexts.
Some routines receive a new 'struct net' parameter to propagate the current
netns:
* ip6mr_get_route
* ip6mr_cache_report
* ip6mr_cache_find
* ip6mr_cache_unresolved
* mif6_add/mif6_delete
* ip6mr_mfc_add/ip6mr_mfc_delete
* ip6mr_reg_vif
All the IPv6 multicast forwarding variables moved to struct netns_ipv6 by
the previous patches are now referenced in the correct namespace.
Changelog:
==========
* Take into account the net associated to mfc6_cache when matching entries in
mfc_unres_queue list.
* Call mroute_clean_tables() in ip6mr_net_exit() to free memory allocated
per-namespace.
* Call dev_net_set() in ip6mr_reg_vif() to initialize dev->nd_net
correctly.
Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/mroute6.h | 3 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 226 | ||||
-rw-r--r-- | net/ipv6/route.c | 2 |
3 files changed, 129 insertions, 102 deletions
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h index 15d85fe12bbd..5375faca1f72 100644 --- a/include/linux/mroute6.h +++ b/include/linux/mroute6.h | |||
@@ -245,7 +245,8 @@ void mfc6_net_set(struct mfc6_cache *mfc, struct net *net) | |||
245 | 245 | ||
246 | #ifdef __KERNEL__ | 246 | #ifdef __KERNEL__ |
247 | struct rtmsg; | 247 | struct rtmsg; |
248 | extern int ip6mr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait); | 248 | extern int ip6mr_get_route(struct net *net, struct sk_buff *skb, |
249 | struct rtmsg *rtm, int nowait); | ||
249 | 250 | ||
250 | #ifdef CONFIG_IPV6_MROUTE | 251 | #ifdef CONFIG_IPV6_MROUTE |
251 | static inline struct sock *mroute6_socket(struct net *net) | 252 | static inline struct sock *mroute6_socket(struct net *net) |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index d619faf68d98..9eed2422b3e3 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -77,8 +77,10 @@ static DEFINE_SPINLOCK(mfc_unres_lock); | |||
77 | static struct kmem_cache *mrt_cachep __read_mostly; | 77 | static struct kmem_cache *mrt_cachep __read_mostly; |
78 | 78 | ||
79 | static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache); | 79 | static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache); |
80 | static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert); | 80 | static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, |
81 | mifi_t mifi, int assert); | ||
81 | static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm); | 82 | static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm); |
83 | static void mroute_clean_tables(struct net *net); | ||
82 | 84 | ||
83 | #ifdef CONFIG_IPV6_PIMSM_V2 | 85 | #ifdef CONFIG_IPV6_PIMSM_V2 |
84 | static struct inet6_protocol pim6_protocol; | 86 | static struct inet6_protocol pim6_protocol; |
@@ -354,7 +356,8 @@ static int pim6_rcv(struct sk_buff *skb) | |||
354 | struct pimreghdr *pim; | 356 | struct pimreghdr *pim; |
355 | struct ipv6hdr *encap; | 357 | struct ipv6hdr *encap; |
356 | struct net_device *reg_dev = NULL; | 358 | struct net_device *reg_dev = NULL; |
357 | int reg_vif_num = init_net.ipv6.mroute_reg_vif_num; | 359 | struct net *net = dev_net(skb->dev); |
360 | int reg_vif_num = net->ipv6.mroute_reg_vif_num; | ||
358 | 361 | ||
359 | if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap))) | 362 | if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap))) |
360 | goto drop; | 363 | goto drop; |
@@ -377,7 +380,7 @@ static int pim6_rcv(struct sk_buff *skb) | |||
377 | 380 | ||
378 | read_lock(&mrt_lock); | 381 | read_lock(&mrt_lock); |
379 | if (reg_vif_num >= 0) | 382 | if (reg_vif_num >= 0) |
380 | reg_dev = init_net.ipv6.vif6_table[reg_vif_num].dev; | 383 | reg_dev = net->ipv6.vif6_table[reg_vif_num].dev; |
381 | if (reg_dev) | 384 | if (reg_dev) |
382 | dev_hold(reg_dev); | 385 | dev_hold(reg_dev); |
383 | read_unlock(&mrt_lock); | 386 | read_unlock(&mrt_lock); |
@@ -413,10 +416,13 @@ static struct inet6_protocol pim6_protocol = { | |||
413 | 416 | ||
414 | static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) | 417 | static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) |
415 | { | 418 | { |
419 | struct net *net = dev_net(dev); | ||
420 | |||
416 | read_lock(&mrt_lock); | 421 | read_lock(&mrt_lock); |
417 | dev->stats.tx_bytes += skb->len; | 422 | dev->stats.tx_bytes += skb->len; |
418 | dev->stats.tx_packets++; | 423 | dev->stats.tx_packets++; |
419 | ip6mr_cache_report(skb, init_net.ipv6.mroute_reg_vif_num, MRT6MSG_WHOLEPKT); | 424 | ip6mr_cache_report(net, skb, net->ipv6.mroute_reg_vif_num, |
425 | MRT6MSG_WHOLEPKT); | ||
420 | read_unlock(&mrt_lock); | 426 | read_unlock(&mrt_lock); |
421 | kfree_skb(skb); | 427 | kfree_skb(skb); |
422 | return 0; | 428 | return 0; |
@@ -435,7 +441,7 @@ static void reg_vif_setup(struct net_device *dev) | |||
435 | dev->destructor = free_netdev; | 441 | dev->destructor = free_netdev; |
436 | } | 442 | } |
437 | 443 | ||
438 | static struct net_device *ip6mr_reg_vif(void) | 444 | static struct net_device *ip6mr_reg_vif(struct net *net) |
439 | { | 445 | { |
440 | struct net_device *dev; | 446 | struct net_device *dev; |
441 | 447 | ||
@@ -443,6 +449,8 @@ static struct net_device *ip6mr_reg_vif(void) | |||
443 | if (dev == NULL) | 449 | if (dev == NULL) |
444 | return NULL; | 450 | return NULL; |
445 | 451 | ||
452 | dev_net_set(dev, net); | ||
453 | |||
446 | if (register_netdevice(dev)) { | 454 | if (register_netdevice(dev)) { |
447 | free_netdev(dev); | 455 | free_netdev(dev); |
448 | return NULL; | 456 | return NULL; |
@@ -469,14 +477,14 @@ failure: | |||
469 | * Delete a VIF entry | 477 | * Delete a VIF entry |
470 | */ | 478 | */ |
471 | 479 | ||
472 | static int mif6_delete(int vifi) | 480 | static int mif6_delete(struct net *net, int vifi) |
473 | { | 481 | { |
474 | struct mif_device *v; | 482 | struct mif_device *v; |
475 | struct net_device *dev; | 483 | struct net_device *dev; |
476 | if (vifi < 0 || vifi >= init_net.ipv6.maxvif) | 484 | if (vifi < 0 || vifi >= net->ipv6.maxvif) |
477 | return -EADDRNOTAVAIL; | 485 | return -EADDRNOTAVAIL; |
478 | 486 | ||
479 | v = &init_net.ipv6.vif6_table[vifi]; | 487 | v = &net->ipv6.vif6_table[vifi]; |
480 | 488 | ||
481 | write_lock_bh(&mrt_lock); | 489 | write_lock_bh(&mrt_lock); |
482 | dev = v->dev; | 490 | dev = v->dev; |
@@ -488,17 +496,17 @@ static int mif6_delete(int vifi) | |||
488 | } | 496 | } |
489 | 497 | ||
490 | #ifdef CONFIG_IPV6_PIMSM_V2 | 498 | #ifdef CONFIG_IPV6_PIMSM_V2 |
491 | if (vifi == init_net.ipv6.mroute_reg_vif_num) | 499 | if (vifi == net->ipv6.mroute_reg_vif_num) |
492 | init_net.ipv6.mroute_reg_vif_num = -1; | 500 | net->ipv6.mroute_reg_vif_num = -1; |
493 | #endif | 501 | #endif |
494 | 502 | ||
495 | if (vifi + 1 == init_net.ipv6.maxvif) { | 503 | if (vifi + 1 == net->ipv6.maxvif) { |
496 | int tmp; | 504 | int tmp; |
497 | for (tmp = vifi - 1; tmp >= 0; tmp--) { | 505 | for (tmp = vifi - 1; tmp >= 0; tmp--) { |
498 | if (MIF_EXISTS(&init_net, tmp)) | 506 | if (MIF_EXISTS(net, tmp)) |
499 | break; | 507 | break; |
500 | } | 508 | } |
501 | init_net.ipv6.maxvif = tmp + 1; | 509 | net->ipv6.maxvif = tmp + 1; |
502 | } | 510 | } |
503 | 511 | ||
504 | write_unlock_bh(&mrt_lock); | 512 | write_unlock_bh(&mrt_lock); |
@@ -525,8 +533,9 @@ static inline void ip6mr_cache_free(struct mfc6_cache *c) | |||
525 | static void ip6mr_destroy_unres(struct mfc6_cache *c) | 533 | static void ip6mr_destroy_unres(struct mfc6_cache *c) |
526 | { | 534 | { |
527 | struct sk_buff *skb; | 535 | struct sk_buff *skb; |
536 | struct net *net = mfc6_net(c); | ||
528 | 537 | ||
529 | atomic_dec(&init_net.ipv6.cache_resolve_queue_len); | 538 | atomic_dec(&net->ipv6.cache_resolve_queue_len); |
530 | 539 | ||
531 | while((skb = skb_dequeue(&c->mfc_un.unres.unresolved)) != NULL) { | 540 | while((skb = skb_dequeue(&c->mfc_un.unres.unresolved)) != NULL) { |
532 | if (ipv6_hdr(skb)->version == 0) { | 541 | if (ipv6_hdr(skb)->version == 0) { |
@@ -535,7 +544,7 @@ static void ip6mr_destroy_unres(struct mfc6_cache *c) | |||
535 | nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); | 544 | nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); |
536 | skb_trim(skb, nlh->nlmsg_len); | 545 | skb_trim(skb, nlh->nlmsg_len); |
537 | ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -ETIMEDOUT; | 546 | ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -ETIMEDOUT; |
538 | rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid); | 547 | rtnl_unicast(skb, net, NETLINK_CB(skb).pid); |
539 | } else | 548 | } else |
540 | kfree_skb(skb); | 549 | kfree_skb(skb); |
541 | } | 550 | } |
@@ -590,13 +599,14 @@ static void ipmr_expire_process(unsigned long dummy) | |||
590 | static void ip6mr_update_thresholds(struct mfc6_cache *cache, unsigned char *ttls) | 599 | static void ip6mr_update_thresholds(struct mfc6_cache *cache, unsigned char *ttls) |
591 | { | 600 | { |
592 | int vifi; | 601 | int vifi; |
602 | struct net *net = mfc6_net(cache); | ||
593 | 603 | ||
594 | cache->mfc_un.res.minvif = MAXMIFS; | 604 | cache->mfc_un.res.minvif = MAXMIFS; |
595 | cache->mfc_un.res.maxvif = 0; | 605 | cache->mfc_un.res.maxvif = 0; |
596 | memset(cache->mfc_un.res.ttls, 255, MAXMIFS); | 606 | memset(cache->mfc_un.res.ttls, 255, MAXMIFS); |
597 | 607 | ||
598 | for (vifi = 0; vifi < init_net.ipv6.maxvif; vifi++) { | 608 | for (vifi = 0; vifi < net->ipv6.maxvif; vifi++) { |
599 | if (MIF_EXISTS(&init_net, vifi) && | 609 | if (MIF_EXISTS(net, vifi) && |
600 | ttls[vifi] && ttls[vifi] < 255) { | 610 | ttls[vifi] && ttls[vifi] < 255) { |
601 | cache->mfc_un.res.ttls[vifi] = ttls[vifi]; | 611 | cache->mfc_un.res.ttls[vifi] = ttls[vifi]; |
602 | if (cache->mfc_un.res.minvif > vifi) | 612 | if (cache->mfc_un.res.minvif > vifi) |
@@ -607,15 +617,15 @@ static void ip6mr_update_thresholds(struct mfc6_cache *cache, unsigned char *ttl | |||
607 | } | 617 | } |
608 | } | 618 | } |
609 | 619 | ||
610 | static int mif6_add(struct mif6ctl *vifc, int mrtsock) | 620 | static int mif6_add(struct net *net, struct mif6ctl *vifc, int mrtsock) |
611 | { | 621 | { |
612 | int vifi = vifc->mif6c_mifi; | 622 | int vifi = vifc->mif6c_mifi; |
613 | struct mif_device *v = &init_net.ipv6.vif6_table[vifi]; | 623 | struct mif_device *v = &net->ipv6.vif6_table[vifi]; |
614 | struct net_device *dev; | 624 | struct net_device *dev; |
615 | int err; | 625 | int err; |
616 | 626 | ||
617 | /* Is vif busy ? */ | 627 | /* Is vif busy ? */ |
618 | if (MIF_EXISTS(&init_net, vifi)) | 628 | if (MIF_EXISTS(net, vifi)) |
619 | return -EADDRINUSE; | 629 | return -EADDRINUSE; |
620 | 630 | ||
621 | switch (vifc->mif6c_flags) { | 631 | switch (vifc->mif6c_flags) { |
@@ -625,9 +635,9 @@ static int mif6_add(struct mif6ctl *vifc, int mrtsock) | |||
625 | * Special Purpose VIF in PIM | 635 | * Special Purpose VIF in PIM |
626 | * All the packets will be sent to the daemon | 636 | * All the packets will be sent to the daemon |
627 | */ | 637 | */ |
628 | if (init_net.ipv6.mroute_reg_vif_num >= 0) | 638 | if (net->ipv6.mroute_reg_vif_num >= 0) |
629 | return -EADDRINUSE; | 639 | return -EADDRINUSE; |
630 | dev = ip6mr_reg_vif(); | 640 | dev = ip6mr_reg_vif(net); |
631 | if (!dev) | 641 | if (!dev) |
632 | return -ENOBUFS; | 642 | return -ENOBUFS; |
633 | err = dev_set_allmulti(dev, 1); | 643 | err = dev_set_allmulti(dev, 1); |
@@ -639,7 +649,7 @@ static int mif6_add(struct mif6ctl *vifc, int mrtsock) | |||
639 | break; | 649 | break; |
640 | #endif | 650 | #endif |
641 | case 0: | 651 | case 0: |
642 | dev = dev_get_by_index(&init_net, vifc->mif6c_pifi); | 652 | dev = dev_get_by_index(net, vifc->mif6c_pifi); |
643 | if (!dev) | 653 | if (!dev) |
644 | return -EADDRNOTAVAIL; | 654 | return -EADDRNOTAVAIL; |
645 | err = dev_set_allmulti(dev, 1); | 655 | err = dev_set_allmulti(dev, 1); |
@@ -673,20 +683,22 @@ static int mif6_add(struct mif6ctl *vifc, int mrtsock) | |||
673 | v->dev = dev; | 683 | v->dev = dev; |
674 | #ifdef CONFIG_IPV6_PIMSM_V2 | 684 | #ifdef CONFIG_IPV6_PIMSM_V2 |
675 | if (v->flags & MIFF_REGISTER) | 685 | if (v->flags & MIFF_REGISTER) |
676 | init_net.ipv6.mroute_reg_vif_num = vifi; | 686 | net->ipv6.mroute_reg_vif_num = vifi; |
677 | #endif | 687 | #endif |
678 | if (vifi + 1 > init_net.ipv6.maxvif) | 688 | if (vifi + 1 > net->ipv6.maxvif) |
679 | init_net.ipv6.maxvif = vifi + 1; | 689 | net->ipv6.maxvif = vifi + 1; |
680 | write_unlock_bh(&mrt_lock); | 690 | write_unlock_bh(&mrt_lock); |
681 | return 0; | 691 | return 0; |
682 | } | 692 | } |
683 | 693 | ||
684 | static struct mfc6_cache *ip6mr_cache_find(struct in6_addr *origin, struct in6_addr *mcastgrp) | 694 | static struct mfc6_cache *ip6mr_cache_find(struct net *net, |
695 | struct in6_addr *origin, | ||
696 | struct in6_addr *mcastgrp) | ||
685 | { | 697 | { |
686 | int line = MFC6_HASH(mcastgrp, origin); | 698 | int line = MFC6_HASH(mcastgrp, origin); |
687 | struct mfc6_cache *c; | 699 | struct mfc6_cache *c; |
688 | 700 | ||
689 | for (c = init_net.ipv6.mfc6_cache_array[line]; c; c = c->next) { | 701 | for (c = net->ipv6.mfc6_cache_array[line]; c; c = c->next) { |
690 | if (ipv6_addr_equal(&c->mf6c_origin, origin) && | 702 | if (ipv6_addr_equal(&c->mf6c_origin, origin) && |
691 | ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp)) | 703 | ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp)) |
692 | break; | 704 | break; |
@@ -743,7 +755,7 @@ static void ip6mr_cache_resolve(struct mfc6_cache *uc, struct mfc6_cache *c) | |||
743 | skb_trim(skb, nlh->nlmsg_len); | 755 | skb_trim(skb, nlh->nlmsg_len); |
744 | ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -EMSGSIZE; | 756 | ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -EMSGSIZE; |
745 | } | 757 | } |
746 | err = rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid); | 758 | err = rtnl_unicast(skb, mfc6_net(uc), NETLINK_CB(skb).pid); |
747 | } else | 759 | } else |
748 | ip6_mr_forward(skb, c); | 760 | ip6_mr_forward(skb, c); |
749 | } | 761 | } |
@@ -756,7 +768,8 @@ static void ip6mr_cache_resolve(struct mfc6_cache *uc, struct mfc6_cache *c) | |||
756 | * Called under mrt_lock. | 768 | * Called under mrt_lock. |
757 | */ | 769 | */ |
758 | 770 | ||
759 | static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | 771 | static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, mifi_t mifi, |
772 | int assert) | ||
760 | { | 773 | { |
761 | struct sk_buff *skb; | 774 | struct sk_buff *skb; |
762 | struct mrt6msg *msg; | 775 | struct mrt6msg *msg; |
@@ -792,7 +805,7 @@ static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | |||
792 | msg = (struct mrt6msg *)skb_transport_header(skb); | 805 | msg = (struct mrt6msg *)skb_transport_header(skb); |
793 | msg->im6_mbz = 0; | 806 | msg->im6_mbz = 0; |
794 | msg->im6_msgtype = MRT6MSG_WHOLEPKT; | 807 | msg->im6_msgtype = MRT6MSG_WHOLEPKT; |
795 | msg->im6_mif = init_net.ipv6.mroute_reg_vif_num; | 808 | msg->im6_mif = net->ipv6.mroute_reg_vif_num; |
796 | msg->im6_pad = 0; | 809 | msg->im6_pad = 0; |
797 | ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr); | 810 | ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr); |
798 | ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr); | 811 | ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr); |
@@ -829,7 +842,7 @@ static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | |||
829 | skb_pull(skb, sizeof(struct ipv6hdr)); | 842 | skb_pull(skb, sizeof(struct ipv6hdr)); |
830 | } | 843 | } |
831 | 844 | ||
832 | if (init_net.ipv6.mroute6_sk == NULL) { | 845 | if (net->ipv6.mroute6_sk == NULL) { |
833 | kfree_skb(skb); | 846 | kfree_skb(skb); |
834 | return -EINVAL; | 847 | return -EINVAL; |
835 | } | 848 | } |
@@ -837,7 +850,7 @@ static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | |||
837 | /* | 850 | /* |
838 | * Deliver to user space multicast routing algorithms | 851 | * Deliver to user space multicast routing algorithms |
839 | */ | 852 | */ |
840 | ret = sock_queue_rcv_skb(init_net.ipv6.mroute6_sk, skb); | 853 | ret = sock_queue_rcv_skb(net->ipv6.mroute6_sk, skb); |
841 | if (ret < 0) { | 854 | if (ret < 0) { |
842 | if (net_ratelimit()) | 855 | if (net_ratelimit()) |
843 | printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n"); | 856 | printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n"); |
@@ -852,14 +865,14 @@ static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | |||
852 | */ | 865 | */ |
853 | 866 | ||
854 | static int | 867 | static int |
855 | ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb) | 868 | ip6mr_cache_unresolved(struct net *net, mifi_t mifi, struct sk_buff *skb) |
856 | { | 869 | { |
857 | int err; | 870 | int err; |
858 | struct mfc6_cache *c; | 871 | struct mfc6_cache *c; |
859 | 872 | ||
860 | spin_lock_bh(&mfc_unres_lock); | 873 | spin_lock_bh(&mfc_unres_lock); |
861 | for (c = mfc_unres_queue; c; c = c->next) { | 874 | for (c = mfc_unres_queue; c; c = c->next) { |
862 | if (net_eq(mfc6_net(c), &init_net) && | 875 | if (net_eq(mfc6_net(c), net) && |
863 | ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) && | 876 | ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) && |
864 | ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr)) | 877 | ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr)) |
865 | break; | 878 | break; |
@@ -870,8 +883,8 @@ ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb) | |||
870 | * Create a new entry if allowable | 883 | * Create a new entry if allowable |
871 | */ | 884 | */ |
872 | 885 | ||
873 | if (atomic_read(&init_net.ipv6.cache_resolve_queue_len) >= 10 || | 886 | if (atomic_read(&net->ipv6.cache_resolve_queue_len) >= 10 || |
874 | (c = ip6mr_cache_alloc_unres(&init_net)) == NULL) { | 887 | (c = ip6mr_cache_alloc_unres(net)) == NULL) { |
875 | spin_unlock_bh(&mfc_unres_lock); | 888 | spin_unlock_bh(&mfc_unres_lock); |
876 | 889 | ||
877 | kfree_skb(skb); | 890 | kfree_skb(skb); |
@@ -888,7 +901,8 @@ ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb) | |||
888 | /* | 901 | /* |
889 | * Reflect first query at pim6sd | 902 | * Reflect first query at pim6sd |
890 | */ | 903 | */ |
891 | if ((err = ip6mr_cache_report(skb, mifi, MRT6MSG_NOCACHE)) < 0) { | 904 | err = ip6mr_cache_report(net, skb, mifi, MRT6MSG_NOCACHE); |
905 | if (err < 0) { | ||
892 | /* If the report failed throw the cache entry | 906 | /* If the report failed throw the cache entry |
893 | out - Brad Parker | 907 | out - Brad Parker |
894 | */ | 908 | */ |
@@ -899,7 +913,7 @@ ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb) | |||
899 | return err; | 913 | return err; |
900 | } | 914 | } |
901 | 915 | ||
902 | atomic_inc(&init_net.ipv6.cache_resolve_queue_len); | 916 | atomic_inc(&net->ipv6.cache_resolve_queue_len); |
903 | c->next = mfc_unres_queue; | 917 | c->next = mfc_unres_queue; |
904 | mfc_unres_queue = c; | 918 | mfc_unres_queue = c; |
905 | 919 | ||
@@ -925,14 +939,14 @@ ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb) | |||
925 | * MFC6 cache manipulation by user space | 939 | * MFC6 cache manipulation by user space |
926 | */ | 940 | */ |
927 | 941 | ||
928 | static int ip6mr_mfc_delete(struct mf6cctl *mfc) | 942 | static int ip6mr_mfc_delete(struct net *net, struct mf6cctl *mfc) |
929 | { | 943 | { |
930 | int line; | 944 | int line; |
931 | struct mfc6_cache *c, **cp; | 945 | struct mfc6_cache *c, **cp; |
932 | 946 | ||
933 | line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr); | 947 | line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr); |
934 | 948 | ||
935 | for (cp = &init_net.ipv6.mfc6_cache_array[line]; | 949 | for (cp = &net->ipv6.mfc6_cache_array[line]; |
936 | (c = *cp) != NULL; cp = &c->next) { | 950 | (c = *cp) != NULL; cp = &c->next) { |
937 | if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && | 951 | if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && |
938 | ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) { | 952 | ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) { |
@@ -951,19 +965,17 @@ static int ip6mr_device_event(struct notifier_block *this, | |||
951 | unsigned long event, void *ptr) | 965 | unsigned long event, void *ptr) |
952 | { | 966 | { |
953 | struct net_device *dev = ptr; | 967 | struct net_device *dev = ptr; |
968 | struct net *net = dev_net(dev); | ||
954 | struct mif_device *v; | 969 | struct mif_device *v; |
955 | int ct; | 970 | int ct; |
956 | 971 | ||
957 | if (!net_eq(dev_net(dev), &init_net)) | ||
958 | return NOTIFY_DONE; | ||
959 | |||
960 | if (event != NETDEV_UNREGISTER) | 972 | if (event != NETDEV_UNREGISTER) |
961 | return NOTIFY_DONE; | 973 | return NOTIFY_DONE; |
962 | 974 | ||
963 | v = &init_net.ipv6.vif6_table[0]; | 975 | v = &net->ipv6.vif6_table[0]; |
964 | for (ct = 0; ct < init_net.ipv6.maxvif; ct++, v++) { | 976 | for (ct = 0; ct < net->ipv6.maxvif; ct++, v++) { |
965 | if (v->dev == dev) | 977 | if (v->dev == dev) |
966 | mif6_delete(ct); | 978 | mif6_delete(net, ct); |
967 | } | 979 | } |
968 | return NOTIFY_DONE; | 980 | return NOTIFY_DONE; |
969 | } | 981 | } |
@@ -1026,6 +1038,7 @@ static void __net_exit ip6mr_net_exit(struct net *net) | |||
1026 | proc_net_remove(net, "ip6_mr_cache"); | 1038 | proc_net_remove(net, "ip6_mr_cache"); |
1027 | proc_net_remove(net, "ip6_mr_vif"); | 1039 | proc_net_remove(net, "ip6_mr_vif"); |
1028 | #endif | 1040 | #endif |
1041 | mroute_clean_tables(net); | ||
1029 | kfree(net->ipv6.mfc6_cache_array); | 1042 | kfree(net->ipv6.mfc6_cache_array); |
1030 | kfree(net->ipv6.vif6_table); | 1043 | kfree(net->ipv6.vif6_table); |
1031 | } | 1044 | } |
@@ -1071,7 +1084,7 @@ void ip6_mr_cleanup(void) | |||
1071 | kmem_cache_destroy(mrt_cachep); | 1084 | kmem_cache_destroy(mrt_cachep); |
1072 | } | 1085 | } |
1073 | 1086 | ||
1074 | static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | 1087 | static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock) |
1075 | { | 1088 | { |
1076 | int line; | 1089 | int line; |
1077 | struct mfc6_cache *uc, *c, **cp; | 1090 | struct mfc6_cache *uc, *c, **cp; |
@@ -1087,7 +1100,7 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | |||
1087 | 1100 | ||
1088 | line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr); | 1101 | line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr); |
1089 | 1102 | ||
1090 | for (cp = &init_net.ipv6.mfc6_cache_array[line]; | 1103 | for (cp = &net->ipv6.mfc6_cache_array[line]; |
1091 | (c = *cp) != NULL; cp = &c->next) { | 1104 | (c = *cp) != NULL; cp = &c->next) { |
1092 | if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && | 1105 | if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && |
1093 | ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) | 1106 | ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) |
@@ -1107,7 +1120,7 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | |||
1107 | if (!ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr)) | 1120 | if (!ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr)) |
1108 | return -EINVAL; | 1121 | return -EINVAL; |
1109 | 1122 | ||
1110 | c = ip6mr_cache_alloc(&init_net); | 1123 | c = ip6mr_cache_alloc(net); |
1111 | if (c == NULL) | 1124 | if (c == NULL) |
1112 | return -ENOMEM; | 1125 | return -ENOMEM; |
1113 | 1126 | ||
@@ -1119,8 +1132,8 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | |||
1119 | c->mfc_flags |= MFC_STATIC; | 1132 | c->mfc_flags |= MFC_STATIC; |
1120 | 1133 | ||
1121 | write_lock_bh(&mrt_lock); | 1134 | write_lock_bh(&mrt_lock); |
1122 | c->next = init_net.ipv6.mfc6_cache_array[line]; | 1135 | c->next = net->ipv6.mfc6_cache_array[line]; |
1123 | init_net.ipv6.mfc6_cache_array[line] = c; | 1136 | net->ipv6.mfc6_cache_array[line] = c; |
1124 | write_unlock_bh(&mrt_lock); | 1137 | write_unlock_bh(&mrt_lock); |
1125 | 1138 | ||
1126 | /* | 1139 | /* |
@@ -1130,11 +1143,11 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | |||
1130 | spin_lock_bh(&mfc_unres_lock); | 1143 | spin_lock_bh(&mfc_unres_lock); |
1131 | for (cp = &mfc_unres_queue; (uc = *cp) != NULL; | 1144 | for (cp = &mfc_unres_queue; (uc = *cp) != NULL; |
1132 | cp = &uc->next) { | 1145 | cp = &uc->next) { |
1133 | if (net_eq(mfc6_net(uc), &init_net) && | 1146 | if (net_eq(mfc6_net(uc), net) && |
1134 | ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) && | 1147 | ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) && |
1135 | ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) { | 1148 | ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) { |
1136 | *cp = uc->next; | 1149 | *cp = uc->next; |
1137 | atomic_dec(&init_net.ipv6.cache_resolve_queue_len); | 1150 | atomic_dec(&net->ipv6.cache_resolve_queue_len); |
1138 | break; | 1151 | break; |
1139 | } | 1152 | } |
1140 | } | 1153 | } |
@@ -1153,16 +1166,16 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | |||
1153 | * Close the multicast socket, and clear the vif tables etc | 1166 | * Close the multicast socket, and clear the vif tables etc |
1154 | */ | 1167 | */ |
1155 | 1168 | ||
1156 | static void mroute_clean_tables(struct sock *sk) | 1169 | static void mroute_clean_tables(struct net *net) |
1157 | { | 1170 | { |
1158 | int i; | 1171 | int i; |
1159 | 1172 | ||
1160 | /* | 1173 | /* |
1161 | * Shut down all active vif entries | 1174 | * Shut down all active vif entries |
1162 | */ | 1175 | */ |
1163 | for (i = 0; i < init_net.ipv6.maxvif; i++) { | 1176 | for (i = 0; i < net->ipv6.maxvif; i++) { |
1164 | if (!(init_net.ipv6.vif6_table[i].flags & VIFF_STATIC)) | 1177 | if (!(net->ipv6.vif6_table[i].flags & VIFF_STATIC)) |
1165 | mif6_delete(i); | 1178 | mif6_delete(net, i); |
1166 | } | 1179 | } |
1167 | 1180 | ||
1168 | /* | 1181 | /* |
@@ -1171,7 +1184,7 @@ static void mroute_clean_tables(struct sock *sk) | |||
1171 | for (i = 0; i < MFC6_LINES; i++) { | 1184 | for (i = 0; i < MFC6_LINES; i++) { |
1172 | struct mfc6_cache *c, **cp; | 1185 | struct mfc6_cache *c, **cp; |
1173 | 1186 | ||
1174 | cp = &init_net.ipv6.mfc6_cache_array[i]; | 1187 | cp = &net->ipv6.mfc6_cache_array[i]; |
1175 | while ((c = *cp) != NULL) { | 1188 | while ((c = *cp) != NULL) { |
1176 | if (c->mfc_flags & MFC_STATIC) { | 1189 | if (c->mfc_flags & MFC_STATIC) { |
1177 | cp = &c->next; | 1190 | cp = &c->next; |
@@ -1185,13 +1198,13 @@ static void mroute_clean_tables(struct sock *sk) | |||
1185 | } | 1198 | } |
1186 | } | 1199 | } |
1187 | 1200 | ||
1188 | if (atomic_read(&init_net.ipv6.cache_resolve_queue_len) != 0) { | 1201 | if (atomic_read(&net->ipv6.cache_resolve_queue_len) != 0) { |
1189 | struct mfc6_cache *c, **cp; | 1202 | struct mfc6_cache *c, **cp; |
1190 | 1203 | ||
1191 | spin_lock_bh(&mfc_unres_lock); | 1204 | spin_lock_bh(&mfc_unres_lock); |
1192 | cp = &mfc_unres_queue; | 1205 | cp = &mfc_unres_queue; |
1193 | while ((c = *cp) != NULL) { | 1206 | while ((c = *cp) != NULL) { |
1194 | if (!net_eq(mfc6_net(c), &init_net)) { | 1207 | if (!net_eq(mfc6_net(c), net)) { |
1195 | cp = &c->next; | 1208 | cp = &c->next; |
1196 | continue; | 1209 | continue; |
1197 | } | 1210 | } |
@@ -1205,11 +1218,12 @@ static void mroute_clean_tables(struct sock *sk) | |||
1205 | static int ip6mr_sk_init(struct sock *sk) | 1218 | static int ip6mr_sk_init(struct sock *sk) |
1206 | { | 1219 | { |
1207 | int err = 0; | 1220 | int err = 0; |
1221 | struct net *net = sock_net(sk); | ||
1208 | 1222 | ||
1209 | rtnl_lock(); | 1223 | rtnl_lock(); |
1210 | write_lock_bh(&mrt_lock); | 1224 | write_lock_bh(&mrt_lock); |
1211 | if (likely(init_net.ipv6.mroute6_sk == NULL)) | 1225 | if (likely(net->ipv6.mroute6_sk == NULL)) |
1212 | init_net.ipv6.mroute6_sk = sk; | 1226 | net->ipv6.mroute6_sk = sk; |
1213 | else | 1227 | else |
1214 | err = -EADDRINUSE; | 1228 | err = -EADDRINUSE; |
1215 | write_unlock_bh(&mrt_lock); | 1229 | write_unlock_bh(&mrt_lock); |
@@ -1222,14 +1236,15 @@ static int ip6mr_sk_init(struct sock *sk) | |||
1222 | int ip6mr_sk_done(struct sock *sk) | 1236 | int ip6mr_sk_done(struct sock *sk) |
1223 | { | 1237 | { |
1224 | int err = 0; | 1238 | int err = 0; |
1239 | struct net *net = sock_net(sk); | ||
1225 | 1240 | ||
1226 | rtnl_lock(); | 1241 | rtnl_lock(); |
1227 | if (sk == init_net.ipv6.mroute6_sk) { | 1242 | if (sk == net->ipv6.mroute6_sk) { |
1228 | write_lock_bh(&mrt_lock); | 1243 | write_lock_bh(&mrt_lock); |
1229 | init_net.ipv6.mroute6_sk = NULL; | 1244 | net->ipv6.mroute6_sk = NULL; |
1230 | write_unlock_bh(&mrt_lock); | 1245 | write_unlock_bh(&mrt_lock); |
1231 | 1246 | ||
1232 | mroute_clean_tables(sk); | 1247 | mroute_clean_tables(net); |
1233 | } else | 1248 | } else |
1234 | err = -EACCES; | 1249 | err = -EACCES; |
1235 | rtnl_unlock(); | 1250 | rtnl_unlock(); |
@@ -1250,9 +1265,10 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1250 | struct mif6ctl vif; | 1265 | struct mif6ctl vif; |
1251 | struct mf6cctl mfc; | 1266 | struct mf6cctl mfc; |
1252 | mifi_t mifi; | 1267 | mifi_t mifi; |
1268 | struct net *net = sock_net(sk); | ||
1253 | 1269 | ||
1254 | if (optname != MRT6_INIT) { | 1270 | if (optname != MRT6_INIT) { |
1255 | if (sk != init_net.ipv6.mroute6_sk && !capable(CAP_NET_ADMIN)) | 1271 | if (sk != net->ipv6.mroute6_sk && !capable(CAP_NET_ADMIN)) |
1256 | return -EACCES; | 1272 | return -EACCES; |
1257 | } | 1273 | } |
1258 | 1274 | ||
@@ -1277,7 +1293,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1277 | if (vif.mif6c_mifi >= MAXMIFS) | 1293 | if (vif.mif6c_mifi >= MAXMIFS) |
1278 | return -ENFILE; | 1294 | return -ENFILE; |
1279 | rtnl_lock(); | 1295 | rtnl_lock(); |
1280 | ret = mif6_add(&vif, sk == init_net.ipv6.mroute6_sk); | 1296 | ret = mif6_add(net, &vif, sk == net->ipv6.mroute6_sk); |
1281 | rtnl_unlock(); | 1297 | rtnl_unlock(); |
1282 | return ret; | 1298 | return ret; |
1283 | 1299 | ||
@@ -1287,7 +1303,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1287 | if (copy_from_user(&mifi, optval, sizeof(mifi_t))) | 1303 | if (copy_from_user(&mifi, optval, sizeof(mifi_t))) |
1288 | return -EFAULT; | 1304 | return -EFAULT; |
1289 | rtnl_lock(); | 1305 | rtnl_lock(); |
1290 | ret = mif6_delete(mifi); | 1306 | ret = mif6_delete(net, mifi); |
1291 | rtnl_unlock(); | 1307 | rtnl_unlock(); |
1292 | return ret; | 1308 | return ret; |
1293 | 1309 | ||
@@ -1303,9 +1319,10 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1303 | return -EFAULT; | 1319 | return -EFAULT; |
1304 | rtnl_lock(); | 1320 | rtnl_lock(); |
1305 | if (optname == MRT6_DEL_MFC) | 1321 | if (optname == MRT6_DEL_MFC) |
1306 | ret = ip6mr_mfc_delete(&mfc); | 1322 | ret = ip6mr_mfc_delete(net, &mfc); |
1307 | else | 1323 | else |
1308 | ret = ip6mr_mfc_add(&mfc, sk == init_net.ipv6.mroute6_sk); | 1324 | ret = ip6mr_mfc_add(net, &mfc, |
1325 | sk == net->ipv6.mroute6_sk); | ||
1309 | rtnl_unlock(); | 1326 | rtnl_unlock(); |
1310 | return ret; | 1327 | return ret; |
1311 | 1328 | ||
@@ -1317,7 +1334,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1317 | int v; | 1334 | int v; |
1318 | if (get_user(v, (int __user *)optval)) | 1335 | if (get_user(v, (int __user *)optval)) |
1319 | return -EFAULT; | 1336 | return -EFAULT; |
1320 | init_net.ipv6.mroute_do_assert = !!v; | 1337 | net->ipv6.mroute_do_assert = !!v; |
1321 | return 0; | 1338 | return 0; |
1322 | } | 1339 | } |
1323 | 1340 | ||
@@ -1330,10 +1347,10 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1330 | v = !!v; | 1347 | v = !!v; |
1331 | rtnl_lock(); | 1348 | rtnl_lock(); |
1332 | ret = 0; | 1349 | ret = 0; |
1333 | if (v != init_net.ipv6.mroute_do_pim) { | 1350 | if (v != net->ipv6.mroute_do_pim) { |
1334 | init_net.ipv6.mroute_do_pim = v; | 1351 | net->ipv6.mroute_do_pim = v; |
1335 | init_net.ipv6.mroute_do_assert = v; | 1352 | net->ipv6.mroute_do_assert = v; |
1336 | if (init_net.ipv6.mroute_do_pim) | 1353 | if (net->ipv6.mroute_do_pim) |
1337 | ret = inet6_add_protocol(&pim6_protocol, | 1354 | ret = inet6_add_protocol(&pim6_protocol, |
1338 | IPPROTO_PIM); | 1355 | IPPROTO_PIM); |
1339 | else | 1356 | else |
@@ -1365,6 +1382,7 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, | |||
1365 | { | 1382 | { |
1366 | int olr; | 1383 | int olr; |
1367 | int val; | 1384 | int val; |
1385 | struct net *net = sock_net(sk); | ||
1368 | 1386 | ||
1369 | switch (optname) { | 1387 | switch (optname) { |
1370 | case MRT6_VERSION: | 1388 | case MRT6_VERSION: |
@@ -1372,11 +1390,11 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, | |||
1372 | break; | 1390 | break; |
1373 | #ifdef CONFIG_IPV6_PIMSM_V2 | 1391 | #ifdef CONFIG_IPV6_PIMSM_V2 |
1374 | case MRT6_PIM: | 1392 | case MRT6_PIM: |
1375 | val = init_net.ipv6.mroute_do_pim; | 1393 | val = net->ipv6.mroute_do_pim; |
1376 | break; | 1394 | break; |
1377 | #endif | 1395 | #endif |
1378 | case MRT6_ASSERT: | 1396 | case MRT6_ASSERT: |
1379 | val = init_net.ipv6.mroute_do_assert; | 1397 | val = net->ipv6.mroute_do_assert; |
1380 | break; | 1398 | break; |
1381 | default: | 1399 | default: |
1382 | return -ENOPROTOOPT; | 1400 | return -ENOPROTOOPT; |
@@ -1406,16 +1424,17 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1406 | struct sioc_mif_req6 vr; | 1424 | struct sioc_mif_req6 vr; |
1407 | struct mif_device *vif; | 1425 | struct mif_device *vif; |
1408 | struct mfc6_cache *c; | 1426 | struct mfc6_cache *c; |
1427 | struct net *net = sock_net(sk); | ||
1409 | 1428 | ||
1410 | switch (cmd) { | 1429 | switch (cmd) { |
1411 | case SIOCGETMIFCNT_IN6: | 1430 | case SIOCGETMIFCNT_IN6: |
1412 | if (copy_from_user(&vr, arg, sizeof(vr))) | 1431 | if (copy_from_user(&vr, arg, sizeof(vr))) |
1413 | return -EFAULT; | 1432 | return -EFAULT; |
1414 | if (vr.mifi >= init_net.ipv6.maxvif) | 1433 | if (vr.mifi >= net->ipv6.maxvif) |
1415 | return -EINVAL; | 1434 | return -EINVAL; |
1416 | read_lock(&mrt_lock); | 1435 | read_lock(&mrt_lock); |
1417 | vif = &init_net.ipv6.vif6_table[vr.mifi]; | 1436 | vif = &net->ipv6.vif6_table[vr.mifi]; |
1418 | if (MIF_EXISTS(&init_net, vr.mifi)) { | 1437 | if (MIF_EXISTS(net, vr.mifi)) { |
1419 | vr.icount = vif->pkt_in; | 1438 | vr.icount = vif->pkt_in; |
1420 | vr.ocount = vif->pkt_out; | 1439 | vr.ocount = vif->pkt_out; |
1421 | vr.ibytes = vif->bytes_in; | 1440 | vr.ibytes = vif->bytes_in; |
@@ -1433,7 +1452,7 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1433 | return -EFAULT; | 1452 | return -EFAULT; |
1434 | 1453 | ||
1435 | read_lock(&mrt_lock); | 1454 | read_lock(&mrt_lock); |
1436 | c = ip6mr_cache_find(&sr.src.sin6_addr, &sr.grp.sin6_addr); | 1455 | c = ip6mr_cache_find(net, &sr.src.sin6_addr, &sr.grp.sin6_addr); |
1437 | if (c) { | 1456 | if (c) { |
1438 | sr.pktcnt = c->mfc_un.res.pkt; | 1457 | sr.pktcnt = c->mfc_un.res.pkt; |
1439 | sr.bytecnt = c->mfc_un.res.bytes; | 1458 | sr.bytecnt = c->mfc_un.res.bytes; |
@@ -1466,7 +1485,8 @@ static inline int ip6mr_forward2_finish(struct sk_buff *skb) | |||
1466 | static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi) | 1485 | static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi) |
1467 | { | 1486 | { |
1468 | struct ipv6hdr *ipv6h; | 1487 | struct ipv6hdr *ipv6h; |
1469 | struct mif_device *vif = &init_net.ipv6.vif6_table[vifi]; | 1488 | struct net *net = mfc6_net(c); |
1489 | struct mif_device *vif = &net->ipv6.vif6_table[vifi]; | ||
1470 | struct net_device *dev; | 1490 | struct net_device *dev; |
1471 | struct dst_entry *dst; | 1491 | struct dst_entry *dst; |
1472 | struct flowi fl; | 1492 | struct flowi fl; |
@@ -1480,7 +1500,7 @@ static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi) | |||
1480 | vif->bytes_out += skb->len; | 1500 | vif->bytes_out += skb->len; |
1481 | vif->dev->stats.tx_bytes += skb->len; | 1501 | vif->dev->stats.tx_bytes += skb->len; |
1482 | vif->dev->stats.tx_packets++; | 1502 | vif->dev->stats.tx_packets++; |
1483 | ip6mr_cache_report(skb, vifi, MRT6MSG_WHOLEPKT); | 1503 | ip6mr_cache_report(net, skb, vifi, MRT6MSG_WHOLEPKT); |
1484 | kfree_skb(skb); | 1504 | kfree_skb(skb); |
1485 | return 0; | 1505 | return 0; |
1486 | } | 1506 | } |
@@ -1495,7 +1515,7 @@ static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi) | |||
1495 | } | 1515 | } |
1496 | }; | 1516 | }; |
1497 | 1517 | ||
1498 | dst = ip6_route_output(&init_net, NULL, &fl); | 1518 | dst = ip6_route_output(net, NULL, &fl); |
1499 | if (!dst) | 1519 | if (!dst) |
1500 | goto out_free; | 1520 | goto out_free; |
1501 | 1521 | ||
@@ -1538,9 +1558,10 @@ out_free: | |||
1538 | 1558 | ||
1539 | static int ip6mr_find_vif(struct net_device *dev) | 1559 | static int ip6mr_find_vif(struct net_device *dev) |
1540 | { | 1560 | { |
1561 | struct net *net = dev_net(dev); | ||
1541 | int ct; | 1562 | int ct; |
1542 | for (ct = init_net.ipv6.maxvif - 1; ct >= 0; ct--) { | 1563 | for (ct = net->ipv6.maxvif - 1; ct >= 0; ct--) { |
1543 | if (init_net.ipv6.vif6_table[ct].dev == dev) | 1564 | if (net->ipv6.vif6_table[ct].dev == dev) |
1544 | break; | 1565 | break; |
1545 | } | 1566 | } |
1546 | return ct; | 1567 | return ct; |
@@ -1550,6 +1571,7 @@ static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache) | |||
1550 | { | 1571 | { |
1551 | int psend = -1; | 1572 | int psend = -1; |
1552 | int vif, ct; | 1573 | int vif, ct; |
1574 | struct net *net = mfc6_net(cache); | ||
1553 | 1575 | ||
1554 | vif = cache->mf6c_parent; | 1576 | vif = cache->mf6c_parent; |
1555 | cache->mfc_un.res.pkt++; | 1577 | cache->mfc_un.res.pkt++; |
@@ -1558,30 +1580,30 @@ static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache) | |||
1558 | /* | 1580 | /* |
1559 | * Wrong interface: drop packet and (maybe) send PIM assert. | 1581 | * Wrong interface: drop packet and (maybe) send PIM assert. |
1560 | */ | 1582 | */ |
1561 | if (init_net.ipv6.vif6_table[vif].dev != skb->dev) { | 1583 | if (net->ipv6.vif6_table[vif].dev != skb->dev) { |
1562 | int true_vifi; | 1584 | int true_vifi; |
1563 | 1585 | ||
1564 | cache->mfc_un.res.wrong_if++; | 1586 | cache->mfc_un.res.wrong_if++; |
1565 | true_vifi = ip6mr_find_vif(skb->dev); | 1587 | true_vifi = ip6mr_find_vif(skb->dev); |
1566 | 1588 | ||
1567 | if (true_vifi >= 0 && init_net.ipv6.mroute_do_assert && | 1589 | if (true_vifi >= 0 && net->ipv6.mroute_do_assert && |
1568 | /* pimsm uses asserts, when switching from RPT to SPT, | 1590 | /* pimsm uses asserts, when switching from RPT to SPT, |
1569 | so that we cannot check that packet arrived on an oif. | 1591 | so that we cannot check that packet arrived on an oif. |
1570 | It is bad, but otherwise we would need to move pretty | 1592 | It is bad, but otherwise we would need to move pretty |
1571 | large chunk of pimd to kernel. Ough... --ANK | 1593 | large chunk of pimd to kernel. Ough... --ANK |
1572 | */ | 1594 | */ |
1573 | (init_net.ipv6.mroute_do_pim || | 1595 | (net->ipv6.mroute_do_pim || |
1574 | cache->mfc_un.res.ttls[true_vifi] < 255) && | 1596 | cache->mfc_un.res.ttls[true_vifi] < 255) && |
1575 | time_after(jiffies, | 1597 | time_after(jiffies, |
1576 | cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) { | 1598 | cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) { |
1577 | cache->mfc_un.res.last_assert = jiffies; | 1599 | cache->mfc_un.res.last_assert = jiffies; |
1578 | ip6mr_cache_report(skb, true_vifi, MRT6MSG_WRONGMIF); | 1600 | ip6mr_cache_report(net, skb, true_vifi, MRT6MSG_WRONGMIF); |
1579 | } | 1601 | } |
1580 | goto dont_forward; | 1602 | goto dont_forward; |
1581 | } | 1603 | } |
1582 | 1604 | ||
1583 | init_net.ipv6.vif6_table[vif].pkt_in++; | 1605 | net->ipv6.vif6_table[vif].pkt_in++; |
1584 | init_net.ipv6.vif6_table[vif].bytes_in += skb->len; | 1606 | net->ipv6.vif6_table[vif].bytes_in += skb->len; |
1585 | 1607 | ||
1586 | /* | 1608 | /* |
1587 | * Forward the frame | 1609 | * Forward the frame |
@@ -1614,9 +1636,11 @@ dont_forward: | |||
1614 | int ip6_mr_input(struct sk_buff *skb) | 1636 | int ip6_mr_input(struct sk_buff *skb) |
1615 | { | 1637 | { |
1616 | struct mfc6_cache *cache; | 1638 | struct mfc6_cache *cache; |
1639 | struct net *net = dev_net(skb->dev); | ||
1617 | 1640 | ||
1618 | read_lock(&mrt_lock); | 1641 | read_lock(&mrt_lock); |
1619 | cache = ip6mr_cache_find(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr); | 1642 | cache = ip6mr_cache_find(net, |
1643 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr); | ||
1620 | 1644 | ||
1621 | /* | 1645 | /* |
1622 | * No usable cache entry | 1646 | * No usable cache entry |
@@ -1626,7 +1650,7 @@ int ip6_mr_input(struct sk_buff *skb) | |||
1626 | 1650 | ||
1627 | vif = ip6mr_find_vif(skb->dev); | 1651 | vif = ip6mr_find_vif(skb->dev); |
1628 | if (vif >= 0) { | 1652 | if (vif >= 0) { |
1629 | int err = ip6mr_cache_unresolved(vif, skb); | 1653 | int err = ip6mr_cache_unresolved(net, vif, skb); |
1630 | read_unlock(&mrt_lock); | 1654 | read_unlock(&mrt_lock); |
1631 | 1655 | ||
1632 | return err; | 1656 | return err; |
@@ -1649,7 +1673,8 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm) | |||
1649 | { | 1673 | { |
1650 | int ct; | 1674 | int ct; |
1651 | struct rtnexthop *nhp; | 1675 | struct rtnexthop *nhp; |
1652 | struct net_device *dev = init_net.ipv6.vif6_table[c->mf6c_parent].dev; | 1676 | struct net *net = mfc6_net(c); |
1677 | struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev; | ||
1653 | u8 *b = skb_tail_pointer(skb); | 1678 | u8 *b = skb_tail_pointer(skb); |
1654 | struct rtattr *mp_head; | 1679 | struct rtattr *mp_head; |
1655 | 1680 | ||
@@ -1665,7 +1690,7 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm) | |||
1665 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); | 1690 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); |
1666 | nhp->rtnh_flags = 0; | 1691 | nhp->rtnh_flags = 0; |
1667 | nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; | 1692 | nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; |
1668 | nhp->rtnh_ifindex = init_net.ipv6.vif6_table[ct].dev->ifindex; | 1693 | nhp->rtnh_ifindex = net->ipv6.vif6_table[ct].dev->ifindex; |
1669 | nhp->rtnh_len = sizeof(*nhp); | 1694 | nhp->rtnh_len = sizeof(*nhp); |
1670 | } | 1695 | } |
1671 | } | 1696 | } |
@@ -1679,14 +1704,15 @@ rtattr_failure: | |||
1679 | return -EMSGSIZE; | 1704 | return -EMSGSIZE; |
1680 | } | 1705 | } |
1681 | 1706 | ||
1682 | int ip6mr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait) | 1707 | int ip6mr_get_route(struct net *net, |
1708 | struct sk_buff *skb, struct rtmsg *rtm, int nowait) | ||
1683 | { | 1709 | { |
1684 | int err; | 1710 | int err; |
1685 | struct mfc6_cache *cache; | 1711 | struct mfc6_cache *cache; |
1686 | struct rt6_info *rt = (struct rt6_info *)skb->dst; | 1712 | struct rt6_info *rt = (struct rt6_info *)skb->dst; |
1687 | 1713 | ||
1688 | read_lock(&mrt_lock); | 1714 | read_lock(&mrt_lock); |
1689 | cache = ip6mr_cache_find(&rt->rt6i_src.addr, &rt->rt6i_dst.addr); | 1715 | cache = ip6mr_cache_find(net, &rt->rt6i_src.addr, &rt->rt6i_dst.addr); |
1690 | 1716 | ||
1691 | if (!cache) { | 1717 | if (!cache) { |
1692 | struct sk_buff *skb2; | 1718 | struct sk_buff *skb2; |
@@ -1729,7 +1755,7 @@ int ip6mr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait) | |||
1729 | ipv6_addr_copy(&iph->saddr, &rt->rt6i_src.addr); | 1755 | ipv6_addr_copy(&iph->saddr, &rt->rt6i_src.addr); |
1730 | ipv6_addr_copy(&iph->daddr, &rt->rt6i_dst.addr); | 1756 | ipv6_addr_copy(&iph->daddr, &rt->rt6i_dst.addr); |
1731 | 1757 | ||
1732 | err = ip6mr_cache_unresolved(vif, skb2); | 1758 | err = ip6mr_cache_unresolved(net, vif, skb2); |
1733 | read_unlock(&mrt_lock); | 1759 | read_unlock(&mrt_lock); |
1734 | 1760 | ||
1735 | return err; | 1761 | return err; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 9da1ece466a2..18c486cf4987 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2194,7 +2194,7 @@ static int rt6_fill_node(struct net *net, | |||
2194 | if (iif) { | 2194 | if (iif) { |
2195 | #ifdef CONFIG_IPV6_MROUTE | 2195 | #ifdef CONFIG_IPV6_MROUTE |
2196 | if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { | 2196 | if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { |
2197 | int err = ip6mr_get_route(skb, rtm, nowait); | 2197 | int err = ip6mr_get_route(net, skb, rtm, nowait); |
2198 | if (err <= 0) { | 2198 | if (err <= 0) { |
2199 | if (!nowait) { | 2199 | if (!nowait) { |
2200 | if (err == 0) | 2200 | if (err == 0) |