diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 765 |
1 files changed, 416 insertions, 349 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e08955baedff..8a0fd4007bdb 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -222,6 +222,8 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { | |||
222 | /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ | 222 | /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ |
223 | const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; | 223 | const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; |
224 | const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; | 224 | const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; |
225 | const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT; | ||
226 | const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; | ||
225 | 227 | ||
226 | /* Check if a valid qdisc is available */ | 228 | /* Check if a valid qdisc is available */ |
227 | static inline int addrconf_qdisc_ok(struct net_device *dev) | 229 | static inline int addrconf_qdisc_ok(struct net_device *dev) |
@@ -321,7 +323,6 @@ EXPORT_SYMBOL(in6_dev_finish_destroy); | |||
321 | static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | 323 | static struct inet6_dev * ipv6_add_dev(struct net_device *dev) |
322 | { | 324 | { |
323 | struct inet6_dev *ndev; | 325 | struct inet6_dev *ndev; |
324 | struct in6_addr maddr; | ||
325 | 326 | ||
326 | ASSERT_RTNL(); | 327 | ASSERT_RTNL(); |
327 | 328 | ||
@@ -335,7 +336,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
335 | 336 | ||
336 | rwlock_init(&ndev->lock); | 337 | rwlock_init(&ndev->lock); |
337 | ndev->dev = dev; | 338 | ndev->dev = dev; |
338 | memcpy(&ndev->cnf, dev->nd_net->ipv6.devconf_dflt, sizeof(ndev->cnf)); | 339 | memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf)); |
339 | ndev->cnf.mtu6 = dev->mtu; | 340 | ndev->cnf.mtu6 = dev->mtu; |
340 | ndev->cnf.sysctl = NULL; | 341 | ndev->cnf.sysctl = NULL; |
341 | ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl); | 342 | ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl); |
@@ -349,7 +350,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
349 | if (snmp6_alloc_dev(ndev) < 0) { | 350 | if (snmp6_alloc_dev(ndev) < 0) { |
350 | ADBG((KERN_WARNING | 351 | ADBG((KERN_WARNING |
351 | "%s(): cannot allocate memory for statistics; dev=%s.\n", | 352 | "%s(): cannot allocate memory for statistics; dev=%s.\n", |
352 | __FUNCTION__, dev->name)); | 353 | __func__, dev->name)); |
353 | neigh_parms_release(&nd_tbl, ndev->nd_parms); | 354 | neigh_parms_release(&nd_tbl, ndev->nd_parms); |
354 | ndev->dead = 1; | 355 | ndev->dead = 1; |
355 | in6_dev_finish_destroy(ndev); | 356 | in6_dev_finish_destroy(ndev); |
@@ -359,7 +360,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
359 | if (snmp6_register_dev(ndev) < 0) { | 360 | if (snmp6_register_dev(ndev) < 0) { |
360 | ADBG((KERN_WARNING | 361 | ADBG((KERN_WARNING |
361 | "%s(): cannot create /proc/net/dev_snmp6/%s\n", | 362 | "%s(): cannot create /proc/net/dev_snmp6/%s\n", |
362 | __FUNCTION__, dev->name)); | 363 | __func__, dev->name)); |
363 | neigh_parms_release(&nd_tbl, ndev->nd_parms); | 364 | neigh_parms_release(&nd_tbl, ndev->nd_parms); |
364 | ndev->dead = 1; | 365 | ndev->dead = 1; |
365 | in6_dev_finish_destroy(ndev); | 366 | in6_dev_finish_destroy(ndev); |
@@ -407,8 +408,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
407 | rcu_assign_pointer(dev->ip6_ptr, ndev); | 408 | rcu_assign_pointer(dev->ip6_ptr, ndev); |
408 | 409 | ||
409 | /* Join all-node multicast group */ | 410 | /* Join all-node multicast group */ |
410 | ipv6_addr_all_nodes(&maddr); | 411 | ipv6_dev_mc_inc(dev, &in6addr_linklocal_allnodes); |
411 | ipv6_dev_mc_inc(dev, &maddr); | ||
412 | 412 | ||
413 | return ndev; | 413 | return ndev; |
414 | } | 414 | } |
@@ -434,18 +434,15 @@ static void dev_forward_change(struct inet6_dev *idev) | |||
434 | { | 434 | { |
435 | struct net_device *dev; | 435 | struct net_device *dev; |
436 | struct inet6_ifaddr *ifa; | 436 | struct inet6_ifaddr *ifa; |
437 | struct in6_addr addr; | ||
438 | 437 | ||
439 | if (!idev) | 438 | if (!idev) |
440 | return; | 439 | return; |
441 | dev = idev->dev; | 440 | dev = idev->dev; |
442 | if (dev && (dev->flags & IFF_MULTICAST)) { | 441 | if (dev && (dev->flags & IFF_MULTICAST)) { |
443 | ipv6_addr_all_routers(&addr); | ||
444 | |||
445 | if (idev->cnf.forwarding) | 442 | if (idev->cnf.forwarding) |
446 | ipv6_dev_mc_inc(dev, &addr); | 443 | ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters); |
447 | else | 444 | else |
448 | ipv6_dev_mc_dec(dev, &addr); | 445 | ipv6_dev_mc_dec(dev, &in6addr_linklocal_allrouters); |
449 | } | 446 | } |
450 | for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) { | 447 | for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) { |
451 | if (ifa->flags&IFA_F_TENTATIVE) | 448 | if (ifa->flags&IFA_F_TENTATIVE) |
@@ -494,7 +491,7 @@ static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) | |||
494 | dev_forward_change((struct inet6_dev *)table->extra1); | 491 | dev_forward_change((struct inet6_dev *)table->extra1); |
495 | 492 | ||
496 | if (*p) | 493 | if (*p) |
497 | rt6_purge_dflt_routers(); | 494 | rt6_purge_dflt_routers(net); |
498 | } | 495 | } |
499 | #endif | 496 | #endif |
500 | 497 | ||
@@ -542,6 +539,25 @@ ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) | |||
542 | *ifap = ifp; | 539 | *ifap = ifp; |
543 | } | 540 | } |
544 | 541 | ||
542 | /* | ||
543 | * Hash function taken from net_alias.c | ||
544 | */ | ||
545 | static u8 ipv6_addr_hash(const struct in6_addr *addr) | ||
546 | { | ||
547 | __u32 word; | ||
548 | |||
549 | /* | ||
550 | * We perform the hash function over the last 64 bits of the address | ||
551 | * This will include the IEEE address token on links that support it. | ||
552 | */ | ||
553 | |||
554 | word = (__force u32)(addr->s6_addr32[2] ^ addr->s6_addr32[3]); | ||
555 | word ^= (word >> 16); | ||
556 | word ^= (word >> 8); | ||
557 | |||
558 | return ((word ^ (word >> 4)) & 0x0f); | ||
559 | } | ||
560 | |||
545 | /* On success it returns ifp with increased reference count */ | 561 | /* On success it returns ifp with increased reference count */ |
546 | 562 | ||
547 | static struct inet6_ifaddr * | 563 | static struct inet6_ifaddr * |
@@ -562,7 +578,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
562 | write_lock(&addrconf_hash_lock); | 578 | write_lock(&addrconf_hash_lock); |
563 | 579 | ||
564 | /* Ignore adding duplicate addresses on an interface */ | 580 | /* Ignore adding duplicate addresses on an interface */ |
565 | if (ipv6_chk_same_addr(&init_net, addr, idev->dev)) { | 581 | if (ipv6_chk_same_addr(dev_net(idev->dev), addr, idev->dev)) { |
566 | ADBG(("ipv6_add_addr: already assigned\n")); | 582 | ADBG(("ipv6_add_addr: already assigned\n")); |
567 | err = -EEXIST; | 583 | err = -EEXIST; |
568 | goto out; | 584 | goto out; |
@@ -752,9 +768,9 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
752 | if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) { | 768 | if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) { |
753 | struct in6_addr prefix; | 769 | struct in6_addr prefix; |
754 | struct rt6_info *rt; | 770 | struct rt6_info *rt; |
755 | 771 | struct net *net = dev_net(ifp->idev->dev); | |
756 | ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); | 772 | ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); |
757 | rt = rt6_lookup(&prefix, NULL, ifp->idev->dev->ifindex, 1); | 773 | rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); |
758 | 774 | ||
759 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { | 775 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { |
760 | if (onlink == 0) { | 776 | if (onlink == 0) { |
@@ -894,20 +910,40 @@ out: | |||
894 | /* | 910 | /* |
895 | * Choose an appropriate source address (RFC3484) | 911 | * Choose an appropriate source address (RFC3484) |
896 | */ | 912 | */ |
913 | enum { | ||
914 | IPV6_SADDR_RULE_INIT = 0, | ||
915 | IPV6_SADDR_RULE_LOCAL, | ||
916 | IPV6_SADDR_RULE_SCOPE, | ||
917 | IPV6_SADDR_RULE_PREFERRED, | ||
918 | #ifdef CONFIG_IPV6_MIP6 | ||
919 | IPV6_SADDR_RULE_HOA, | ||
920 | #endif | ||
921 | IPV6_SADDR_RULE_OIF, | ||
922 | IPV6_SADDR_RULE_LABEL, | ||
923 | #ifdef CONFIG_IPV6_PRIVACY | ||
924 | IPV6_SADDR_RULE_PRIVACY, | ||
925 | #endif | ||
926 | IPV6_SADDR_RULE_ORCHID, | ||
927 | IPV6_SADDR_RULE_PREFIX, | ||
928 | IPV6_SADDR_RULE_MAX | ||
929 | }; | ||
930 | |||
897 | struct ipv6_saddr_score { | 931 | struct ipv6_saddr_score { |
898 | int addr_type; | 932 | int rule; |
899 | unsigned int attrs; | 933 | int addr_type; |
900 | int matchlen; | 934 | struct inet6_ifaddr *ifa; |
901 | int scope; | 935 | DECLARE_BITMAP(scorebits, IPV6_SADDR_RULE_MAX); |
902 | unsigned int rule; | 936 | int scopedist; |
937 | int matchlen; | ||
903 | }; | 938 | }; |
904 | 939 | ||
905 | #define IPV6_SADDR_SCORE_LOCAL 0x0001 | 940 | struct ipv6_saddr_dst { |
906 | #define IPV6_SADDR_SCORE_PREFERRED 0x0004 | 941 | const struct in6_addr *addr; |
907 | #define IPV6_SADDR_SCORE_HOA 0x0008 | 942 | int ifindex; |
908 | #define IPV6_SADDR_SCORE_OIF 0x0010 | 943 | int scope; |
909 | #define IPV6_SADDR_SCORE_LABEL 0x0020 | 944 | int label; |
910 | #define IPV6_SADDR_SCORE_PRIVACY 0x0040 | 945 | unsigned int prefs; |
946 | }; | ||
911 | 947 | ||
912 | static inline int ipv6_saddr_preferred(int type) | 948 | static inline int ipv6_saddr_preferred(int type) |
913 | { | 949 | { |
@@ -917,27 +953,152 @@ static inline int ipv6_saddr_preferred(int type) | |||
917 | return 0; | 953 | return 0; |
918 | } | 954 | } |
919 | 955 | ||
920 | int ipv6_dev_get_saddr(struct net_device *daddr_dev, | 956 | static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, |
921 | struct in6_addr *daddr, struct in6_addr *saddr) | 957 | struct ipv6_saddr_dst *dst, |
958 | int i) | ||
922 | { | 959 | { |
923 | struct ipv6_saddr_score hiscore; | 960 | int ret; |
924 | struct inet6_ifaddr *ifa_result = NULL; | 961 | |
925 | int daddr_type = __ipv6_addr_type(daddr); | 962 | if (i <= score->rule) { |
926 | int daddr_scope = __ipv6_addr_src_scope(daddr_type); | 963 | switch (i) { |
927 | int daddr_ifindex = daddr_dev ? daddr_dev->ifindex : 0; | 964 | case IPV6_SADDR_RULE_SCOPE: |
928 | u32 daddr_label = ipv6_addr_label(daddr, daddr_type, daddr_ifindex); | 965 | ret = score->scopedist; |
966 | break; | ||
967 | case IPV6_SADDR_RULE_PREFIX: | ||
968 | ret = score->matchlen; | ||
969 | break; | ||
970 | default: | ||
971 | ret = !!test_bit(i, score->scorebits); | ||
972 | } | ||
973 | goto out; | ||
974 | } | ||
975 | |||
976 | switch (i) { | ||
977 | case IPV6_SADDR_RULE_INIT: | ||
978 | /* Rule 0: remember if hiscore is not ready yet */ | ||
979 | ret = !!score->ifa; | ||
980 | break; | ||
981 | case IPV6_SADDR_RULE_LOCAL: | ||
982 | /* Rule 1: Prefer same address */ | ||
983 | ret = ipv6_addr_equal(&score->ifa->addr, dst->addr); | ||
984 | break; | ||
985 | case IPV6_SADDR_RULE_SCOPE: | ||
986 | /* Rule 2: Prefer appropriate scope | ||
987 | * | ||
988 | * ret | ||
989 | * ^ | ||
990 | * -1 | d 15 | ||
991 | * ---+--+-+---> scope | ||
992 | * | | ||
993 | * | d is scope of the destination. | ||
994 | * B-d | \ | ||
995 | * | \ <- smaller scope is better if | ||
996 | * B-15 | \ if scope is enough for destinaion. | ||
997 | * | ret = B - scope (-1 <= scope >= d <= 15). | ||
998 | * d-C-1 | / | ||
999 | * |/ <- greater is better | ||
1000 | * -C / if scope is not enough for destination. | ||
1001 | * /| ret = scope - C (-1 <= d < scope <= 15). | ||
1002 | * | ||
1003 | * d - C - 1 < B -15 (for all -1 <= d <= 15). | ||
1004 | * C > d + 14 - B >= 15 + 14 - B = 29 - B. | ||
1005 | * Assume B = 0 and we get C > 29. | ||
1006 | */ | ||
1007 | ret = __ipv6_addr_src_scope(score->addr_type); | ||
1008 | if (ret >= dst->scope) | ||
1009 | ret = -ret; | ||
1010 | else | ||
1011 | ret -= 128; /* 30 is enough */ | ||
1012 | score->scopedist = ret; | ||
1013 | break; | ||
1014 | case IPV6_SADDR_RULE_PREFERRED: | ||
1015 | /* Rule 3: Avoid deprecated and optimistic addresses */ | ||
1016 | ret = ipv6_saddr_preferred(score->addr_type) || | ||
1017 | !(score->ifa->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)); | ||
1018 | break; | ||
1019 | #ifdef CONFIG_IPV6_MIP6 | ||
1020 | case IPV6_SADDR_RULE_HOA: | ||
1021 | { | ||
1022 | /* Rule 4: Prefer home address */ | ||
1023 | int prefhome = !(dst->prefs & IPV6_PREFER_SRC_COA); | ||
1024 | ret = !(score->ifa->flags & IFA_F_HOMEADDRESS) ^ prefhome; | ||
1025 | break; | ||
1026 | } | ||
1027 | #endif | ||
1028 | case IPV6_SADDR_RULE_OIF: | ||
1029 | /* Rule 5: Prefer outgoing interface */ | ||
1030 | ret = (!dst->ifindex || | ||
1031 | dst->ifindex == score->ifa->idev->dev->ifindex); | ||
1032 | break; | ||
1033 | case IPV6_SADDR_RULE_LABEL: | ||
1034 | /* Rule 6: Prefer matching label */ | ||
1035 | ret = ipv6_addr_label(&score->ifa->addr, score->addr_type, | ||
1036 | score->ifa->idev->dev->ifindex) == dst->label; | ||
1037 | break; | ||
1038 | #ifdef CONFIG_IPV6_PRIVACY | ||
1039 | case IPV6_SADDR_RULE_PRIVACY: | ||
1040 | { | ||
1041 | /* Rule 7: Prefer public address | ||
1042 | * Note: prefer temprary address if use_tempaddr >= 2 | ||
1043 | */ | ||
1044 | int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP) ? | ||
1045 | !!(dst->prefs & IPV6_PREFER_SRC_TMP) : | ||
1046 | score->ifa->idev->cnf.use_tempaddr >= 2; | ||
1047 | ret = (!(score->ifa->flags & IFA_F_TEMPORARY)) ^ preftmp; | ||
1048 | break; | ||
1049 | } | ||
1050 | #endif | ||
1051 | case IPV6_SADDR_RULE_ORCHID: | ||
1052 | /* Rule 8-: Prefer ORCHID vs ORCHID or | ||
1053 | * non-ORCHID vs non-ORCHID | ||
1054 | */ | ||
1055 | ret = !(ipv6_addr_orchid(&score->ifa->addr) ^ | ||
1056 | ipv6_addr_orchid(dst->addr)); | ||
1057 | break; | ||
1058 | case IPV6_SADDR_RULE_PREFIX: | ||
1059 | /* Rule 8: Use longest matching prefix */ | ||
1060 | score->matchlen = ret = ipv6_addr_diff(&score->ifa->addr, | ||
1061 | dst->addr); | ||
1062 | break; | ||
1063 | default: | ||
1064 | ret = 0; | ||
1065 | } | ||
1066 | |||
1067 | if (ret) | ||
1068 | __set_bit(i, score->scorebits); | ||
1069 | score->rule = i; | ||
1070 | out: | ||
1071 | return ret; | ||
1072 | } | ||
1073 | |||
1074 | int ipv6_dev_get_saddr(struct net_device *dst_dev, | ||
1075 | const struct in6_addr *daddr, unsigned int prefs, | ||
1076 | struct in6_addr *saddr) | ||
1077 | { | ||
1078 | struct ipv6_saddr_score scores[2], | ||
1079 | *score = &scores[0], *hiscore = &scores[1]; | ||
1080 | struct net *net = dev_net(dst_dev); | ||
1081 | struct ipv6_saddr_dst dst; | ||
929 | struct net_device *dev; | 1082 | struct net_device *dev; |
1083 | int dst_type; | ||
1084 | |||
1085 | dst_type = __ipv6_addr_type(daddr); | ||
1086 | dst.addr = daddr; | ||
1087 | dst.ifindex = dst_dev ? dst_dev->ifindex : 0; | ||
1088 | dst.scope = __ipv6_addr_src_scope(dst_type); | ||
1089 | dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex); | ||
1090 | dst.prefs = prefs; | ||
930 | 1091 | ||
931 | memset(&hiscore, 0, sizeof(hiscore)); | 1092 | hiscore->rule = -1; |
1093 | hiscore->ifa = NULL; | ||
932 | 1094 | ||
933 | read_lock(&dev_base_lock); | 1095 | read_lock(&dev_base_lock); |
934 | rcu_read_lock(); | 1096 | rcu_read_lock(); |
935 | 1097 | ||
936 | for_each_netdev(&init_net, dev) { | 1098 | for_each_netdev(net, dev) { |
937 | struct inet6_dev *idev; | 1099 | struct inet6_dev *idev; |
938 | struct inet6_ifaddr *ifa; | ||
939 | 1100 | ||
940 | /* Rule 0: Candidate Source Address (section 4) | 1101 | /* Candidate Source Address (section 4) |
941 | * - multicast and link-local destination address, | 1102 | * - multicast and link-local destination address, |
942 | * the set of candidate source address MUST only | 1103 | * the set of candidate source address MUST only |
943 | * include addresses assigned to interfaces | 1104 | * include addresses assigned to interfaces |
@@ -949,9 +1110,9 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
949 | * belonging to the same site as the outgoing | 1110 | * belonging to the same site as the outgoing |
950 | * interface.) | 1111 | * interface.) |
951 | */ | 1112 | */ |
952 | if ((daddr_type & IPV6_ADDR_MULTICAST || | 1113 | if (((dst_type & IPV6_ADDR_MULTICAST) || |
953 | daddr_scope <= IPV6_ADDR_SCOPE_LINKLOCAL) && | 1114 | dst.scope <= IPV6_ADDR_SCOPE_LINKLOCAL) && |
954 | daddr_dev && dev != daddr_dev) | 1115 | dst.ifindex && dev->ifindex != dst.ifindex) |
955 | continue; | 1116 | continue; |
956 | 1117 | ||
957 | idev = __in6_dev_get(dev); | 1118 | idev = __in6_dev_get(dev); |
@@ -959,12 +1120,10 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
959 | continue; | 1120 | continue; |
960 | 1121 | ||
961 | read_lock_bh(&idev->lock); | 1122 | read_lock_bh(&idev->lock); |
962 | for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) { | 1123 | for (score->ifa = idev->addr_list; score->ifa; score->ifa = score->ifa->if_next) { |
963 | struct ipv6_saddr_score score; | 1124 | int i; |
964 | |||
965 | score.addr_type = __ipv6_addr_type(&ifa->addr); | ||
966 | 1125 | ||
967 | /* Rule 0: | 1126 | /* |
968 | * - Tentative Address (RFC2462 section 5.4) | 1127 | * - Tentative Address (RFC2462 section 5.4) |
969 | * - A tentative address is not considered | 1128 | * - A tentative address is not considered |
970 | * "assigned to an interface" in the traditional | 1129 | * "assigned to an interface" in the traditional |
@@ -974,11 +1133,14 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
974 | * addresses, and the unspecified address MUST | 1133 | * addresses, and the unspecified address MUST |
975 | * NOT be included in a candidate set. | 1134 | * NOT be included in a candidate set. |
976 | */ | 1135 | */ |
977 | if ((ifa->flags & IFA_F_TENTATIVE) && | 1136 | if ((score->ifa->flags & IFA_F_TENTATIVE) && |
978 | (!(ifa->flags & IFA_F_OPTIMISTIC))) | 1137 | (!(score->ifa->flags & IFA_F_OPTIMISTIC))) |
979 | continue; | 1138 | continue; |
980 | if (unlikely(score.addr_type == IPV6_ADDR_ANY || | 1139 | |
981 | score.addr_type & IPV6_ADDR_MULTICAST)) { | 1140 | score->addr_type = __ipv6_addr_type(&score->ifa->addr); |
1141 | |||
1142 | if (unlikely(score->addr_type == IPV6_ADDR_ANY || | ||
1143 | score->addr_type & IPV6_ADDR_MULTICAST)) { | ||
982 | LIMIT_NETDEBUG(KERN_DEBUG | 1144 | LIMIT_NETDEBUG(KERN_DEBUG |
983 | "ADDRCONF: unspecified / multicast address " | 1145 | "ADDRCONF: unspecified / multicast address " |
984 | "assigned as unicast address on %s", | 1146 | "assigned as unicast address on %s", |
@@ -986,207 +1148,63 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
986 | continue; | 1148 | continue; |
987 | } | 1149 | } |
988 | 1150 | ||
989 | score.attrs = 0; | 1151 | score->rule = -1; |
990 | score.matchlen = 0; | 1152 | bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX); |
991 | score.scope = 0; | 1153 | |
992 | score.rule = 0; | 1154 | for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) { |
1155 | int minihiscore, miniscore; | ||
1156 | |||
1157 | minihiscore = ipv6_get_saddr_eval(hiscore, &dst, i); | ||
1158 | miniscore = ipv6_get_saddr_eval(score, &dst, i); | ||
1159 | |||
1160 | if (minihiscore > miniscore) { | ||
1161 | if (i == IPV6_SADDR_RULE_SCOPE && | ||
1162 | score->scopedist > 0) { | ||
1163 | /* | ||
1164 | * special case: | ||
1165 | * each remaining entry | ||
1166 | * has too small (not enough) | ||
1167 | * scope, because ifa entries | ||
1168 | * are sorted by their scope | ||
1169 | * values. | ||
1170 | */ | ||
1171 | goto try_nextdev; | ||
1172 | } | ||
1173 | break; | ||
1174 | } else if (minihiscore < miniscore) { | ||
1175 | struct ipv6_saddr_score *tmp; | ||
993 | 1176 | ||
994 | if (ifa_result == NULL) { | 1177 | if (hiscore->ifa) |
995 | /* record it if the first available entry */ | 1178 | in6_ifa_put(hiscore->ifa); |
996 | goto record_it; | ||
997 | } | ||
998 | 1179 | ||
999 | /* Rule 1: Prefer same address */ | 1180 | in6_ifa_hold(score->ifa); |
1000 | if (hiscore.rule < 1) { | ||
1001 | if (ipv6_addr_equal(&ifa_result->addr, daddr)) | ||
1002 | hiscore.attrs |= IPV6_SADDR_SCORE_LOCAL; | ||
1003 | hiscore.rule++; | ||
1004 | } | ||
1005 | if (ipv6_addr_equal(&ifa->addr, daddr)) { | ||
1006 | score.attrs |= IPV6_SADDR_SCORE_LOCAL; | ||
1007 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)) { | ||
1008 | score.rule = 1; | ||
1009 | goto record_it; | ||
1010 | } | ||
1011 | } else { | ||
1012 | if (hiscore.attrs & IPV6_SADDR_SCORE_LOCAL) | ||
1013 | continue; | ||
1014 | } | ||
1015 | 1181 | ||
1016 | /* Rule 2: Prefer appropriate scope */ | 1182 | tmp = hiscore; |
1017 | if (hiscore.rule < 2) { | 1183 | hiscore = score; |
1018 | hiscore.scope = __ipv6_addr_src_scope(hiscore.addr_type); | 1184 | score = tmp; |
1019 | hiscore.rule++; | ||
1020 | } | ||
1021 | score.scope = __ipv6_addr_src_scope(score.addr_type); | ||
1022 | if (hiscore.scope < score.scope) { | ||
1023 | if (hiscore.scope < daddr_scope) { | ||
1024 | score.rule = 2; | ||
1025 | goto record_it; | ||
1026 | } else | ||
1027 | continue; | ||
1028 | } else if (score.scope < hiscore.scope) { | ||
1029 | if (score.scope < daddr_scope) | ||
1030 | break; /* addresses sorted by scope */ | ||
1031 | else { | ||
1032 | score.rule = 2; | ||
1033 | goto record_it; | ||
1034 | } | ||
1035 | } | ||
1036 | 1185 | ||
1037 | /* Rule 3: Avoid deprecated and optimistic addresses */ | 1186 | /* restore our iterator */ |
1038 | if (hiscore.rule < 3) { | 1187 | score->ifa = hiscore->ifa; |
1039 | if (ipv6_saddr_preferred(hiscore.addr_type) || | ||
1040 | (((ifa_result->flags & | ||
1041 | (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0))) | ||
1042 | hiscore.attrs |= IPV6_SADDR_SCORE_PREFERRED; | ||
1043 | hiscore.rule++; | ||
1044 | } | ||
1045 | if (ipv6_saddr_preferred(score.addr_type) || | ||
1046 | (((ifa->flags & | ||
1047 | (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0))) { | ||
1048 | score.attrs |= IPV6_SADDR_SCORE_PREFERRED; | ||
1049 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) { | ||
1050 | score.rule = 3; | ||
1051 | goto record_it; | ||
1052 | } | ||
1053 | } else { | ||
1054 | if (hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED) | ||
1055 | continue; | ||
1056 | } | ||
1057 | 1188 | ||
1058 | /* Rule 4: Prefer home address */ | 1189 | break; |
1059 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | ||
1060 | if (hiscore.rule < 4) { | ||
1061 | if (ifa_result->flags & IFA_F_HOMEADDRESS) | ||
1062 | hiscore.attrs |= IPV6_SADDR_SCORE_HOA; | ||
1063 | hiscore.rule++; | ||
1064 | } | ||
1065 | if (ifa->flags & IFA_F_HOMEADDRESS) { | ||
1066 | score.attrs |= IPV6_SADDR_SCORE_HOA; | ||
1067 | if (!(ifa_result->flags & IFA_F_HOMEADDRESS)) { | ||
1068 | score.rule = 4; | ||
1069 | goto record_it; | ||
1070 | } | ||
1071 | } else { | ||
1072 | if (hiscore.attrs & IPV6_SADDR_SCORE_HOA) | ||
1073 | continue; | ||
1074 | } | ||
1075 | #else | ||
1076 | if (hiscore.rule < 4) | ||
1077 | hiscore.rule++; | ||
1078 | #endif | ||
1079 | |||
1080 | /* Rule 5: Prefer outgoing interface */ | ||
1081 | if (hiscore.rule < 5) { | ||
1082 | if (daddr_dev == NULL || | ||
1083 | daddr_dev == ifa_result->idev->dev) | ||
1084 | hiscore.attrs |= IPV6_SADDR_SCORE_OIF; | ||
1085 | hiscore.rule++; | ||
1086 | } | ||
1087 | if (daddr_dev == NULL || | ||
1088 | daddr_dev == ifa->idev->dev) { | ||
1089 | score.attrs |= IPV6_SADDR_SCORE_OIF; | ||
1090 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_OIF)) { | ||
1091 | score.rule = 5; | ||
1092 | goto record_it; | ||
1093 | } | ||
1094 | } else { | ||
1095 | if (hiscore.attrs & IPV6_SADDR_SCORE_OIF) | ||
1096 | continue; | ||
1097 | } | ||
1098 | |||
1099 | /* Rule 6: Prefer matching label */ | ||
1100 | if (hiscore.rule < 6) { | ||
1101 | if (ipv6_addr_label(&ifa_result->addr, | ||
1102 | hiscore.addr_type, | ||
1103 | ifa_result->idev->dev->ifindex) == daddr_label) | ||
1104 | hiscore.attrs |= IPV6_SADDR_SCORE_LABEL; | ||
1105 | hiscore.rule++; | ||
1106 | } | ||
1107 | if (ipv6_addr_label(&ifa->addr, | ||
1108 | score.addr_type, | ||
1109 | ifa->idev->dev->ifindex) == daddr_label) { | ||
1110 | score.attrs |= IPV6_SADDR_SCORE_LABEL; | ||
1111 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_LABEL)) { | ||
1112 | score.rule = 6; | ||
1113 | goto record_it; | ||
1114 | } | ||
1115 | } else { | ||
1116 | if (hiscore.attrs & IPV6_SADDR_SCORE_LABEL) | ||
1117 | continue; | ||
1118 | } | ||
1119 | |||
1120 | #ifdef CONFIG_IPV6_PRIVACY | ||
1121 | /* Rule 7: Prefer public address | ||
1122 | * Note: prefer temprary address if use_tempaddr >= 2 | ||
1123 | */ | ||
1124 | if (hiscore.rule < 7) { | ||
1125 | if ((!(ifa_result->flags & IFA_F_TEMPORARY)) ^ | ||
1126 | (ifa_result->idev->cnf.use_tempaddr >= 2)) | ||
1127 | hiscore.attrs |= IPV6_SADDR_SCORE_PRIVACY; | ||
1128 | hiscore.rule++; | ||
1129 | } | ||
1130 | if ((!(ifa->flags & IFA_F_TEMPORARY)) ^ | ||
1131 | (ifa->idev->cnf.use_tempaddr >= 2)) { | ||
1132 | score.attrs |= IPV6_SADDR_SCORE_PRIVACY; | ||
1133 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)) { | ||
1134 | score.rule = 7; | ||
1135 | goto record_it; | ||
1136 | } | 1190 | } |
1137 | } else { | ||
1138 | if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY) | ||
1139 | continue; | ||
1140 | } | 1191 | } |
1141 | #else | ||
1142 | if (hiscore.rule < 7) | ||
1143 | hiscore.rule++; | ||
1144 | #endif | ||
1145 | /* Rule 8: Use longest matching prefix */ | ||
1146 | if (hiscore.rule < 8) { | ||
1147 | hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr); | ||
1148 | hiscore.rule++; | ||
1149 | } | ||
1150 | score.matchlen = ipv6_addr_diff(&ifa->addr, daddr); | ||
1151 | if (score.matchlen > hiscore.matchlen) { | ||
1152 | score.rule = 8; | ||
1153 | goto record_it; | ||
1154 | } | ||
1155 | #if 0 | ||
1156 | else if (score.matchlen < hiscore.matchlen) | ||
1157 | continue; | ||
1158 | #endif | ||
1159 | |||
1160 | /* Final Rule: choose first available one */ | ||
1161 | continue; | ||
1162 | record_it: | ||
1163 | if (ifa_result) | ||
1164 | in6_ifa_put(ifa_result); | ||
1165 | in6_ifa_hold(ifa); | ||
1166 | ifa_result = ifa; | ||
1167 | hiscore = score; | ||
1168 | } | 1192 | } |
1193 | try_nextdev: | ||
1169 | read_unlock_bh(&idev->lock); | 1194 | read_unlock_bh(&idev->lock); |
1170 | } | 1195 | } |
1171 | rcu_read_unlock(); | 1196 | rcu_read_unlock(); |
1172 | read_unlock(&dev_base_lock); | 1197 | read_unlock(&dev_base_lock); |
1173 | 1198 | ||
1174 | if (!ifa_result) | 1199 | if (!hiscore->ifa) |
1175 | return -EADDRNOTAVAIL; | 1200 | return -EADDRNOTAVAIL; |
1176 | 1201 | ||
1177 | ipv6_addr_copy(saddr, &ifa_result->addr); | 1202 | ipv6_addr_copy(saddr, &hiscore->ifa->addr); |
1178 | in6_ifa_put(ifa_result); | 1203 | in6_ifa_put(hiscore->ifa); |
1179 | return 0; | 1204 | return 0; |
1180 | } | 1205 | } |
1181 | 1206 | ||
1182 | 1207 | EXPORT_SYMBOL(ipv6_dev_get_saddr); | |
1183 | int ipv6_get_saddr(struct dst_entry *dst, | ||
1184 | struct in6_addr *daddr, struct in6_addr *saddr) | ||
1185 | { | ||
1186 | return ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, daddr, saddr); | ||
1187 | } | ||
1188 | |||
1189 | EXPORT_SYMBOL(ipv6_get_saddr); | ||
1190 | 1208 | ||
1191 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, | 1209 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, |
1192 | unsigned char banned_flags) | 1210 | unsigned char banned_flags) |
@@ -1232,7 +1250,7 @@ int ipv6_chk_addr(struct net *net, struct in6_addr *addr, | |||
1232 | 1250 | ||
1233 | read_lock_bh(&addrconf_hash_lock); | 1251 | read_lock_bh(&addrconf_hash_lock); |
1234 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1252 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { |
1235 | if (ifp->idev->dev->nd_net != net) | 1253 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1236 | continue; | 1254 | continue; |
1237 | if (ipv6_addr_equal(&ifp->addr, addr) && | 1255 | if (ipv6_addr_equal(&ifp->addr, addr) && |
1238 | !(ifp->flags&IFA_F_TENTATIVE)) { | 1256 | !(ifp->flags&IFA_F_TENTATIVE)) { |
@@ -1254,7 +1272,7 @@ int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, | |||
1254 | u8 hash = ipv6_addr_hash(addr); | 1272 | u8 hash = ipv6_addr_hash(addr); |
1255 | 1273 | ||
1256 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1274 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { |
1257 | if (ifp->idev->dev->nd_net != net) | 1275 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1258 | continue; | 1276 | continue; |
1259 | if (ipv6_addr_equal(&ifp->addr, addr)) { | 1277 | if (ipv6_addr_equal(&ifp->addr, addr)) { |
1260 | if (dev == NULL || ifp->idev->dev == dev) | 1278 | if (dev == NULL || ifp->idev->dev == dev) |
@@ -1264,7 +1282,32 @@ int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, | |||
1264 | return ifp != NULL; | 1282 | return ifp != NULL; |
1265 | } | 1283 | } |
1266 | 1284 | ||
1267 | struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr, | 1285 | int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev) |
1286 | { | ||
1287 | struct inet6_dev *idev; | ||
1288 | struct inet6_ifaddr *ifa; | ||
1289 | int onlink; | ||
1290 | |||
1291 | onlink = 0; | ||
1292 | rcu_read_lock(); | ||
1293 | idev = __in6_dev_get(dev); | ||
1294 | if (idev) { | ||
1295 | read_lock_bh(&idev->lock); | ||
1296 | for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) { | ||
1297 | onlink = ipv6_prefix_equal(addr, &ifa->addr, | ||
1298 | ifa->prefix_len); | ||
1299 | if (onlink) | ||
1300 | break; | ||
1301 | } | ||
1302 | read_unlock_bh(&idev->lock); | ||
1303 | } | ||
1304 | rcu_read_unlock(); | ||
1305 | return onlink; | ||
1306 | } | ||
1307 | |||
1308 | EXPORT_SYMBOL(ipv6_chk_prefix); | ||
1309 | |||
1310 | struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr, | ||
1268 | struct net_device *dev, int strict) | 1311 | struct net_device *dev, int strict) |
1269 | { | 1312 | { |
1270 | struct inet6_ifaddr * ifp; | 1313 | struct inet6_ifaddr * ifp; |
@@ -1272,7 +1315,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr, | |||
1272 | 1315 | ||
1273 | read_lock_bh(&addrconf_hash_lock); | 1316 | read_lock_bh(&addrconf_hash_lock); |
1274 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1317 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { |
1275 | if (ifp->idev->dev->nd_net != net) | 1318 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1276 | continue; | 1319 | continue; |
1277 | if (ipv6_addr_equal(&ifp->addr, addr)) { | 1320 | if (ipv6_addr_equal(&ifp->addr, addr)) { |
1278 | if (dev == NULL || ifp->idev->dev == dev || | 1321 | if (dev == NULL || ifp->idev->dev == dev || |
@@ -1449,6 +1492,29 @@ static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev) | |||
1449 | return 0; | 1492 | return 0; |
1450 | } | 1493 | } |
1451 | 1494 | ||
1495 | int __ipv6_isatap_ifid(u8 *eui, __be32 addr) | ||
1496 | { | ||
1497 | eui[0] = (ipv4_is_zeronet(addr) || ipv4_is_private_10(addr) || | ||
1498 | ipv4_is_loopback(addr) || ipv4_is_linklocal_169(addr) || | ||
1499 | ipv4_is_private_172(addr) || ipv4_is_test_192(addr) || | ||
1500 | ipv4_is_anycast_6to4(addr) || ipv4_is_private_192(addr) || | ||
1501 | ipv4_is_test_198(addr) || ipv4_is_multicast(addr) || | ||
1502 | ipv4_is_lbcast(addr)) ? 0x00 : 0x02; | ||
1503 | eui[1] = 0; | ||
1504 | eui[2] = 0x5E; | ||
1505 | eui[3] = 0xFE; | ||
1506 | memcpy(eui + 4, &addr, 4); | ||
1507 | return 0; | ||
1508 | } | ||
1509 | EXPORT_SYMBOL(__ipv6_isatap_ifid); | ||
1510 | |||
1511 | static int addrconf_ifid_sit(u8 *eui, struct net_device *dev) | ||
1512 | { | ||
1513 | if (dev->priv_flags & IFF_ISATAP) | ||
1514 | return __ipv6_isatap_ifid(eui, *(__be32 *)dev->dev_addr); | ||
1515 | return -1; | ||
1516 | } | ||
1517 | |||
1452 | static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) | 1518 | static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) |
1453 | { | 1519 | { |
1454 | switch (dev->type) { | 1520 | switch (dev->type) { |
@@ -1461,8 +1527,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) | |||
1461 | case ARPHRD_INFINIBAND: | 1527 | case ARPHRD_INFINIBAND: |
1462 | return addrconf_ifid_infiniband(eui, dev); | 1528 | return addrconf_ifid_infiniband(eui, dev); |
1463 | case ARPHRD_SIT: | 1529 | case ARPHRD_SIT: |
1464 | if (dev->priv_flags & IFF_ISATAP) | 1530 | return addrconf_ifid_sit(eui, dev); |
1465 | return ipv6_isatap_eui64(eui, *(__be32 *)dev->dev_addr); | ||
1466 | } | 1531 | } |
1467 | return -1; | 1532 | return -1; |
1468 | } | 1533 | } |
@@ -1574,7 +1639,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
1574 | .fc_expires = expires, | 1639 | .fc_expires = expires, |
1575 | .fc_dst_len = plen, | 1640 | .fc_dst_len = plen, |
1576 | .fc_flags = RTF_UP | flags, | 1641 | .fc_flags = RTF_UP | flags, |
1577 | .fc_nlinfo.nl_net = &init_net, | 1642 | .fc_nlinfo.nl_net = dev_net(dev), |
1578 | }; | 1643 | }; |
1579 | 1644 | ||
1580 | ipv6_addr_copy(&cfg.fc_dst, pfx); | 1645 | ipv6_addr_copy(&cfg.fc_dst, pfx); |
@@ -1601,7 +1666,7 @@ static void addrconf_add_mroute(struct net_device *dev) | |||
1601 | .fc_ifindex = dev->ifindex, | 1666 | .fc_ifindex = dev->ifindex, |
1602 | .fc_dst_len = 8, | 1667 | .fc_dst_len = 8, |
1603 | .fc_flags = RTF_UP, | 1668 | .fc_flags = RTF_UP, |
1604 | .fc_nlinfo.nl_net = &init_net, | 1669 | .fc_nlinfo.nl_net = dev_net(dev), |
1605 | }; | 1670 | }; |
1606 | 1671 | ||
1607 | ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); | 1672 | ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); |
@@ -1618,7 +1683,7 @@ static void sit_route_add(struct net_device *dev) | |||
1618 | .fc_ifindex = dev->ifindex, | 1683 | .fc_ifindex = dev->ifindex, |
1619 | .fc_dst_len = 96, | 1684 | .fc_dst_len = 96, |
1620 | .fc_flags = RTF_UP | RTF_NONEXTHOP, | 1685 | .fc_flags = RTF_UP | RTF_NONEXTHOP, |
1621 | .fc_nlinfo.nl_net = &init_net, | 1686 | .fc_nlinfo.nl_net = dev_net(dev), |
1622 | }; | 1687 | }; |
1623 | 1688 | ||
1624 | /* prefix length - 96 bits "::d.d.d.d" */ | 1689 | /* prefix length - 96 bits "::d.d.d.d" */ |
@@ -1719,7 +1784,8 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1719 | 1784 | ||
1720 | if (pinfo->onlink) { | 1785 | if (pinfo->onlink) { |
1721 | struct rt6_info *rt; | 1786 | struct rt6_info *rt; |
1722 | rt = rt6_lookup(&pinfo->prefix, NULL, dev->ifindex, 1); | 1787 | rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, |
1788 | dev->ifindex, 1); | ||
1723 | 1789 | ||
1724 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { | 1790 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { |
1725 | if (rt->rt6i_flags&RTF_EXPIRES) { | 1791 | if (rt->rt6i_flags&RTF_EXPIRES) { |
@@ -1762,7 +1828,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1762 | 1828 | ||
1763 | ok: | 1829 | ok: |
1764 | 1830 | ||
1765 | ifp = ipv6_get_ifaddr(&init_net, &addr, dev, 1); | 1831 | ifp = ipv6_get_ifaddr(dev_net(dev), &addr, dev, 1); |
1766 | 1832 | ||
1767 | if (ifp == NULL && valid_lft) { | 1833 | if (ifp == NULL && valid_lft) { |
1768 | int max_addresses = in6_dev->cnf.max_addresses; | 1834 | int max_addresses = in6_dev->cnf.max_addresses; |
@@ -1888,7 +1954,7 @@ ok: | |||
1888 | * Special case for SIT interfaces where we create a new "virtual" | 1954 | * Special case for SIT interfaces where we create a new "virtual" |
1889 | * device. | 1955 | * device. |
1890 | */ | 1956 | */ |
1891 | int addrconf_set_dstaddr(void __user *arg) | 1957 | int addrconf_set_dstaddr(struct net *net, void __user *arg) |
1892 | { | 1958 | { |
1893 | struct in6_ifreq ireq; | 1959 | struct in6_ifreq ireq; |
1894 | struct net_device *dev; | 1960 | struct net_device *dev; |
@@ -1900,7 +1966,7 @@ int addrconf_set_dstaddr(void __user *arg) | |||
1900 | if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) | 1966 | if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) |
1901 | goto err_exit; | 1967 | goto err_exit; |
1902 | 1968 | ||
1903 | dev = __dev_get_by_index(&init_net, ireq.ifr6_ifindex); | 1969 | dev = __dev_get_by_index(net, ireq.ifr6_ifindex); |
1904 | 1970 | ||
1905 | err = -ENODEV; | 1971 | err = -ENODEV; |
1906 | if (dev == NULL) | 1972 | if (dev == NULL) |
@@ -1931,7 +1997,8 @@ int addrconf_set_dstaddr(void __user *arg) | |||
1931 | 1997 | ||
1932 | if (err == 0) { | 1998 | if (err == 0) { |
1933 | err = -ENOBUFS; | 1999 | err = -ENOBUFS; |
1934 | if ((dev = __dev_get_by_name(&init_net, p.name)) == NULL) | 2000 | dev = __dev_get_by_name(net, p.name); |
2001 | if (!dev) | ||
1935 | goto err_exit; | 2002 | goto err_exit; |
1936 | err = dev_open(dev); | 2003 | err = dev_open(dev); |
1937 | } | 2004 | } |
@@ -1946,8 +2013,9 @@ err_exit: | |||
1946 | /* | 2013 | /* |
1947 | * Manual configuration of address on an interface | 2014 | * Manual configuration of address on an interface |
1948 | */ | 2015 | */ |
1949 | static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | 2016 | static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, |
1950 | __u8 ifa_flags, __u32 prefered_lft, __u32 valid_lft) | 2017 | int plen, __u8 ifa_flags, __u32 prefered_lft, |
2018 | __u32 valid_lft) | ||
1951 | { | 2019 | { |
1952 | struct inet6_ifaddr *ifp; | 2020 | struct inet6_ifaddr *ifp; |
1953 | struct inet6_dev *idev; | 2021 | struct inet6_dev *idev; |
@@ -1961,7 +2029,8 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | |||
1961 | if (!valid_lft || prefered_lft > valid_lft) | 2029 | if (!valid_lft || prefered_lft > valid_lft) |
1962 | return -EINVAL; | 2030 | return -EINVAL; |
1963 | 2031 | ||
1964 | if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL) | 2032 | dev = __dev_get_by_index(net, ifindex); |
2033 | if (!dev) | ||
1965 | return -ENODEV; | 2034 | return -ENODEV; |
1966 | 2035 | ||
1967 | if ((idev = addrconf_add_dev(dev)) == NULL) | 2036 | if ((idev = addrconf_add_dev(dev)) == NULL) |
@@ -2006,13 +2075,15 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | |||
2006 | return PTR_ERR(ifp); | 2075 | return PTR_ERR(ifp); |
2007 | } | 2076 | } |
2008 | 2077 | ||
2009 | static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) | 2078 | static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, |
2079 | int plen) | ||
2010 | { | 2080 | { |
2011 | struct inet6_ifaddr *ifp; | 2081 | struct inet6_ifaddr *ifp; |
2012 | struct inet6_dev *idev; | 2082 | struct inet6_dev *idev; |
2013 | struct net_device *dev; | 2083 | struct net_device *dev; |
2014 | 2084 | ||
2015 | if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL) | 2085 | dev = __dev_get_by_index(net, ifindex); |
2086 | if (!dev) | ||
2016 | return -ENODEV; | 2087 | return -ENODEV; |
2017 | 2088 | ||
2018 | if ((idev = __in6_dev_get(dev)) == NULL) | 2089 | if ((idev = __in6_dev_get(dev)) == NULL) |
@@ -2040,7 +2111,7 @@ static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) | |||
2040 | } | 2111 | } |
2041 | 2112 | ||
2042 | 2113 | ||
2043 | int addrconf_add_ifaddr(void __user *arg) | 2114 | int addrconf_add_ifaddr(struct net *net, void __user *arg) |
2044 | { | 2115 | { |
2045 | struct in6_ifreq ireq; | 2116 | struct in6_ifreq ireq; |
2046 | int err; | 2117 | int err; |
@@ -2052,13 +2123,14 @@ int addrconf_add_ifaddr(void __user *arg) | |||
2052 | return -EFAULT; | 2123 | return -EFAULT; |
2053 | 2124 | ||
2054 | rtnl_lock(); | 2125 | rtnl_lock(); |
2055 | err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen, | 2126 | err = inet6_addr_add(net, ireq.ifr6_ifindex, &ireq.ifr6_addr, |
2056 | IFA_F_PERMANENT, INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); | 2127 | ireq.ifr6_prefixlen, IFA_F_PERMANENT, |
2128 | INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); | ||
2057 | rtnl_unlock(); | 2129 | rtnl_unlock(); |
2058 | return err; | 2130 | return err; |
2059 | } | 2131 | } |
2060 | 2132 | ||
2061 | int addrconf_del_ifaddr(void __user *arg) | 2133 | int addrconf_del_ifaddr(struct net *net, void __user *arg) |
2062 | { | 2134 | { |
2063 | struct in6_ifreq ireq; | 2135 | struct in6_ifreq ireq; |
2064 | int err; | 2136 | int err; |
@@ -2070,7 +2142,8 @@ int addrconf_del_ifaddr(void __user *arg) | |||
2070 | return -EFAULT; | 2142 | return -EFAULT; |
2071 | 2143 | ||
2072 | rtnl_lock(); | 2144 | rtnl_lock(); |
2073 | err = inet6_addr_del(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen); | 2145 | err = inet6_addr_del(net, ireq.ifr6_ifindex, &ireq.ifr6_addr, |
2146 | ireq.ifr6_prefixlen); | ||
2074 | rtnl_unlock(); | 2147 | rtnl_unlock(); |
2075 | return err; | 2148 | return err; |
2076 | } | 2149 | } |
@@ -2081,6 +2154,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2081 | struct inet6_ifaddr * ifp; | 2154 | struct inet6_ifaddr * ifp; |
2082 | struct in6_addr addr; | 2155 | struct in6_addr addr; |
2083 | struct net_device *dev; | 2156 | struct net_device *dev; |
2157 | struct net *net = dev_net(idev->dev); | ||
2084 | int scope; | 2158 | int scope; |
2085 | 2159 | ||
2086 | ASSERT_RTNL(); | 2160 | ASSERT_RTNL(); |
@@ -2107,7 +2181,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2107 | return; | 2181 | return; |
2108 | } | 2182 | } |
2109 | 2183 | ||
2110 | for_each_netdev(&init_net, dev) { | 2184 | for_each_netdev(net, dev) { |
2111 | struct in_device * in_dev = __in_dev_get_rtnl(dev); | 2185 | struct in_device * in_dev = __in_dev_get_rtnl(dev); |
2112 | if (in_dev && (dev->flags & IFF_UP)) { | 2186 | if (in_dev && (dev->flags & IFF_UP)) { |
2113 | struct in_ifaddr * ifa; | 2187 | struct in_ifaddr * ifa; |
@@ -2270,15 +2344,16 @@ ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) | |||
2270 | static void ip6_tnl_add_linklocal(struct inet6_dev *idev) | 2344 | static void ip6_tnl_add_linklocal(struct inet6_dev *idev) |
2271 | { | 2345 | { |
2272 | struct net_device *link_dev; | 2346 | struct net_device *link_dev; |
2347 | struct net *net = dev_net(idev->dev); | ||
2273 | 2348 | ||
2274 | /* first try to inherit the link-local address from the link device */ | 2349 | /* first try to inherit the link-local address from the link device */ |
2275 | if (idev->dev->iflink && | 2350 | if (idev->dev->iflink && |
2276 | (link_dev = __dev_get_by_index(&init_net, idev->dev->iflink))) { | 2351 | (link_dev = __dev_get_by_index(net, idev->dev->iflink))) { |
2277 | if (!ipv6_inherit_linklocal(idev, link_dev)) | 2352 | if (!ipv6_inherit_linklocal(idev, link_dev)) |
2278 | return; | 2353 | return; |
2279 | } | 2354 | } |
2280 | /* then try to inherit it from any device */ | 2355 | /* then try to inherit it from any device */ |
2281 | for_each_netdev(&init_net, link_dev) { | 2356 | for_each_netdev(net, link_dev) { |
2282 | if (!ipv6_inherit_linklocal(idev, link_dev)) | 2357 | if (!ipv6_inherit_linklocal(idev, link_dev)) |
2283 | return; | 2358 | return; |
2284 | } | 2359 | } |
@@ -2311,9 +2386,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2311 | int run_pending = 0; | 2386 | int run_pending = 0; |
2312 | int err; | 2387 | int err; |
2313 | 2388 | ||
2314 | if (dev->nd_net != &init_net) | ||
2315 | return NOTIFY_DONE; | ||
2316 | |||
2317 | switch(event) { | 2389 | switch(event) { |
2318 | case NETDEV_REGISTER: | 2390 | case NETDEV_REGISTER: |
2319 | if (!idev && dev->mtu >= IPV6_MIN_MTU) { | 2391 | if (!idev && dev->mtu >= IPV6_MIN_MTU) { |
@@ -2453,6 +2525,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2453 | { | 2525 | { |
2454 | struct inet6_dev *idev; | 2526 | struct inet6_dev *idev; |
2455 | struct inet6_ifaddr *ifa, **bifa; | 2527 | struct inet6_ifaddr *ifa, **bifa; |
2528 | struct net *net = dev_net(dev); | ||
2456 | int i; | 2529 | int i; |
2457 | 2530 | ||
2458 | ASSERT_RTNL(); | 2531 | ASSERT_RTNL(); |
@@ -2460,7 +2533,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2460 | if ((dev->flags & IFF_LOOPBACK) && how == 1) | 2533 | if ((dev->flags & IFF_LOOPBACK) && how == 1) |
2461 | how = 0; | 2534 | how = 0; |
2462 | 2535 | ||
2463 | rt6_ifdown(dev); | 2536 | rt6_ifdown(net, dev); |
2464 | neigh_ifdown(&nd_tbl, dev); | 2537 | neigh_ifdown(&nd_tbl, dev); |
2465 | 2538 | ||
2466 | idev = __in6_dev_get(dev); | 2539 | idev = __in6_dev_get(dev); |
@@ -2579,8 +2652,6 @@ static void addrconf_rs_timer(unsigned long data) | |||
2579 | 2652 | ||
2580 | spin_lock(&ifp->lock); | 2653 | spin_lock(&ifp->lock); |
2581 | if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) { | 2654 | if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) { |
2582 | struct in6_addr all_routers; | ||
2583 | |||
2584 | /* The wait after the last probe can be shorter */ | 2655 | /* The wait after the last probe can be shorter */ |
2585 | addrconf_mod_timer(ifp, AC_RS, | 2656 | addrconf_mod_timer(ifp, AC_RS, |
2586 | (ifp->probes == ifp->idev->cnf.rtr_solicits) ? | 2657 | (ifp->probes == ifp->idev->cnf.rtr_solicits) ? |
@@ -2588,9 +2659,7 @@ static void addrconf_rs_timer(unsigned long data) | |||
2588 | ifp->idev->cnf.rtr_solicit_interval); | 2659 | ifp->idev->cnf.rtr_solicit_interval); |
2589 | spin_unlock(&ifp->lock); | 2660 | spin_unlock(&ifp->lock); |
2590 | 2661 | ||
2591 | ipv6_addr_all_routers(&all_routers); | 2662 | ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters); |
2592 | |||
2593 | ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers); | ||
2594 | } else { | 2663 | } else { |
2595 | spin_unlock(&ifp->lock); | 2664 | spin_unlock(&ifp->lock); |
2596 | /* | 2665 | /* |
@@ -2677,7 +2746,6 @@ static void addrconf_dad_timer(unsigned long data) | |||
2677 | { | 2746 | { |
2678 | struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; | 2747 | struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; |
2679 | struct inet6_dev *idev = ifp->idev; | 2748 | struct inet6_dev *idev = ifp->idev; |
2680 | struct in6_addr unspec; | ||
2681 | struct in6_addr mcaddr; | 2749 | struct in6_addr mcaddr; |
2682 | 2750 | ||
2683 | read_lock_bh(&idev->lock); | 2751 | read_lock_bh(&idev->lock); |
@@ -2706,9 +2774,8 @@ static void addrconf_dad_timer(unsigned long data) | |||
2706 | read_unlock_bh(&idev->lock); | 2774 | read_unlock_bh(&idev->lock); |
2707 | 2775 | ||
2708 | /* send a neighbour solicitation for our addr */ | 2776 | /* send a neighbour solicitation for our addr */ |
2709 | memset(&unspec, 0, sizeof(unspec)); | ||
2710 | addrconf_addr_solict_mult(&ifp->addr, &mcaddr); | 2777 | addrconf_addr_solict_mult(&ifp->addr, &mcaddr); |
2711 | ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &unspec); | 2778 | ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any); |
2712 | out: | 2779 | out: |
2713 | in6_ifa_put(ifp); | 2780 | in6_ifa_put(ifp); |
2714 | } | 2781 | } |
@@ -2731,16 +2798,12 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) | |||
2731 | ifp->idev->cnf.rtr_solicits > 0 && | 2798 | ifp->idev->cnf.rtr_solicits > 0 && |
2732 | (dev->flags&IFF_LOOPBACK) == 0 && | 2799 | (dev->flags&IFF_LOOPBACK) == 0 && |
2733 | (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { | 2800 | (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { |
2734 | struct in6_addr all_routers; | ||
2735 | |||
2736 | ipv6_addr_all_routers(&all_routers); | ||
2737 | |||
2738 | /* | 2801 | /* |
2739 | * If a host as already performed a random delay | 2802 | * If a host as already performed a random delay |
2740 | * [...] as part of DAD [...] there is no need | 2803 | * [...] as part of DAD [...] there is no need |
2741 | * to delay again before sending the first RS | 2804 | * to delay again before sending the first RS |
2742 | */ | 2805 | */ |
2743 | ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers); | 2806 | ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters); |
2744 | 2807 | ||
2745 | spin_lock_bh(&ifp->lock); | 2808 | spin_lock_bh(&ifp->lock); |
2746 | ifp->probes = 1; | 2809 | ifp->probes = 1; |
@@ -2776,12 +2839,12 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq) | |||
2776 | { | 2839 | { |
2777 | struct inet6_ifaddr *ifa = NULL; | 2840 | struct inet6_ifaddr *ifa = NULL; |
2778 | struct if6_iter_state *state = seq->private; | 2841 | struct if6_iter_state *state = seq->private; |
2779 | struct net *net = state->p.net; | 2842 | struct net *net = seq_file_net(seq); |
2780 | 2843 | ||
2781 | for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { | 2844 | for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { |
2782 | ifa = inet6_addr_lst[state->bucket]; | 2845 | ifa = inet6_addr_lst[state->bucket]; |
2783 | 2846 | ||
2784 | while (ifa && ifa->idev->dev->nd_net != net) | 2847 | while (ifa && !net_eq(dev_net(ifa->idev->dev), net)) |
2785 | ifa = ifa->lst_next; | 2848 | ifa = ifa->lst_next; |
2786 | if (ifa) | 2849 | if (ifa) |
2787 | break; | 2850 | break; |
@@ -2792,12 +2855,12 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq) | |||
2792 | static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa) | 2855 | static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa) |
2793 | { | 2856 | { |
2794 | struct if6_iter_state *state = seq->private; | 2857 | struct if6_iter_state *state = seq->private; |
2795 | struct net *net = state->p.net; | 2858 | struct net *net = seq_file_net(seq); |
2796 | 2859 | ||
2797 | ifa = ifa->lst_next; | 2860 | ifa = ifa->lst_next; |
2798 | try_again: | 2861 | try_again: |
2799 | if (ifa) { | 2862 | if (ifa) { |
2800 | if (ifa->idev->dev->nd_net != net) { | 2863 | if (!net_eq(dev_net(ifa->idev->dev), net)) { |
2801 | ifa = ifa->lst_next; | 2864 | ifa = ifa->lst_next; |
2802 | goto try_again; | 2865 | goto try_again; |
2803 | } | 2866 | } |
@@ -2915,9 +2978,9 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) | |||
2915 | u8 hash = ipv6_addr_hash(addr); | 2978 | u8 hash = ipv6_addr_hash(addr); |
2916 | read_lock_bh(&addrconf_hash_lock); | 2979 | read_lock_bh(&addrconf_hash_lock); |
2917 | for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) { | 2980 | for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) { |
2918 | if (ifp->idev->dev->nd_net != net) | 2981 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
2919 | continue; | 2982 | continue; |
2920 | if (ipv6_addr_cmp(&ifp->addr, addr) == 0 && | 2983 | if (ipv6_addr_equal(&ifp->addr, addr) && |
2921 | (ifp->flags & IFA_F_HOMEADDRESS)) { | 2984 | (ifp->flags & IFA_F_HOMEADDRESS)) { |
2922 | ret = 1; | 2985 | ret = 1; |
2923 | break; | 2986 | break; |
@@ -3064,15 +3127,12 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { | |||
3064 | static int | 3127 | static int |
3065 | inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 3128 | inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
3066 | { | 3129 | { |
3067 | struct net *net = skb->sk->sk_net; | 3130 | struct net *net = sock_net(skb->sk); |
3068 | struct ifaddrmsg *ifm; | 3131 | struct ifaddrmsg *ifm; |
3069 | struct nlattr *tb[IFA_MAX+1]; | 3132 | struct nlattr *tb[IFA_MAX+1]; |
3070 | struct in6_addr *pfx; | 3133 | struct in6_addr *pfx; |
3071 | int err; | 3134 | int err; |
3072 | 3135 | ||
3073 | if (net != &init_net) | ||
3074 | return -EINVAL; | ||
3075 | |||
3076 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3136 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3077 | if (err < 0) | 3137 | if (err < 0) |
3078 | return err; | 3138 | return err; |
@@ -3082,7 +3142,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3082 | if (pfx == NULL) | 3142 | if (pfx == NULL) |
3083 | return -EINVAL; | 3143 | return -EINVAL; |
3084 | 3144 | ||
3085 | return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen); | 3145 | return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); |
3086 | } | 3146 | } |
3087 | 3147 | ||
3088 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | 3148 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, |
@@ -3125,7 +3185,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | |||
3125 | static int | 3185 | static int |
3126 | inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 3186 | inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
3127 | { | 3187 | { |
3128 | struct net *net = skb->sk->sk_net; | 3188 | struct net *net = sock_net(skb->sk); |
3129 | struct ifaddrmsg *ifm; | 3189 | struct ifaddrmsg *ifm; |
3130 | struct nlattr *tb[IFA_MAX+1]; | 3190 | struct nlattr *tb[IFA_MAX+1]; |
3131 | struct in6_addr *pfx; | 3191 | struct in6_addr *pfx; |
@@ -3135,9 +3195,6 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3135 | u8 ifa_flags; | 3195 | u8 ifa_flags; |
3136 | int err; | 3196 | int err; |
3137 | 3197 | ||
3138 | if (net != &init_net) | ||
3139 | return -EINVAL; | ||
3140 | |||
3141 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3198 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3142 | if (err < 0) | 3199 | if (err < 0) |
3143 | return err; | 3200 | return err; |
@@ -3158,7 +3215,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3158 | valid_lft = INFINITY_LIFE_TIME; | 3215 | valid_lft = INFINITY_LIFE_TIME; |
3159 | } | 3216 | } |
3160 | 3217 | ||
3161 | dev = __dev_get_by_index(&init_net, ifm->ifa_index); | 3218 | dev = __dev_get_by_index(net, ifm->ifa_index); |
3162 | if (dev == NULL) | 3219 | if (dev == NULL) |
3163 | return -ENODEV; | 3220 | return -ENODEV; |
3164 | 3221 | ||
@@ -3171,8 +3228,9 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3171 | * It would be best to check for !NLM_F_CREATE here but | 3228 | * It would be best to check for !NLM_F_CREATE here but |
3172 | * userspace alreay relies on not having to provide this. | 3229 | * userspace alreay relies on not having to provide this. |
3173 | */ | 3230 | */ |
3174 | return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, | 3231 | return inet6_addr_add(net, ifm->ifa_index, pfx, |
3175 | ifa_flags, preferred_lft, valid_lft); | 3232 | ifm->ifa_prefixlen, ifa_flags, |
3233 | preferred_lft, valid_lft); | ||
3176 | } | 3234 | } |
3177 | 3235 | ||
3178 | if (nlh->nlmsg_flags & NLM_F_EXCL || | 3236 | if (nlh->nlmsg_flags & NLM_F_EXCL || |
@@ -3337,12 +3395,13 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
3337 | struct inet6_ifaddr *ifa; | 3395 | struct inet6_ifaddr *ifa; |
3338 | struct ifmcaddr6 *ifmca; | 3396 | struct ifmcaddr6 *ifmca; |
3339 | struct ifacaddr6 *ifaca; | 3397 | struct ifacaddr6 *ifaca; |
3398 | struct net *net = sock_net(skb->sk); | ||
3340 | 3399 | ||
3341 | s_idx = cb->args[0]; | 3400 | s_idx = cb->args[0]; |
3342 | s_ip_idx = ip_idx = cb->args[1]; | 3401 | s_ip_idx = ip_idx = cb->args[1]; |
3343 | 3402 | ||
3344 | idx = 0; | 3403 | idx = 0; |
3345 | for_each_netdev(&init_net, dev) { | 3404 | for_each_netdev(net, dev) { |
3346 | if (idx < s_idx) | 3405 | if (idx < s_idx) |
3347 | goto cont; | 3406 | goto cont; |
3348 | if (idx > s_idx) | 3407 | if (idx > s_idx) |
@@ -3409,42 +3468,30 @@ cont: | |||
3409 | 3468 | ||
3410 | static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3469 | static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3411 | { | 3470 | { |
3412 | struct net *net = skb->sk->sk_net; | ||
3413 | enum addr_type_t type = UNICAST_ADDR; | 3471 | enum addr_type_t type = UNICAST_ADDR; |
3414 | 3472 | ||
3415 | if (net != &init_net) | ||
3416 | return 0; | ||
3417 | |||
3418 | return inet6_dump_addr(skb, cb, type); | 3473 | return inet6_dump_addr(skb, cb, type); |
3419 | } | 3474 | } |
3420 | 3475 | ||
3421 | static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3476 | static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3422 | { | 3477 | { |
3423 | struct net *net = skb->sk->sk_net; | ||
3424 | enum addr_type_t type = MULTICAST_ADDR; | 3478 | enum addr_type_t type = MULTICAST_ADDR; |
3425 | 3479 | ||
3426 | if (net != &init_net) | ||
3427 | return 0; | ||
3428 | |||
3429 | return inet6_dump_addr(skb, cb, type); | 3480 | return inet6_dump_addr(skb, cb, type); |
3430 | } | 3481 | } |
3431 | 3482 | ||
3432 | 3483 | ||
3433 | static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3484 | static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3434 | { | 3485 | { |
3435 | struct net *net = skb->sk->sk_net; | ||
3436 | enum addr_type_t type = ANYCAST_ADDR; | 3486 | enum addr_type_t type = ANYCAST_ADDR; |
3437 | 3487 | ||
3438 | if (net != &init_net) | ||
3439 | return 0; | ||
3440 | |||
3441 | return inet6_dump_addr(skb, cb, type); | 3488 | return inet6_dump_addr(skb, cb, type); |
3442 | } | 3489 | } |
3443 | 3490 | ||
3444 | static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | 3491 | static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, |
3445 | void *arg) | 3492 | void *arg) |
3446 | { | 3493 | { |
3447 | struct net *net = in_skb->sk->sk_net; | 3494 | struct net *net = sock_net(in_skb->sk); |
3448 | struct ifaddrmsg *ifm; | 3495 | struct ifaddrmsg *ifm; |
3449 | struct nlattr *tb[IFA_MAX+1]; | 3496 | struct nlattr *tb[IFA_MAX+1]; |
3450 | struct in6_addr *addr = NULL; | 3497 | struct in6_addr *addr = NULL; |
@@ -3453,9 +3500,6 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3453 | struct sk_buff *skb; | 3500 | struct sk_buff *skb; |
3454 | int err; | 3501 | int err; |
3455 | 3502 | ||
3456 | if (net != &init_net) | ||
3457 | return -EINVAL; | ||
3458 | |||
3459 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3503 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3460 | if (err < 0) | 3504 | if (err < 0) |
3461 | goto errout; | 3505 | goto errout; |
@@ -3468,7 +3512,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3468 | 3512 | ||
3469 | ifm = nlmsg_data(nlh); | 3513 | ifm = nlmsg_data(nlh); |
3470 | if (ifm->ifa_index) | 3514 | if (ifm->ifa_index) |
3471 | dev = __dev_get_by_index(&init_net, ifm->ifa_index); | 3515 | dev = __dev_get_by_index(net, ifm->ifa_index); |
3472 | 3516 | ||
3473 | if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) { | 3517 | if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) { |
3474 | err = -EADDRNOTAVAIL; | 3518 | err = -EADDRNOTAVAIL; |
@@ -3488,7 +3532,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3488 | kfree_skb(skb); | 3532 | kfree_skb(skb); |
3489 | goto errout_ifa; | 3533 | goto errout_ifa; |
3490 | } | 3534 | } |
3491 | err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); | 3535 | err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); |
3492 | errout_ifa: | 3536 | errout_ifa: |
3493 | in6_ifa_put(ifa); | 3537 | in6_ifa_put(ifa); |
3494 | errout: | 3538 | errout: |
@@ -3498,6 +3542,7 @@ errout: | |||
3498 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | 3542 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) |
3499 | { | 3543 | { |
3500 | struct sk_buff *skb; | 3544 | struct sk_buff *skb; |
3545 | struct net *net = dev_net(ifa->idev->dev); | ||
3501 | int err = -ENOBUFS; | 3546 | int err = -ENOBUFS; |
3502 | 3547 | ||
3503 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); | 3548 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); |
@@ -3511,10 +3556,10 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | |||
3511 | kfree_skb(skb); | 3556 | kfree_skb(skb); |
3512 | goto errout; | 3557 | goto errout; |
3513 | } | 3558 | } |
3514 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 3559 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); |
3515 | errout: | 3560 | errout: |
3516 | if (err < 0) | 3561 | if (err < 0) |
3517 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err); | 3562 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); |
3518 | } | 3563 | } |
3519 | 3564 | ||
3520 | static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | 3565 | static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, |
@@ -3556,6 +3601,9 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | |||
3556 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 3601 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
3557 | array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad; | 3602 | array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad; |
3558 | #endif | 3603 | #endif |
3604 | #ifdef CONFIG_IPV6_MROUTE | ||
3605 | array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding; | ||
3606 | #endif | ||
3559 | } | 3607 | } |
3560 | 3608 | ||
3561 | static inline size_t inet6_if_nlmsg_size(void) | 3609 | static inline size_t inet6_if_nlmsg_size(void) |
@@ -3673,18 +3721,15 @@ nla_put_failure: | |||
3673 | 3721 | ||
3674 | static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | 3722 | static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) |
3675 | { | 3723 | { |
3676 | struct net *net = skb->sk->sk_net; | 3724 | struct net *net = sock_net(skb->sk); |
3677 | int idx, err; | 3725 | int idx, err; |
3678 | int s_idx = cb->args[0]; | 3726 | int s_idx = cb->args[0]; |
3679 | struct net_device *dev; | 3727 | struct net_device *dev; |
3680 | struct inet6_dev *idev; | 3728 | struct inet6_dev *idev; |
3681 | 3729 | ||
3682 | if (net != &init_net) | ||
3683 | return 0; | ||
3684 | |||
3685 | read_lock(&dev_base_lock); | 3730 | read_lock(&dev_base_lock); |
3686 | idx = 0; | 3731 | idx = 0; |
3687 | for_each_netdev(&init_net, dev) { | 3732 | for_each_netdev(net, dev) { |
3688 | if (idx < s_idx) | 3733 | if (idx < s_idx) |
3689 | goto cont; | 3734 | goto cont; |
3690 | if ((idev = in6_dev_get(dev)) == NULL) | 3735 | if ((idev = in6_dev_get(dev)) == NULL) |
@@ -3706,6 +3751,7 @@ cont: | |||
3706 | void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | 3751 | void inet6_ifinfo_notify(int event, struct inet6_dev *idev) |
3707 | { | 3752 | { |
3708 | struct sk_buff *skb; | 3753 | struct sk_buff *skb; |
3754 | struct net *net = dev_net(idev->dev); | ||
3709 | int err = -ENOBUFS; | 3755 | int err = -ENOBUFS; |
3710 | 3756 | ||
3711 | skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC); | 3757 | skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC); |
@@ -3719,10 +3765,10 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | |||
3719 | kfree_skb(skb); | 3765 | kfree_skb(skb); |
3720 | goto errout; | 3766 | goto errout; |
3721 | } | 3767 | } |
3722 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 3768 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); |
3723 | errout: | 3769 | errout: |
3724 | if (err < 0) | 3770 | if (err < 0) |
3725 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err); | 3771 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); |
3726 | } | 3772 | } |
3727 | 3773 | ||
3728 | static inline size_t inet6_prefix_nlmsg_size(void) | 3774 | static inline size_t inet6_prefix_nlmsg_size(void) |
@@ -3775,6 +3821,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3775 | struct prefix_info *pinfo) | 3821 | struct prefix_info *pinfo) |
3776 | { | 3822 | { |
3777 | struct sk_buff *skb; | 3823 | struct sk_buff *skb; |
3824 | struct net *net = dev_net(idev->dev); | ||
3778 | int err = -ENOBUFS; | 3825 | int err = -ENOBUFS; |
3779 | 3826 | ||
3780 | skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC); | 3827 | skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC); |
@@ -3788,10 +3835,10 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3788 | kfree_skb(skb); | 3835 | kfree_skb(skb); |
3789 | goto errout; | 3836 | goto errout; |
3790 | } | 3837 | } |
3791 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); | 3838 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); |
3792 | errout: | 3839 | errout: |
3793 | if (err < 0) | 3840 | if (err < 0) |
3794 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_PREFIX, err); | 3841 | rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err); |
3795 | } | 3842 | } |
3796 | 3843 | ||
3797 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | 3844 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) |
@@ -3887,7 +3934,7 @@ static int addrconf_sysctl_forward_strategy(ctl_table *table, | |||
3887 | static struct addrconf_sysctl_table | 3934 | static struct addrconf_sysctl_table |
3888 | { | 3935 | { |
3889 | struct ctl_table_header *sysctl_header; | 3936 | struct ctl_table_header *sysctl_header; |
3890 | ctl_table addrconf_vars[__NET_IPV6_MAX]; | 3937 | ctl_table addrconf_vars[DEVCONF_MAX+1]; |
3891 | char *dev_name; | 3938 | char *dev_name; |
3892 | } addrconf_sysctl __read_mostly = { | 3939 | } addrconf_sysctl __read_mostly = { |
3893 | .sysctl_header = NULL, | 3940 | .sysctl_header = NULL, |
@@ -4105,6 +4152,16 @@ static struct addrconf_sysctl_table | |||
4105 | 4152 | ||
4106 | }, | 4153 | }, |
4107 | #endif | 4154 | #endif |
4155 | #ifdef CONFIG_IPV6_MROUTE | ||
4156 | { | ||
4157 | .ctl_name = CTL_UNNUMBERED, | ||
4158 | .procname = "mc_forwarding", | ||
4159 | .data = &ipv6_devconf.mc_forwarding, | ||
4160 | .maxlen = sizeof(int), | ||
4161 | .mode = 0644, | ||
4162 | .proc_handler = &proc_dointvec, | ||
4163 | }, | ||
4164 | #endif | ||
4108 | { | 4165 | { |
4109 | .ctl_name = 0, /* sentinel */ | 4166 | .ctl_name = 0, /* sentinel */ |
4110 | } | 4167 | } |
@@ -4186,7 +4243,7 @@ static void addrconf_sysctl_register(struct inet6_dev *idev) | |||
4186 | NET_IPV6_NEIGH, "ipv6", | 4243 | NET_IPV6_NEIGH, "ipv6", |
4187 | &ndisc_ifinfo_sysctl_change, | 4244 | &ndisc_ifinfo_sysctl_change, |
4188 | NULL); | 4245 | NULL); |
4189 | __addrconf_sysctl_register(idev->dev->nd_net, idev->dev->name, | 4246 | __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, |
4190 | idev->dev->ifindex, idev, &idev->cnf); | 4247 | idev->dev->ifindex, idev, &idev->cnf); |
4191 | } | 4248 | } |
4192 | 4249 | ||
@@ -4281,6 +4338,32 @@ int unregister_inet6addr_notifier(struct notifier_block *nb) | |||
4281 | 4338 | ||
4282 | EXPORT_SYMBOL(unregister_inet6addr_notifier); | 4339 | EXPORT_SYMBOL(unregister_inet6addr_notifier); |
4283 | 4340 | ||
4341 | |||
4342 | static int addrconf_net_init(struct net *net) | ||
4343 | { | ||
4344 | return 0; | ||
4345 | } | ||
4346 | |||
4347 | static void addrconf_net_exit(struct net *net) | ||
4348 | { | ||
4349 | struct net_device *dev; | ||
4350 | |||
4351 | rtnl_lock(); | ||
4352 | /* clean dev list */ | ||
4353 | for_each_netdev(net, dev) { | ||
4354 | if (__in6_dev_get(dev) == NULL) | ||
4355 | continue; | ||
4356 | addrconf_ifdown(dev, 1); | ||
4357 | } | ||
4358 | addrconf_ifdown(net->loopback_dev, 2); | ||
4359 | rtnl_unlock(); | ||
4360 | } | ||
4361 | |||
4362 | static struct pernet_operations addrconf_net_ops = { | ||
4363 | .init = addrconf_net_init, | ||
4364 | .exit = addrconf_net_exit, | ||
4365 | }; | ||
4366 | |||
4284 | /* | 4367 | /* |
4285 | * Init / cleanup code | 4368 | * Init / cleanup code |
4286 | */ | 4369 | */ |
@@ -4322,14 +4405,9 @@ int __init addrconf_init(void) | |||
4322 | if (err) | 4405 | if (err) |
4323 | goto errlo; | 4406 | goto errlo; |
4324 | 4407 | ||
4325 | ip6_null_entry.u.dst.dev = init_net.loopback_dev; | 4408 | err = register_pernet_device(&addrconf_net_ops); |
4326 | ip6_null_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); | 4409 | if (err) |
4327 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 4410 | return err; |
4328 | ip6_prohibit_entry.u.dst.dev = init_net.loopback_dev; | ||
4329 | ip6_prohibit_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); | ||
4330 | ip6_blk_hole_entry.u.dst.dev = init_net.loopback_dev; | ||
4331 | ip6_blk_hole_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); | ||
4332 | #endif | ||
4333 | 4411 | ||
4334 | register_netdevice_notifier(&ipv6_dev_notf); | 4412 | register_netdevice_notifier(&ipv6_dev_notf); |
4335 | 4413 | ||
@@ -4359,31 +4437,19 @@ errlo: | |||
4359 | 4437 | ||
4360 | void addrconf_cleanup(void) | 4438 | void addrconf_cleanup(void) |
4361 | { | 4439 | { |
4362 | struct net_device *dev; | ||
4363 | struct inet6_ifaddr *ifa; | 4440 | struct inet6_ifaddr *ifa; |
4364 | int i; | 4441 | int i; |
4365 | 4442 | ||
4366 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4443 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4444 | unregister_pernet_device(&addrconf_net_ops); | ||
4367 | 4445 | ||
4368 | unregister_pernet_subsys(&addrconf_ops); | 4446 | unregister_pernet_subsys(&addrconf_ops); |
4369 | 4447 | ||
4370 | rtnl_lock(); | 4448 | rtnl_lock(); |
4371 | 4449 | ||
4372 | /* | 4450 | /* |
4373 | * clean dev list. | ||
4374 | */ | ||
4375 | |||
4376 | for_each_netdev(&init_net, dev) { | ||
4377 | if (__in6_dev_get(dev) == NULL) | ||
4378 | continue; | ||
4379 | addrconf_ifdown(dev, 1); | ||
4380 | } | ||
4381 | addrconf_ifdown(init_net.loopback_dev, 2); | ||
4382 | |||
4383 | /* | ||
4384 | * Check hash table. | 4451 | * Check hash table. |
4385 | */ | 4452 | */ |
4386 | |||
4387 | write_lock_bh(&addrconf_hash_lock); | 4453 | write_lock_bh(&addrconf_hash_lock); |
4388 | for (i=0; i < IN6_ADDR_HSIZE; i++) { | 4454 | for (i=0; i < IN6_ADDR_HSIZE; i++) { |
4389 | for (ifa=inet6_addr_lst[i]; ifa; ) { | 4455 | for (ifa=inet6_addr_lst[i]; ifa; ) { |
@@ -4400,6 +4466,7 @@ void addrconf_cleanup(void) | |||
4400 | write_unlock_bh(&addrconf_hash_lock); | 4466 | write_unlock_bh(&addrconf_hash_lock); |
4401 | 4467 | ||
4402 | del_timer(&addr_chk_timer); | 4468 | del_timer(&addr_chk_timer); |
4403 | |||
4404 | rtnl_unlock(); | 4469 | rtnl_unlock(); |
4470 | |||
4471 | unregister_pernet_subsys(&addrconf_net_ops); | ||
4405 | } | 4472 | } |