diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 113 |
1 files changed, 50 insertions, 63 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 127021bdd180..c878fb681efb 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -561,7 +561,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
561 | write_lock(&addrconf_hash_lock); | 561 | write_lock(&addrconf_hash_lock); |
562 | 562 | ||
563 | /* Ignore adding duplicate addresses on an interface */ | 563 | /* Ignore adding duplicate addresses on an interface */ |
564 | if (ipv6_chk_same_addr(&init_net, addr, idev->dev)) { | 564 | if (ipv6_chk_same_addr(idev->dev->nd_net, addr, idev->dev)) { |
565 | ADBG(("ipv6_add_addr: already assigned\n")); | 565 | ADBG(("ipv6_add_addr: already assigned\n")); |
566 | err = -EEXIST; | 566 | err = -EEXIST; |
567 | goto out; | 567 | goto out; |
@@ -751,9 +751,9 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
751 | if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) { | 751 | if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) { |
752 | struct in6_addr prefix; | 752 | struct in6_addr prefix; |
753 | struct rt6_info *rt; | 753 | struct rt6_info *rt; |
754 | 754 | struct net *net = ifp->idev->dev->nd_net; | |
755 | ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); | 755 | ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); |
756 | rt = rt6_lookup(&init_net, &prefix, NULL, ifp->idev->dev->ifindex, 1); | 756 | rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); |
757 | 757 | ||
758 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { | 758 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { |
759 | if (onlink == 0) { | 759 | if (onlink == 0) { |
@@ -905,6 +905,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
905 | { | 905 | { |
906 | struct ipv6_saddr_score hiscore; | 906 | struct ipv6_saddr_score hiscore; |
907 | struct inet6_ifaddr *ifa_result = NULL; | 907 | struct inet6_ifaddr *ifa_result = NULL; |
908 | struct net *net = daddr_dev->nd_net; | ||
908 | int daddr_type = __ipv6_addr_type(daddr); | 909 | int daddr_type = __ipv6_addr_type(daddr); |
909 | int daddr_scope = __ipv6_addr_src_scope(daddr_type); | 910 | int daddr_scope = __ipv6_addr_src_scope(daddr_type); |
910 | int daddr_ifindex = daddr_dev ? daddr_dev->ifindex : 0; | 911 | int daddr_ifindex = daddr_dev ? daddr_dev->ifindex : 0; |
@@ -916,7 +917,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
916 | read_lock(&dev_base_lock); | 917 | read_lock(&dev_base_lock); |
917 | rcu_read_lock(); | 918 | rcu_read_lock(); |
918 | 919 | ||
919 | for_each_netdev(&init_net, dev) { | 920 | for_each_netdev(net, dev) { |
920 | struct inet6_dev *idev; | 921 | struct inet6_dev *idev; |
921 | struct inet6_ifaddr *ifa; | 922 | struct inet6_ifaddr *ifa; |
922 | 923 | ||
@@ -1555,7 +1556,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
1555 | .fc_expires = expires, | 1556 | .fc_expires = expires, |
1556 | .fc_dst_len = plen, | 1557 | .fc_dst_len = plen, |
1557 | .fc_flags = RTF_UP | flags, | 1558 | .fc_flags = RTF_UP | flags, |
1558 | .fc_nlinfo.nl_net = &init_net, | 1559 | .fc_nlinfo.nl_net = dev->nd_net, |
1559 | }; | 1560 | }; |
1560 | 1561 | ||
1561 | ipv6_addr_copy(&cfg.fc_dst, pfx); | 1562 | ipv6_addr_copy(&cfg.fc_dst, pfx); |
@@ -1582,7 +1583,7 @@ static void addrconf_add_mroute(struct net_device *dev) | |||
1582 | .fc_ifindex = dev->ifindex, | 1583 | .fc_ifindex = dev->ifindex, |
1583 | .fc_dst_len = 8, | 1584 | .fc_dst_len = 8, |
1584 | .fc_flags = RTF_UP, | 1585 | .fc_flags = RTF_UP, |
1585 | .fc_nlinfo.nl_net = &init_net, | 1586 | .fc_nlinfo.nl_net = dev->nd_net, |
1586 | }; | 1587 | }; |
1587 | 1588 | ||
1588 | ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); | 1589 | ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); |
@@ -1599,7 +1600,7 @@ static void sit_route_add(struct net_device *dev) | |||
1599 | .fc_ifindex = dev->ifindex, | 1600 | .fc_ifindex = dev->ifindex, |
1600 | .fc_dst_len = 96, | 1601 | .fc_dst_len = 96, |
1601 | .fc_flags = RTF_UP | RTF_NONEXTHOP, | 1602 | .fc_flags = RTF_UP | RTF_NONEXTHOP, |
1602 | .fc_nlinfo.nl_net = &init_net, | 1603 | .fc_nlinfo.nl_net = dev->nd_net, |
1603 | }; | 1604 | }; |
1604 | 1605 | ||
1605 | /* prefix length - 96 bits "::d.d.d.d" */ | 1606 | /* prefix length - 96 bits "::d.d.d.d" */ |
@@ -1700,7 +1701,8 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1700 | 1701 | ||
1701 | if (pinfo->onlink) { | 1702 | if (pinfo->onlink) { |
1702 | struct rt6_info *rt; | 1703 | struct rt6_info *rt; |
1703 | rt = rt6_lookup(&init_net, &pinfo->prefix, NULL, dev->ifindex, 1); | 1704 | rt = rt6_lookup(dev->nd_net, &pinfo->prefix, NULL, |
1705 | dev->ifindex, 1); | ||
1704 | 1706 | ||
1705 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { | 1707 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { |
1706 | if (rt->rt6i_flags&RTF_EXPIRES) { | 1708 | if (rt->rt6i_flags&RTF_EXPIRES) { |
@@ -1743,7 +1745,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1743 | 1745 | ||
1744 | ok: | 1746 | ok: |
1745 | 1747 | ||
1746 | ifp = ipv6_get_ifaddr(&init_net, &addr, dev, 1); | 1748 | ifp = ipv6_get_ifaddr(dev->nd_net, &addr, dev, 1); |
1747 | 1749 | ||
1748 | if (ifp == NULL && valid_lft) { | 1750 | if (ifp == NULL && valid_lft) { |
1749 | int max_addresses = in6_dev->cnf.max_addresses; | 1751 | int max_addresses = in6_dev->cnf.max_addresses; |
@@ -2066,6 +2068,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2066 | struct inet6_ifaddr * ifp; | 2068 | struct inet6_ifaddr * ifp; |
2067 | struct in6_addr addr; | 2069 | struct in6_addr addr; |
2068 | struct net_device *dev; | 2070 | struct net_device *dev; |
2071 | struct net *net = idev->dev->nd_net; | ||
2069 | int scope; | 2072 | int scope; |
2070 | 2073 | ||
2071 | ASSERT_RTNL(); | 2074 | ASSERT_RTNL(); |
@@ -2092,7 +2095,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2092 | return; | 2095 | return; |
2093 | } | 2096 | } |
2094 | 2097 | ||
2095 | for_each_netdev(&init_net, dev) { | 2098 | for_each_netdev(net, dev) { |
2096 | struct in_device * in_dev = __in_dev_get_rtnl(dev); | 2099 | struct in_device * in_dev = __in_dev_get_rtnl(dev); |
2097 | if (in_dev && (dev->flags & IFF_UP)) { | 2100 | if (in_dev && (dev->flags & IFF_UP)) { |
2098 | struct in_ifaddr * ifa; | 2101 | struct in_ifaddr * ifa; |
@@ -2255,15 +2258,16 @@ ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) | |||
2255 | static void ip6_tnl_add_linklocal(struct inet6_dev *idev) | 2258 | static void ip6_tnl_add_linklocal(struct inet6_dev *idev) |
2256 | { | 2259 | { |
2257 | struct net_device *link_dev; | 2260 | struct net_device *link_dev; |
2261 | struct net *net = idev->dev->nd_net; | ||
2258 | 2262 | ||
2259 | /* first try to inherit the link-local address from the link device */ | 2263 | /* first try to inherit the link-local address from the link device */ |
2260 | if (idev->dev->iflink && | 2264 | if (idev->dev->iflink && |
2261 | (link_dev = __dev_get_by_index(&init_net, idev->dev->iflink))) { | 2265 | (link_dev = __dev_get_by_index(net, idev->dev->iflink))) { |
2262 | if (!ipv6_inherit_linklocal(idev, link_dev)) | 2266 | if (!ipv6_inherit_linklocal(idev, link_dev)) |
2263 | return; | 2267 | return; |
2264 | } | 2268 | } |
2265 | /* then try to inherit it from any device */ | 2269 | /* then try to inherit it from any device */ |
2266 | for_each_netdev(&init_net, link_dev) { | 2270 | for_each_netdev(net, link_dev) { |
2267 | if (!ipv6_inherit_linklocal(idev, link_dev)) | 2271 | if (!ipv6_inherit_linklocal(idev, link_dev)) |
2268 | return; | 2272 | return; |
2269 | } | 2273 | } |
@@ -2296,9 +2300,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2296 | int run_pending = 0; | 2300 | int run_pending = 0; |
2297 | int err; | 2301 | int err; |
2298 | 2302 | ||
2299 | if (dev->nd_net != &init_net) | ||
2300 | return NOTIFY_DONE; | ||
2301 | |||
2302 | switch(event) { | 2303 | switch(event) { |
2303 | case NETDEV_REGISTER: | 2304 | case NETDEV_REGISTER: |
2304 | if (!idev && dev->mtu >= IPV6_MIN_MTU) { | 2305 | if (!idev && dev->mtu >= IPV6_MIN_MTU) { |
@@ -3056,9 +3057,6 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3056 | struct in6_addr *pfx; | 3057 | struct in6_addr *pfx; |
3057 | int err; | 3058 | int err; |
3058 | 3059 | ||
3059 | if (net != &init_net) | ||
3060 | return -EINVAL; | ||
3061 | |||
3062 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3060 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3063 | if (err < 0) | 3061 | if (err < 0) |
3064 | return err; | 3062 | return err; |
@@ -3121,9 +3119,6 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3121 | u8 ifa_flags; | 3119 | u8 ifa_flags; |
3122 | int err; | 3120 | int err; |
3123 | 3121 | ||
3124 | if (net != &init_net) | ||
3125 | return -EINVAL; | ||
3126 | |||
3127 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3122 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3128 | if (err < 0) | 3123 | if (err < 0) |
3129 | return err; | 3124 | return err; |
@@ -3324,12 +3319,13 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
3324 | struct inet6_ifaddr *ifa; | 3319 | struct inet6_ifaddr *ifa; |
3325 | struct ifmcaddr6 *ifmca; | 3320 | struct ifmcaddr6 *ifmca; |
3326 | struct ifacaddr6 *ifaca; | 3321 | struct ifacaddr6 *ifaca; |
3322 | struct net *net = skb->sk->sk_net; | ||
3327 | 3323 | ||
3328 | s_idx = cb->args[0]; | 3324 | s_idx = cb->args[0]; |
3329 | s_ip_idx = ip_idx = cb->args[1]; | 3325 | s_ip_idx = ip_idx = cb->args[1]; |
3330 | 3326 | ||
3331 | idx = 0; | 3327 | idx = 0; |
3332 | for_each_netdev(&init_net, dev) { | 3328 | for_each_netdev(net, dev) { |
3333 | if (idx < s_idx) | 3329 | if (idx < s_idx) |
3334 | goto cont; | 3330 | goto cont; |
3335 | if (idx > s_idx) | 3331 | if (idx > s_idx) |
@@ -3396,35 +3392,23 @@ cont: | |||
3396 | 3392 | ||
3397 | static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3393 | static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3398 | { | 3394 | { |
3399 | struct net *net = skb->sk->sk_net; | ||
3400 | enum addr_type_t type = UNICAST_ADDR; | 3395 | enum addr_type_t type = UNICAST_ADDR; |
3401 | 3396 | ||
3402 | if (net != &init_net) | ||
3403 | return 0; | ||
3404 | |||
3405 | return inet6_dump_addr(skb, cb, type); | 3397 | return inet6_dump_addr(skb, cb, type); |
3406 | } | 3398 | } |
3407 | 3399 | ||
3408 | static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3400 | static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3409 | { | 3401 | { |
3410 | struct net *net = skb->sk->sk_net; | ||
3411 | enum addr_type_t type = MULTICAST_ADDR; | 3402 | enum addr_type_t type = MULTICAST_ADDR; |
3412 | 3403 | ||
3413 | if (net != &init_net) | ||
3414 | return 0; | ||
3415 | |||
3416 | return inet6_dump_addr(skb, cb, type); | 3404 | return inet6_dump_addr(skb, cb, type); |
3417 | } | 3405 | } |
3418 | 3406 | ||
3419 | 3407 | ||
3420 | static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3408 | static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3421 | { | 3409 | { |
3422 | struct net *net = skb->sk->sk_net; | ||
3423 | enum addr_type_t type = ANYCAST_ADDR; | 3410 | enum addr_type_t type = ANYCAST_ADDR; |
3424 | 3411 | ||
3425 | if (net != &init_net) | ||
3426 | return 0; | ||
3427 | |||
3428 | return inet6_dump_addr(skb, cb, type); | 3412 | return inet6_dump_addr(skb, cb, type); |
3429 | } | 3413 | } |
3430 | 3414 | ||
@@ -3440,9 +3424,6 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3440 | struct sk_buff *skb; | 3424 | struct sk_buff *skb; |
3441 | int err; | 3425 | int err; |
3442 | 3426 | ||
3443 | if (net != &init_net) | ||
3444 | return -EINVAL; | ||
3445 | |||
3446 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3427 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3447 | if (err < 0) | 3428 | if (err < 0) |
3448 | goto errout; | 3429 | goto errout; |
@@ -3455,7 +3436,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3455 | 3436 | ||
3456 | ifm = nlmsg_data(nlh); | 3437 | ifm = nlmsg_data(nlh); |
3457 | if (ifm->ifa_index) | 3438 | if (ifm->ifa_index) |
3458 | dev = __dev_get_by_index(&init_net, ifm->ifa_index); | 3439 | dev = __dev_get_by_index(net, ifm->ifa_index); |
3459 | 3440 | ||
3460 | if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) { | 3441 | if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) { |
3461 | err = -EADDRNOTAVAIL; | 3442 | err = -EADDRNOTAVAIL; |
@@ -3475,7 +3456,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3475 | kfree_skb(skb); | 3456 | kfree_skb(skb); |
3476 | goto errout_ifa; | 3457 | goto errout_ifa; |
3477 | } | 3458 | } |
3478 | err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); | 3459 | err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); |
3479 | errout_ifa: | 3460 | errout_ifa: |
3480 | in6_ifa_put(ifa); | 3461 | in6_ifa_put(ifa); |
3481 | errout: | 3462 | errout: |
@@ -3485,6 +3466,7 @@ errout: | |||
3485 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | 3466 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) |
3486 | { | 3467 | { |
3487 | struct sk_buff *skb; | 3468 | struct sk_buff *skb; |
3469 | struct net *net = ifa->idev->dev->nd_net; | ||
3488 | int err = -ENOBUFS; | 3470 | int err = -ENOBUFS; |
3489 | 3471 | ||
3490 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); | 3472 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); |
@@ -3498,10 +3480,10 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | |||
3498 | kfree_skb(skb); | 3480 | kfree_skb(skb); |
3499 | goto errout; | 3481 | goto errout; |
3500 | } | 3482 | } |
3501 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 3483 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); |
3502 | errout: | 3484 | errout: |
3503 | if (err < 0) | 3485 | if (err < 0) |
3504 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err); | 3486 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); |
3505 | } | 3487 | } |
3506 | 3488 | ||
3507 | static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | 3489 | static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, |
@@ -3666,12 +3648,9 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
3666 | struct net_device *dev; | 3648 | struct net_device *dev; |
3667 | struct inet6_dev *idev; | 3649 | struct inet6_dev *idev; |
3668 | 3650 | ||
3669 | if (net != &init_net) | ||
3670 | return 0; | ||
3671 | |||
3672 | read_lock(&dev_base_lock); | 3651 | read_lock(&dev_base_lock); |
3673 | idx = 0; | 3652 | idx = 0; |
3674 | for_each_netdev(&init_net, dev) { | 3653 | for_each_netdev(net, dev) { |
3675 | if (idx < s_idx) | 3654 | if (idx < s_idx) |
3676 | goto cont; | 3655 | goto cont; |
3677 | if ((idev = in6_dev_get(dev)) == NULL) | 3656 | if ((idev = in6_dev_get(dev)) == NULL) |
@@ -3693,6 +3672,7 @@ cont: | |||
3693 | void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | 3672 | void inet6_ifinfo_notify(int event, struct inet6_dev *idev) |
3694 | { | 3673 | { |
3695 | struct sk_buff *skb; | 3674 | struct sk_buff *skb; |
3675 | struct net *net = idev->dev->nd_net; | ||
3696 | int err = -ENOBUFS; | 3676 | int err = -ENOBUFS; |
3697 | 3677 | ||
3698 | skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC); | 3678 | skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC); |
@@ -3706,10 +3686,10 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | |||
3706 | kfree_skb(skb); | 3686 | kfree_skb(skb); |
3707 | goto errout; | 3687 | goto errout; |
3708 | } | 3688 | } |
3709 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 3689 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); |
3710 | errout: | 3690 | errout: |
3711 | if (err < 0) | 3691 | if (err < 0) |
3712 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err); | 3692 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); |
3713 | } | 3693 | } |
3714 | 3694 | ||
3715 | static inline size_t inet6_prefix_nlmsg_size(void) | 3695 | static inline size_t inet6_prefix_nlmsg_size(void) |
@@ -3762,6 +3742,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3762 | struct prefix_info *pinfo) | 3742 | struct prefix_info *pinfo) |
3763 | { | 3743 | { |
3764 | struct sk_buff *skb; | 3744 | struct sk_buff *skb; |
3745 | struct net *net = idev->dev->nd_net; | ||
3765 | int err = -ENOBUFS; | 3746 | int err = -ENOBUFS; |
3766 | 3747 | ||
3767 | skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC); | 3748 | skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC); |
@@ -3775,10 +3756,10 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3775 | kfree_skb(skb); | 3756 | kfree_skb(skb); |
3776 | goto errout; | 3757 | goto errout; |
3777 | } | 3758 | } |
3778 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); | 3759 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); |
3779 | errout: | 3760 | errout: |
3780 | if (err < 0) | 3761 | if (err < 0) |
3781 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_PREFIX, err); | 3762 | rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err); |
3782 | } | 3763 | } |
3783 | 3764 | ||
3784 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | 3765 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) |
@@ -4276,7 +4257,26 @@ static int addrconf_net_init(struct net *net) | |||
4276 | 4257 | ||
4277 | static void addrconf_net_exit(struct net *net) | 4258 | static void addrconf_net_exit(struct net *net) |
4278 | { | 4259 | { |
4279 | ; | 4260 | struct net_device *dev; |
4261 | |||
4262 | /* | ||
4263 | * Remove loopback references from default routing entries | ||
4264 | */ | ||
4265 | /* in6_dev_put(net->ipv6.ip6_null_entry->rt6i_idev); */ | ||
4266 | /* #ifdef CONFIG_IPV6_MULTIPLE_TABLES */ | ||
4267 | /* in6_dev_put(net->ipv6.ip6_prohibit_entry->rt6i_idev); */ | ||
4268 | /* in6_dev_put(net->ipv6.ip6_blk_hole_entry->rt6i_idev); */ | ||
4269 | /* #endif */ | ||
4270 | |||
4271 | rtnl_lock(); | ||
4272 | /* clean dev list */ | ||
4273 | for_each_netdev(net, dev) { | ||
4274 | if (__in6_dev_get(dev) == NULL) | ||
4275 | continue; | ||
4276 | addrconf_ifdown(dev, 1); | ||
4277 | } | ||
4278 | addrconf_ifdown(net->loopback_dev, 2); | ||
4279 | rtnl_unlock(); | ||
4280 | } | 4280 | } |
4281 | 4281 | ||
4282 | static struct pernet_operations addrconf_net_ops = { | 4282 | static struct pernet_operations addrconf_net_ops = { |
@@ -4357,7 +4357,6 @@ errlo: | |||
4357 | 4357 | ||
4358 | void addrconf_cleanup(void) | 4358 | void addrconf_cleanup(void) |
4359 | { | 4359 | { |
4360 | struct net_device *dev; | ||
4361 | struct inet6_ifaddr *ifa; | 4360 | struct inet6_ifaddr *ifa; |
4362 | int i; | 4361 | int i; |
4363 | 4362 | ||
@@ -4369,20 +4368,8 @@ void addrconf_cleanup(void) | |||
4369 | rtnl_lock(); | 4368 | rtnl_lock(); |
4370 | 4369 | ||
4371 | /* | 4370 | /* |
4372 | * clean dev list. | ||
4373 | */ | ||
4374 | |||
4375 | for_each_netdev(&init_net, dev) { | ||
4376 | if (__in6_dev_get(dev) == NULL) | ||
4377 | continue; | ||
4378 | addrconf_ifdown(dev, 1); | ||
4379 | } | ||
4380 | addrconf_ifdown(init_net.loopback_dev, 2); | ||
4381 | |||
4382 | /* | ||
4383 | * Check hash table. | 4371 | * Check hash table. |
4384 | */ | 4372 | */ |
4385 | |||
4386 | write_lock_bh(&addrconf_hash_lock); | 4373 | write_lock_bh(&addrconf_hash_lock); |
4387 | for (i=0; i < IN6_ADDR_HSIZE; i++) { | 4374 | for (i=0; i < IN6_ADDR_HSIZE; i++) { |
4388 | for (ifa=inet6_addr_lst[i]; ifa; ) { | 4375 | for (ifa=inet6_addr_lst[i]; ifa; ) { |