diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 647 |
1 files changed, 324 insertions, 323 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e7a1882db048..87f688857ade 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -335,7 +335,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
335 | 335 | ||
336 | rwlock_init(&ndev->lock); | 336 | rwlock_init(&ndev->lock); |
337 | ndev->dev = dev; | 337 | ndev->dev = dev; |
338 | memcpy(&ndev->cnf, dev->nd_net->ipv6.devconf_dflt, sizeof(ndev->cnf)); | 338 | memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf)); |
339 | ndev->cnf.mtu6 = dev->mtu; | 339 | ndev->cnf.mtu6 = dev->mtu; |
340 | ndev->cnf.sysctl = NULL; | 340 | ndev->cnf.sysctl = NULL; |
341 | ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl); | 341 | ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl); |
@@ -349,7 +349,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
349 | if (snmp6_alloc_dev(ndev) < 0) { | 349 | if (snmp6_alloc_dev(ndev) < 0) { |
350 | ADBG((KERN_WARNING | 350 | ADBG((KERN_WARNING |
351 | "%s(): cannot allocate memory for statistics; dev=%s.\n", | 351 | "%s(): cannot allocate memory for statistics; dev=%s.\n", |
352 | __FUNCTION__, dev->name)); | 352 | __func__, dev->name)); |
353 | neigh_parms_release(&nd_tbl, ndev->nd_parms); | 353 | neigh_parms_release(&nd_tbl, ndev->nd_parms); |
354 | ndev->dead = 1; | 354 | ndev->dead = 1; |
355 | in6_dev_finish_destroy(ndev); | 355 | in6_dev_finish_destroy(ndev); |
@@ -359,7 +359,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
359 | if (snmp6_register_dev(ndev) < 0) { | 359 | if (snmp6_register_dev(ndev) < 0) { |
360 | ADBG((KERN_WARNING | 360 | ADBG((KERN_WARNING |
361 | "%s(): cannot create /proc/net/dev_snmp6/%s\n", | 361 | "%s(): cannot create /proc/net/dev_snmp6/%s\n", |
362 | __FUNCTION__, dev->name)); | 362 | __func__, dev->name)); |
363 | neigh_parms_release(&nd_tbl, ndev->nd_parms); | 363 | neigh_parms_release(&nd_tbl, ndev->nd_parms); |
364 | ndev->dead = 1; | 364 | ndev->dead = 1; |
365 | in6_dev_finish_destroy(ndev); | 365 | in6_dev_finish_destroy(ndev); |
@@ -493,7 +493,7 @@ static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) | |||
493 | dev_forward_change((struct inet6_dev *)table->extra1); | 493 | dev_forward_change((struct inet6_dev *)table->extra1); |
494 | 494 | ||
495 | if (*p) | 495 | if (*p) |
496 | rt6_purge_dflt_routers(); | 496 | rt6_purge_dflt_routers(net); |
497 | } | 497 | } |
498 | #endif | 498 | #endif |
499 | 499 | ||
@@ -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(dev_net(idev->dev), 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 = dev_net(ifp->idev->dev); | |
755 | ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); | 755 | ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); |
756 | rt = rt6_lookup(&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) { |
@@ -893,20 +893,40 @@ out: | |||
893 | /* | 893 | /* |
894 | * Choose an appropriate source address (RFC3484) | 894 | * Choose an appropriate source address (RFC3484) |
895 | */ | 895 | */ |
896 | enum { | ||
897 | IPV6_SADDR_RULE_INIT = 0, | ||
898 | IPV6_SADDR_RULE_LOCAL, | ||
899 | IPV6_SADDR_RULE_SCOPE, | ||
900 | IPV6_SADDR_RULE_PREFERRED, | ||
901 | #ifdef CONFIG_IPV6_MIP6 | ||
902 | IPV6_SADDR_RULE_HOA, | ||
903 | #endif | ||
904 | IPV6_SADDR_RULE_OIF, | ||
905 | IPV6_SADDR_RULE_LABEL, | ||
906 | #ifdef CONFIG_IPV6_PRIVACY | ||
907 | IPV6_SADDR_RULE_PRIVACY, | ||
908 | #endif | ||
909 | IPV6_SADDR_RULE_ORCHID, | ||
910 | IPV6_SADDR_RULE_PREFIX, | ||
911 | IPV6_SADDR_RULE_MAX | ||
912 | }; | ||
913 | |||
896 | struct ipv6_saddr_score { | 914 | struct ipv6_saddr_score { |
897 | int addr_type; | 915 | int rule; |
898 | unsigned int attrs; | 916 | int addr_type; |
899 | int matchlen; | 917 | struct inet6_ifaddr *ifa; |
900 | int scope; | 918 | DECLARE_BITMAP(scorebits, IPV6_SADDR_RULE_MAX); |
901 | unsigned int rule; | 919 | int scopedist; |
920 | int matchlen; | ||
902 | }; | 921 | }; |
903 | 922 | ||
904 | #define IPV6_SADDR_SCORE_LOCAL 0x0001 | 923 | struct ipv6_saddr_dst { |
905 | #define IPV6_SADDR_SCORE_PREFERRED 0x0004 | 924 | struct in6_addr *addr; |
906 | #define IPV6_SADDR_SCORE_HOA 0x0008 | 925 | int ifindex; |
907 | #define IPV6_SADDR_SCORE_OIF 0x0010 | 926 | int scope; |
908 | #define IPV6_SADDR_SCORE_LABEL 0x0020 | 927 | int label; |
909 | #define IPV6_SADDR_SCORE_PRIVACY 0x0040 | 928 | unsigned int prefs; |
929 | }; | ||
910 | 930 | ||
911 | static inline int ipv6_saddr_preferred(int type) | 931 | static inline int ipv6_saddr_preferred(int type) |
912 | { | 932 | { |
@@ -916,27 +936,152 @@ static inline int ipv6_saddr_preferred(int type) | |||
916 | return 0; | 936 | return 0; |
917 | } | 937 | } |
918 | 938 | ||
919 | int ipv6_dev_get_saddr(struct net_device *daddr_dev, | 939 | static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, |
920 | struct in6_addr *daddr, struct in6_addr *saddr) | 940 | struct ipv6_saddr_dst *dst, |
941 | int i) | ||
921 | { | 942 | { |
922 | struct ipv6_saddr_score hiscore; | 943 | int ret; |
923 | struct inet6_ifaddr *ifa_result = NULL; | 944 | |
924 | int daddr_type = __ipv6_addr_type(daddr); | 945 | if (i <= score->rule) { |
925 | int daddr_scope = __ipv6_addr_src_scope(daddr_type); | 946 | switch (i) { |
926 | int daddr_ifindex = daddr_dev ? daddr_dev->ifindex : 0; | 947 | case IPV6_SADDR_RULE_SCOPE: |
927 | u32 daddr_label = ipv6_addr_label(daddr, daddr_type, daddr_ifindex); | 948 | ret = score->scopedist; |
949 | break; | ||
950 | case IPV6_SADDR_RULE_PREFIX: | ||
951 | ret = score->matchlen; | ||
952 | break; | ||
953 | default: | ||
954 | ret = !!test_bit(i, score->scorebits); | ||
955 | } | ||
956 | goto out; | ||
957 | } | ||
958 | |||
959 | switch (i) { | ||
960 | case IPV6_SADDR_RULE_INIT: | ||
961 | /* Rule 0: remember if hiscore is not ready yet */ | ||
962 | ret = !!score->ifa; | ||
963 | break; | ||
964 | case IPV6_SADDR_RULE_LOCAL: | ||
965 | /* Rule 1: Prefer same address */ | ||
966 | ret = ipv6_addr_equal(&score->ifa->addr, dst->addr); | ||
967 | break; | ||
968 | case IPV6_SADDR_RULE_SCOPE: | ||
969 | /* Rule 2: Prefer appropriate scope | ||
970 | * | ||
971 | * ret | ||
972 | * ^ | ||
973 | * -1 | d 15 | ||
974 | * ---+--+-+---> scope | ||
975 | * | | ||
976 | * | d is scope of the destination. | ||
977 | * B-d | \ | ||
978 | * | \ <- smaller scope is better if | ||
979 | * B-15 | \ if scope is enough for destinaion. | ||
980 | * | ret = B - scope (-1 <= scope >= d <= 15). | ||
981 | * d-C-1 | / | ||
982 | * |/ <- greater is better | ||
983 | * -C / if scope is not enough for destination. | ||
984 | * /| ret = scope - C (-1 <= d < scope <= 15). | ||
985 | * | ||
986 | * d - C - 1 < B -15 (for all -1 <= d <= 15). | ||
987 | * C > d + 14 - B >= 15 + 14 - B = 29 - B. | ||
988 | * Assume B = 0 and we get C > 29. | ||
989 | */ | ||
990 | ret = __ipv6_addr_src_scope(score->addr_type); | ||
991 | if (ret >= dst->scope) | ||
992 | ret = -ret; | ||
993 | else | ||
994 | ret -= 128; /* 30 is enough */ | ||
995 | score->scopedist = ret; | ||
996 | break; | ||
997 | case IPV6_SADDR_RULE_PREFERRED: | ||
998 | /* Rule 3: Avoid deprecated and optimistic addresses */ | ||
999 | ret = ipv6_saddr_preferred(score->addr_type) || | ||
1000 | !(score->ifa->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)); | ||
1001 | break; | ||
1002 | #ifdef CONFIG_IPV6_MIP6 | ||
1003 | case IPV6_SADDR_RULE_HOA: | ||
1004 | { | ||
1005 | /* Rule 4: Prefer home address */ | ||
1006 | int prefhome = !(dst->prefs & IPV6_PREFER_SRC_COA); | ||
1007 | ret = !(score->ifa->flags & IFA_F_HOMEADDRESS) ^ prefhome; | ||
1008 | break; | ||
1009 | } | ||
1010 | #endif | ||
1011 | case IPV6_SADDR_RULE_OIF: | ||
1012 | /* Rule 5: Prefer outgoing interface */ | ||
1013 | ret = (!dst->ifindex || | ||
1014 | dst->ifindex == score->ifa->idev->dev->ifindex); | ||
1015 | break; | ||
1016 | case IPV6_SADDR_RULE_LABEL: | ||
1017 | /* Rule 6: Prefer matching label */ | ||
1018 | ret = ipv6_addr_label(&score->ifa->addr, score->addr_type, | ||
1019 | score->ifa->idev->dev->ifindex) == dst->label; | ||
1020 | break; | ||
1021 | #ifdef CONFIG_IPV6_PRIVACY | ||
1022 | case IPV6_SADDR_RULE_PRIVACY: | ||
1023 | { | ||
1024 | /* Rule 7: Prefer public address | ||
1025 | * Note: prefer temprary address if use_tempaddr >= 2 | ||
1026 | */ | ||
1027 | int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP) ? | ||
1028 | !!(dst->prefs & IPV6_PREFER_SRC_TMP) : | ||
1029 | score->ifa->idev->cnf.use_tempaddr >= 2; | ||
1030 | ret = (!(score->ifa->flags & IFA_F_TEMPORARY)) ^ preftmp; | ||
1031 | break; | ||
1032 | } | ||
1033 | #endif | ||
1034 | case IPV6_SADDR_RULE_ORCHID: | ||
1035 | /* Rule 8-: Prefer ORCHID vs ORCHID or | ||
1036 | * non-ORCHID vs non-ORCHID | ||
1037 | */ | ||
1038 | ret = !(ipv6_addr_orchid(&score->ifa->addr) ^ | ||
1039 | ipv6_addr_orchid(dst->addr)); | ||
1040 | break; | ||
1041 | case IPV6_SADDR_RULE_PREFIX: | ||
1042 | /* Rule 8: Use longest matching prefix */ | ||
1043 | score->matchlen = ret = ipv6_addr_diff(&score->ifa->addr, | ||
1044 | dst->addr); | ||
1045 | break; | ||
1046 | default: | ||
1047 | ret = 0; | ||
1048 | } | ||
1049 | |||
1050 | if (ret) | ||
1051 | __set_bit(i, score->scorebits); | ||
1052 | score->rule = i; | ||
1053 | out: | ||
1054 | return ret; | ||
1055 | } | ||
1056 | |||
1057 | int ipv6_dev_get_saddr(struct net_device *dst_dev, | ||
1058 | struct in6_addr *daddr, unsigned int prefs, | ||
1059 | struct in6_addr *saddr) | ||
1060 | { | ||
1061 | struct ipv6_saddr_score scores[2], | ||
1062 | *score = &scores[0], *hiscore = &scores[1]; | ||
1063 | struct net *net = dev_net(dst_dev); | ||
1064 | struct ipv6_saddr_dst dst; | ||
928 | struct net_device *dev; | 1065 | struct net_device *dev; |
1066 | int dst_type; | ||
1067 | |||
1068 | dst_type = __ipv6_addr_type(daddr); | ||
1069 | dst.addr = daddr; | ||
1070 | dst.ifindex = dst_dev ? dst_dev->ifindex : 0; | ||
1071 | dst.scope = __ipv6_addr_src_scope(dst_type); | ||
1072 | dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex); | ||
1073 | dst.prefs = prefs; | ||
929 | 1074 | ||
930 | memset(&hiscore, 0, sizeof(hiscore)); | 1075 | hiscore->rule = -1; |
1076 | hiscore->ifa = NULL; | ||
931 | 1077 | ||
932 | read_lock(&dev_base_lock); | 1078 | read_lock(&dev_base_lock); |
933 | rcu_read_lock(); | 1079 | rcu_read_lock(); |
934 | 1080 | ||
935 | for_each_netdev(&init_net, dev) { | 1081 | for_each_netdev(net, dev) { |
936 | struct inet6_dev *idev; | 1082 | struct inet6_dev *idev; |
937 | struct inet6_ifaddr *ifa; | ||
938 | 1083 | ||
939 | /* Rule 0: Candidate Source Address (section 4) | 1084 | /* Candidate Source Address (section 4) |
940 | * - multicast and link-local destination address, | 1085 | * - multicast and link-local destination address, |
941 | * the set of candidate source address MUST only | 1086 | * the set of candidate source address MUST only |
942 | * include addresses assigned to interfaces | 1087 | * include addresses assigned to interfaces |
@@ -948,9 +1093,9 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
948 | * belonging to the same site as the outgoing | 1093 | * belonging to the same site as the outgoing |
949 | * interface.) | 1094 | * interface.) |
950 | */ | 1095 | */ |
951 | if ((daddr_type & IPV6_ADDR_MULTICAST || | 1096 | if (((dst_type & IPV6_ADDR_MULTICAST) || |
952 | daddr_scope <= IPV6_ADDR_SCOPE_LINKLOCAL) && | 1097 | dst.scope <= IPV6_ADDR_SCOPE_LINKLOCAL) && |
953 | daddr_dev && dev != daddr_dev) | 1098 | dst.ifindex && dev->ifindex != dst.ifindex) |
954 | continue; | 1099 | continue; |
955 | 1100 | ||
956 | idev = __in6_dev_get(dev); | 1101 | idev = __in6_dev_get(dev); |
@@ -958,12 +1103,10 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
958 | continue; | 1103 | continue; |
959 | 1104 | ||
960 | read_lock_bh(&idev->lock); | 1105 | read_lock_bh(&idev->lock); |
961 | for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) { | 1106 | for (score->ifa = idev->addr_list; score->ifa; score->ifa = score->ifa->if_next) { |
962 | struct ipv6_saddr_score score; | 1107 | int i; |
963 | |||
964 | score.addr_type = __ipv6_addr_type(&ifa->addr); | ||
965 | 1108 | ||
966 | /* Rule 0: | 1109 | /* |
967 | * - Tentative Address (RFC2462 section 5.4) | 1110 | * - Tentative Address (RFC2462 section 5.4) |
968 | * - A tentative address is not considered | 1111 | * - A tentative address is not considered |
969 | * "assigned to an interface" in the traditional | 1112 | * "assigned to an interface" in the traditional |
@@ -973,11 +1116,14 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
973 | * addresses, and the unspecified address MUST | 1116 | * addresses, and the unspecified address MUST |
974 | * NOT be included in a candidate set. | 1117 | * NOT be included in a candidate set. |
975 | */ | 1118 | */ |
976 | if ((ifa->flags & IFA_F_TENTATIVE) && | 1119 | if ((score->ifa->flags & IFA_F_TENTATIVE) && |
977 | (!(ifa->flags & IFA_F_OPTIMISTIC))) | 1120 | (!(score->ifa->flags & IFA_F_OPTIMISTIC))) |
978 | continue; | 1121 | continue; |
979 | if (unlikely(score.addr_type == IPV6_ADDR_ANY || | 1122 | |
980 | score.addr_type & IPV6_ADDR_MULTICAST)) { | 1123 | score->addr_type = __ipv6_addr_type(&score->ifa->addr); |
1124 | |||
1125 | if (unlikely(score->addr_type == IPV6_ADDR_ANY || | ||
1126 | score->addr_type & IPV6_ADDR_MULTICAST)) { | ||
981 | LIMIT_NETDEBUG(KERN_DEBUG | 1127 | LIMIT_NETDEBUG(KERN_DEBUG |
982 | "ADDRCONF: unspecified / multicast address " | 1128 | "ADDRCONF: unspecified / multicast address " |
983 | "assigned as unicast address on %s", | 1129 | "assigned as unicast address on %s", |
@@ -985,207 +1131,63 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
985 | continue; | 1131 | continue; |
986 | } | 1132 | } |
987 | 1133 | ||
988 | score.attrs = 0; | 1134 | score->rule = -1; |
989 | score.matchlen = 0; | 1135 | bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX); |
990 | score.scope = 0; | 1136 | |
991 | score.rule = 0; | 1137 | for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) { |
992 | 1138 | int minihiscore, miniscore; | |
993 | if (ifa_result == NULL) { | 1139 | |
994 | /* record it if the first available entry */ | 1140 | minihiscore = ipv6_get_saddr_eval(hiscore, &dst, i); |
995 | goto record_it; | 1141 | miniscore = ipv6_get_saddr_eval(score, &dst, i); |
996 | } | 1142 | |
997 | 1143 | if (minihiscore > miniscore) { | |
998 | /* Rule 1: Prefer same address */ | 1144 | if (i == IPV6_SADDR_RULE_SCOPE && |
999 | if (hiscore.rule < 1) { | 1145 | score->scopedist > 0) { |
1000 | if (ipv6_addr_equal(&ifa_result->addr, daddr)) | 1146 | /* |
1001 | hiscore.attrs |= IPV6_SADDR_SCORE_LOCAL; | 1147 | * special case: |
1002 | hiscore.rule++; | 1148 | * each remaining entry |
1003 | } | 1149 | * has too small (not enough) |
1004 | if (ipv6_addr_equal(&ifa->addr, daddr)) { | 1150 | * scope, because ifa entries |
1005 | score.attrs |= IPV6_SADDR_SCORE_LOCAL; | 1151 | * are sorted by their scope |
1006 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)) { | 1152 | * values. |
1007 | score.rule = 1; | 1153 | */ |
1008 | goto record_it; | 1154 | goto try_nextdev; |
1009 | } | 1155 | } |
1010 | } else { | 1156 | break; |
1011 | if (hiscore.attrs & IPV6_SADDR_SCORE_LOCAL) | 1157 | } else if (minihiscore < miniscore) { |
1012 | continue; | 1158 | struct ipv6_saddr_score *tmp; |
1013 | } | ||
1014 | |||
1015 | /* Rule 2: Prefer appropriate scope */ | ||
1016 | if (hiscore.rule < 2) { | ||
1017 | hiscore.scope = __ipv6_addr_src_scope(hiscore.addr_type); | ||
1018 | hiscore.rule++; | ||
1019 | } | ||
1020 | score.scope = __ipv6_addr_src_scope(score.addr_type); | ||
1021 | if (hiscore.scope < score.scope) { | ||
1022 | if (hiscore.scope < daddr_scope) { | ||
1023 | score.rule = 2; | ||
1024 | goto record_it; | ||
1025 | } else | ||
1026 | continue; | ||
1027 | } else if (score.scope < hiscore.scope) { | ||
1028 | if (score.scope < daddr_scope) | ||
1029 | break; /* addresses sorted by scope */ | ||
1030 | else { | ||
1031 | score.rule = 2; | ||
1032 | goto record_it; | ||
1033 | } | ||
1034 | } | ||
1035 | 1159 | ||
1036 | /* Rule 3: Avoid deprecated and optimistic addresses */ | 1160 | if (hiscore->ifa) |
1037 | if (hiscore.rule < 3) { | 1161 | in6_ifa_put(hiscore->ifa); |
1038 | if (ipv6_saddr_preferred(hiscore.addr_type) || | ||
1039 | (((ifa_result->flags & | ||
1040 | (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0))) | ||
1041 | hiscore.attrs |= IPV6_SADDR_SCORE_PREFERRED; | ||
1042 | hiscore.rule++; | ||
1043 | } | ||
1044 | if (ipv6_saddr_preferred(score.addr_type) || | ||
1045 | (((ifa->flags & | ||
1046 | (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0))) { | ||
1047 | score.attrs |= IPV6_SADDR_SCORE_PREFERRED; | ||
1048 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) { | ||
1049 | score.rule = 3; | ||
1050 | goto record_it; | ||
1051 | } | ||
1052 | } else { | ||
1053 | if (hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED) | ||
1054 | continue; | ||
1055 | } | ||
1056 | 1162 | ||
1057 | /* Rule 4: Prefer home address */ | 1163 | in6_ifa_hold(score->ifa); |
1058 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | ||
1059 | if (hiscore.rule < 4) { | ||
1060 | if (ifa_result->flags & IFA_F_HOMEADDRESS) | ||
1061 | hiscore.attrs |= IPV6_SADDR_SCORE_HOA; | ||
1062 | hiscore.rule++; | ||
1063 | } | ||
1064 | if (ifa->flags & IFA_F_HOMEADDRESS) { | ||
1065 | score.attrs |= IPV6_SADDR_SCORE_HOA; | ||
1066 | if (!(ifa_result->flags & IFA_F_HOMEADDRESS)) { | ||
1067 | score.rule = 4; | ||
1068 | goto record_it; | ||
1069 | } | ||
1070 | } else { | ||
1071 | if (hiscore.attrs & IPV6_SADDR_SCORE_HOA) | ||
1072 | continue; | ||
1073 | } | ||
1074 | #else | ||
1075 | if (hiscore.rule < 4) | ||
1076 | hiscore.rule++; | ||
1077 | #endif | ||
1078 | 1164 | ||
1079 | /* Rule 5: Prefer outgoing interface */ | 1165 | tmp = hiscore; |
1080 | if (hiscore.rule < 5) { | 1166 | hiscore = score; |
1081 | if (daddr_dev == NULL || | 1167 | score = tmp; |
1082 | daddr_dev == ifa_result->idev->dev) | ||
1083 | hiscore.attrs |= IPV6_SADDR_SCORE_OIF; | ||
1084 | hiscore.rule++; | ||
1085 | } | ||
1086 | if (daddr_dev == NULL || | ||
1087 | daddr_dev == ifa->idev->dev) { | ||
1088 | score.attrs |= IPV6_SADDR_SCORE_OIF; | ||
1089 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_OIF)) { | ||
1090 | score.rule = 5; | ||
1091 | goto record_it; | ||
1092 | } | ||
1093 | } else { | ||
1094 | if (hiscore.attrs & IPV6_SADDR_SCORE_OIF) | ||
1095 | continue; | ||
1096 | } | ||
1097 | 1168 | ||
1098 | /* Rule 6: Prefer matching label */ | 1169 | /* restore our iterator */ |
1099 | if (hiscore.rule < 6) { | 1170 | score->ifa = hiscore->ifa; |
1100 | if (ipv6_addr_label(&ifa_result->addr, | ||
1101 | hiscore.addr_type, | ||
1102 | ifa_result->idev->dev->ifindex) == daddr_label) | ||
1103 | hiscore.attrs |= IPV6_SADDR_SCORE_LABEL; | ||
1104 | hiscore.rule++; | ||
1105 | } | ||
1106 | if (ipv6_addr_label(&ifa->addr, | ||
1107 | score.addr_type, | ||
1108 | ifa->idev->dev->ifindex) == daddr_label) { | ||
1109 | score.attrs |= IPV6_SADDR_SCORE_LABEL; | ||
1110 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_LABEL)) { | ||
1111 | score.rule = 6; | ||
1112 | goto record_it; | ||
1113 | } | ||
1114 | } else { | ||
1115 | if (hiscore.attrs & IPV6_SADDR_SCORE_LABEL) | ||
1116 | continue; | ||
1117 | } | ||
1118 | 1171 | ||
1119 | #ifdef CONFIG_IPV6_PRIVACY | 1172 | break; |
1120 | /* Rule 7: Prefer public address | ||
1121 | * Note: prefer temprary address if use_tempaddr >= 2 | ||
1122 | */ | ||
1123 | if (hiscore.rule < 7) { | ||
1124 | if ((!(ifa_result->flags & IFA_F_TEMPORARY)) ^ | ||
1125 | (ifa_result->idev->cnf.use_tempaddr >= 2)) | ||
1126 | hiscore.attrs |= IPV6_SADDR_SCORE_PRIVACY; | ||
1127 | hiscore.rule++; | ||
1128 | } | ||
1129 | if ((!(ifa->flags & IFA_F_TEMPORARY)) ^ | ||
1130 | (ifa->idev->cnf.use_tempaddr >= 2)) { | ||
1131 | score.attrs |= IPV6_SADDR_SCORE_PRIVACY; | ||
1132 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)) { | ||
1133 | score.rule = 7; | ||
1134 | goto record_it; | ||
1135 | } | 1173 | } |
1136 | } else { | ||
1137 | if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY) | ||
1138 | continue; | ||
1139 | } | ||
1140 | #else | ||
1141 | if (hiscore.rule < 7) | ||
1142 | hiscore.rule++; | ||
1143 | #endif | ||
1144 | /* Rule 8: Use longest matching prefix */ | ||
1145 | if (hiscore.rule < 8) { | ||
1146 | hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr); | ||
1147 | hiscore.rule++; | ||
1148 | } | ||
1149 | score.matchlen = ipv6_addr_diff(&ifa->addr, daddr); | ||
1150 | if (score.matchlen > hiscore.matchlen) { | ||
1151 | score.rule = 8; | ||
1152 | goto record_it; | ||
1153 | } | 1174 | } |
1154 | #if 0 | ||
1155 | else if (score.matchlen < hiscore.matchlen) | ||
1156 | continue; | ||
1157 | #endif | ||
1158 | |||
1159 | /* Final Rule: choose first available one */ | ||
1160 | continue; | ||
1161 | record_it: | ||
1162 | if (ifa_result) | ||
1163 | in6_ifa_put(ifa_result); | ||
1164 | in6_ifa_hold(ifa); | ||
1165 | ifa_result = ifa; | ||
1166 | hiscore = score; | ||
1167 | } | 1175 | } |
1176 | try_nextdev: | ||
1168 | read_unlock_bh(&idev->lock); | 1177 | read_unlock_bh(&idev->lock); |
1169 | } | 1178 | } |
1170 | rcu_read_unlock(); | 1179 | rcu_read_unlock(); |
1171 | read_unlock(&dev_base_lock); | 1180 | read_unlock(&dev_base_lock); |
1172 | 1181 | ||
1173 | if (!ifa_result) | 1182 | if (!hiscore->ifa) |
1174 | return -EADDRNOTAVAIL; | 1183 | return -EADDRNOTAVAIL; |
1175 | 1184 | ||
1176 | ipv6_addr_copy(saddr, &ifa_result->addr); | 1185 | ipv6_addr_copy(saddr, &hiscore->ifa->addr); |
1177 | in6_ifa_put(ifa_result); | 1186 | in6_ifa_put(hiscore->ifa); |
1178 | return 0; | 1187 | return 0; |
1179 | } | 1188 | } |
1180 | 1189 | ||
1181 | 1190 | EXPORT_SYMBOL(ipv6_dev_get_saddr); | |
1182 | int ipv6_get_saddr(struct dst_entry *dst, | ||
1183 | struct in6_addr *daddr, struct in6_addr *saddr) | ||
1184 | { | ||
1185 | return ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, daddr, saddr); | ||
1186 | } | ||
1187 | |||
1188 | EXPORT_SYMBOL(ipv6_get_saddr); | ||
1189 | 1191 | ||
1190 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, | 1192 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, |
1191 | unsigned char banned_flags) | 1193 | unsigned char banned_flags) |
@@ -1231,7 +1233,7 @@ int ipv6_chk_addr(struct net *net, struct in6_addr *addr, | |||
1231 | 1233 | ||
1232 | read_lock_bh(&addrconf_hash_lock); | 1234 | read_lock_bh(&addrconf_hash_lock); |
1233 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1235 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { |
1234 | if (ifp->idev->dev->nd_net != net) | 1236 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1235 | continue; | 1237 | continue; |
1236 | if (ipv6_addr_equal(&ifp->addr, addr) && | 1238 | if (ipv6_addr_equal(&ifp->addr, addr) && |
1237 | !(ifp->flags&IFA_F_TENTATIVE)) { | 1239 | !(ifp->flags&IFA_F_TENTATIVE)) { |
@@ -1253,7 +1255,7 @@ int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, | |||
1253 | u8 hash = ipv6_addr_hash(addr); | 1255 | u8 hash = ipv6_addr_hash(addr); |
1254 | 1256 | ||
1255 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1257 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { |
1256 | if (ifp->idev->dev->nd_net != net) | 1258 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1257 | continue; | 1259 | continue; |
1258 | if (ipv6_addr_equal(&ifp->addr, addr)) { | 1260 | if (ipv6_addr_equal(&ifp->addr, addr)) { |
1259 | if (dev == NULL || ifp->idev->dev == dev) | 1261 | if (dev == NULL || ifp->idev->dev == dev) |
@@ -1271,7 +1273,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr, | |||
1271 | 1273 | ||
1272 | read_lock_bh(&addrconf_hash_lock); | 1274 | read_lock_bh(&addrconf_hash_lock); |
1273 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1275 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { |
1274 | if (ifp->idev->dev->nd_net != net) | 1276 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1275 | continue; | 1277 | continue; |
1276 | if (ipv6_addr_equal(&ifp->addr, addr)) { | 1278 | if (ipv6_addr_equal(&ifp->addr, addr)) { |
1277 | if (dev == NULL || ifp->idev->dev == dev || | 1279 | if (dev == NULL || ifp->idev->dev == dev || |
@@ -1573,7 +1575,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
1573 | .fc_expires = expires, | 1575 | .fc_expires = expires, |
1574 | .fc_dst_len = plen, | 1576 | .fc_dst_len = plen, |
1575 | .fc_flags = RTF_UP | flags, | 1577 | .fc_flags = RTF_UP | flags, |
1576 | .fc_nlinfo.nl_net = &init_net, | 1578 | .fc_nlinfo.nl_net = dev_net(dev), |
1577 | }; | 1579 | }; |
1578 | 1580 | ||
1579 | ipv6_addr_copy(&cfg.fc_dst, pfx); | 1581 | ipv6_addr_copy(&cfg.fc_dst, pfx); |
@@ -1600,7 +1602,7 @@ static void addrconf_add_mroute(struct net_device *dev) | |||
1600 | .fc_ifindex = dev->ifindex, | 1602 | .fc_ifindex = dev->ifindex, |
1601 | .fc_dst_len = 8, | 1603 | .fc_dst_len = 8, |
1602 | .fc_flags = RTF_UP, | 1604 | .fc_flags = RTF_UP, |
1603 | .fc_nlinfo.nl_net = &init_net, | 1605 | .fc_nlinfo.nl_net = dev_net(dev), |
1604 | }; | 1606 | }; |
1605 | 1607 | ||
1606 | ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); | 1608 | ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); |
@@ -1617,7 +1619,7 @@ static void sit_route_add(struct net_device *dev) | |||
1617 | .fc_ifindex = dev->ifindex, | 1619 | .fc_ifindex = dev->ifindex, |
1618 | .fc_dst_len = 96, | 1620 | .fc_dst_len = 96, |
1619 | .fc_flags = RTF_UP | RTF_NONEXTHOP, | 1621 | .fc_flags = RTF_UP | RTF_NONEXTHOP, |
1620 | .fc_nlinfo.nl_net = &init_net, | 1622 | .fc_nlinfo.nl_net = dev_net(dev), |
1621 | }; | 1623 | }; |
1622 | 1624 | ||
1623 | /* prefix length - 96 bits "::d.d.d.d" */ | 1625 | /* prefix length - 96 bits "::d.d.d.d" */ |
@@ -1718,7 +1720,8 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1718 | 1720 | ||
1719 | if (pinfo->onlink) { | 1721 | if (pinfo->onlink) { |
1720 | struct rt6_info *rt; | 1722 | struct rt6_info *rt; |
1721 | rt = rt6_lookup(&pinfo->prefix, NULL, dev->ifindex, 1); | 1723 | rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, |
1724 | dev->ifindex, 1); | ||
1722 | 1725 | ||
1723 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { | 1726 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { |
1724 | if (rt->rt6i_flags&RTF_EXPIRES) { | 1727 | if (rt->rt6i_flags&RTF_EXPIRES) { |
@@ -1761,7 +1764,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1761 | 1764 | ||
1762 | ok: | 1765 | ok: |
1763 | 1766 | ||
1764 | ifp = ipv6_get_ifaddr(&init_net, &addr, dev, 1); | 1767 | ifp = ipv6_get_ifaddr(dev_net(dev), &addr, dev, 1); |
1765 | 1768 | ||
1766 | if (ifp == NULL && valid_lft) { | 1769 | if (ifp == NULL && valid_lft) { |
1767 | int max_addresses = in6_dev->cnf.max_addresses; | 1770 | int max_addresses = in6_dev->cnf.max_addresses; |
@@ -1887,7 +1890,7 @@ ok: | |||
1887 | * Special case for SIT interfaces where we create a new "virtual" | 1890 | * Special case for SIT interfaces where we create a new "virtual" |
1888 | * device. | 1891 | * device. |
1889 | */ | 1892 | */ |
1890 | int addrconf_set_dstaddr(void __user *arg) | 1893 | int addrconf_set_dstaddr(struct net *net, void __user *arg) |
1891 | { | 1894 | { |
1892 | struct in6_ifreq ireq; | 1895 | struct in6_ifreq ireq; |
1893 | struct net_device *dev; | 1896 | struct net_device *dev; |
@@ -1899,7 +1902,7 @@ int addrconf_set_dstaddr(void __user *arg) | |||
1899 | if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) | 1902 | if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) |
1900 | goto err_exit; | 1903 | goto err_exit; |
1901 | 1904 | ||
1902 | dev = __dev_get_by_index(&init_net, ireq.ifr6_ifindex); | 1905 | dev = __dev_get_by_index(net, ireq.ifr6_ifindex); |
1903 | 1906 | ||
1904 | err = -ENODEV; | 1907 | err = -ENODEV; |
1905 | if (dev == NULL) | 1908 | if (dev == NULL) |
@@ -1930,7 +1933,8 @@ int addrconf_set_dstaddr(void __user *arg) | |||
1930 | 1933 | ||
1931 | if (err == 0) { | 1934 | if (err == 0) { |
1932 | err = -ENOBUFS; | 1935 | err = -ENOBUFS; |
1933 | if ((dev = __dev_get_by_name(&init_net, p.name)) == NULL) | 1936 | dev = __dev_get_by_name(net, p.name); |
1937 | if (!dev) | ||
1934 | goto err_exit; | 1938 | goto err_exit; |
1935 | err = dev_open(dev); | 1939 | err = dev_open(dev); |
1936 | } | 1940 | } |
@@ -1945,8 +1949,9 @@ err_exit: | |||
1945 | /* | 1949 | /* |
1946 | * Manual configuration of address on an interface | 1950 | * Manual configuration of address on an interface |
1947 | */ | 1951 | */ |
1948 | static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | 1952 | static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, |
1949 | __u8 ifa_flags, __u32 prefered_lft, __u32 valid_lft) | 1953 | int plen, __u8 ifa_flags, __u32 prefered_lft, |
1954 | __u32 valid_lft) | ||
1950 | { | 1955 | { |
1951 | struct inet6_ifaddr *ifp; | 1956 | struct inet6_ifaddr *ifp; |
1952 | struct inet6_dev *idev; | 1957 | struct inet6_dev *idev; |
@@ -1960,7 +1965,8 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | |||
1960 | if (!valid_lft || prefered_lft > valid_lft) | 1965 | if (!valid_lft || prefered_lft > valid_lft) |
1961 | return -EINVAL; | 1966 | return -EINVAL; |
1962 | 1967 | ||
1963 | if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL) | 1968 | dev = __dev_get_by_index(net, ifindex); |
1969 | if (!dev) | ||
1964 | return -ENODEV; | 1970 | return -ENODEV; |
1965 | 1971 | ||
1966 | if ((idev = addrconf_add_dev(dev)) == NULL) | 1972 | if ((idev = addrconf_add_dev(dev)) == NULL) |
@@ -2005,13 +2011,15 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | |||
2005 | return PTR_ERR(ifp); | 2011 | return PTR_ERR(ifp); |
2006 | } | 2012 | } |
2007 | 2013 | ||
2008 | static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) | 2014 | static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, |
2015 | int plen) | ||
2009 | { | 2016 | { |
2010 | struct inet6_ifaddr *ifp; | 2017 | struct inet6_ifaddr *ifp; |
2011 | struct inet6_dev *idev; | 2018 | struct inet6_dev *idev; |
2012 | struct net_device *dev; | 2019 | struct net_device *dev; |
2013 | 2020 | ||
2014 | if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL) | 2021 | dev = __dev_get_by_index(net, ifindex); |
2022 | if (!dev) | ||
2015 | return -ENODEV; | 2023 | return -ENODEV; |
2016 | 2024 | ||
2017 | if ((idev = __in6_dev_get(dev)) == NULL) | 2025 | if ((idev = __in6_dev_get(dev)) == NULL) |
@@ -2039,7 +2047,7 @@ static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) | |||
2039 | } | 2047 | } |
2040 | 2048 | ||
2041 | 2049 | ||
2042 | int addrconf_add_ifaddr(void __user *arg) | 2050 | int addrconf_add_ifaddr(struct net *net, void __user *arg) |
2043 | { | 2051 | { |
2044 | struct in6_ifreq ireq; | 2052 | struct in6_ifreq ireq; |
2045 | int err; | 2053 | int err; |
@@ -2051,13 +2059,14 @@ int addrconf_add_ifaddr(void __user *arg) | |||
2051 | return -EFAULT; | 2059 | return -EFAULT; |
2052 | 2060 | ||
2053 | rtnl_lock(); | 2061 | rtnl_lock(); |
2054 | err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen, | 2062 | err = inet6_addr_add(net, ireq.ifr6_ifindex, &ireq.ifr6_addr, |
2055 | IFA_F_PERMANENT, INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); | 2063 | ireq.ifr6_prefixlen, IFA_F_PERMANENT, |
2064 | INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); | ||
2056 | rtnl_unlock(); | 2065 | rtnl_unlock(); |
2057 | return err; | 2066 | return err; |
2058 | } | 2067 | } |
2059 | 2068 | ||
2060 | int addrconf_del_ifaddr(void __user *arg) | 2069 | int addrconf_del_ifaddr(struct net *net, void __user *arg) |
2061 | { | 2070 | { |
2062 | struct in6_ifreq ireq; | 2071 | struct in6_ifreq ireq; |
2063 | int err; | 2072 | int err; |
@@ -2069,7 +2078,8 @@ int addrconf_del_ifaddr(void __user *arg) | |||
2069 | return -EFAULT; | 2078 | return -EFAULT; |
2070 | 2079 | ||
2071 | rtnl_lock(); | 2080 | rtnl_lock(); |
2072 | err = inet6_addr_del(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen); | 2081 | err = inet6_addr_del(net, ireq.ifr6_ifindex, &ireq.ifr6_addr, |
2082 | ireq.ifr6_prefixlen); | ||
2073 | rtnl_unlock(); | 2083 | rtnl_unlock(); |
2074 | return err; | 2084 | return err; |
2075 | } | 2085 | } |
@@ -2080,6 +2090,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2080 | struct inet6_ifaddr * ifp; | 2090 | struct inet6_ifaddr * ifp; |
2081 | struct in6_addr addr; | 2091 | struct in6_addr addr; |
2082 | struct net_device *dev; | 2092 | struct net_device *dev; |
2093 | struct net *net = dev_net(idev->dev); | ||
2083 | int scope; | 2094 | int scope; |
2084 | 2095 | ||
2085 | ASSERT_RTNL(); | 2096 | ASSERT_RTNL(); |
@@ -2106,7 +2117,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2106 | return; | 2117 | return; |
2107 | } | 2118 | } |
2108 | 2119 | ||
2109 | for_each_netdev(&init_net, dev) { | 2120 | for_each_netdev(net, dev) { |
2110 | struct in_device * in_dev = __in_dev_get_rtnl(dev); | 2121 | struct in_device * in_dev = __in_dev_get_rtnl(dev); |
2111 | if (in_dev && (dev->flags & IFF_UP)) { | 2122 | if (in_dev && (dev->flags & IFF_UP)) { |
2112 | struct in_ifaddr * ifa; | 2123 | struct in_ifaddr * ifa; |
@@ -2269,15 +2280,16 @@ ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) | |||
2269 | static void ip6_tnl_add_linklocal(struct inet6_dev *idev) | 2280 | static void ip6_tnl_add_linklocal(struct inet6_dev *idev) |
2270 | { | 2281 | { |
2271 | struct net_device *link_dev; | 2282 | struct net_device *link_dev; |
2283 | struct net *net = dev_net(idev->dev); | ||
2272 | 2284 | ||
2273 | /* first try to inherit the link-local address from the link device */ | 2285 | /* first try to inherit the link-local address from the link device */ |
2274 | if (idev->dev->iflink && | 2286 | if (idev->dev->iflink && |
2275 | (link_dev = __dev_get_by_index(&init_net, idev->dev->iflink))) { | 2287 | (link_dev = __dev_get_by_index(net, idev->dev->iflink))) { |
2276 | if (!ipv6_inherit_linklocal(idev, link_dev)) | 2288 | if (!ipv6_inherit_linklocal(idev, link_dev)) |
2277 | return; | 2289 | return; |
2278 | } | 2290 | } |
2279 | /* then try to inherit it from any device */ | 2291 | /* then try to inherit it from any device */ |
2280 | for_each_netdev(&init_net, link_dev) { | 2292 | for_each_netdev(net, link_dev) { |
2281 | if (!ipv6_inherit_linklocal(idev, link_dev)) | 2293 | if (!ipv6_inherit_linklocal(idev, link_dev)) |
2282 | return; | 2294 | return; |
2283 | } | 2295 | } |
@@ -2310,9 +2322,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2310 | int run_pending = 0; | 2322 | int run_pending = 0; |
2311 | int err; | 2323 | int err; |
2312 | 2324 | ||
2313 | if (dev->nd_net != &init_net) | ||
2314 | return NOTIFY_DONE; | ||
2315 | |||
2316 | switch(event) { | 2325 | switch(event) { |
2317 | case NETDEV_REGISTER: | 2326 | case NETDEV_REGISTER: |
2318 | if (!idev && dev->mtu >= IPV6_MIN_MTU) { | 2327 | if (!idev && dev->mtu >= IPV6_MIN_MTU) { |
@@ -2452,6 +2461,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2452 | { | 2461 | { |
2453 | struct inet6_dev *idev; | 2462 | struct inet6_dev *idev; |
2454 | struct inet6_ifaddr *ifa, **bifa; | 2463 | struct inet6_ifaddr *ifa, **bifa; |
2464 | struct net *net = dev_net(dev); | ||
2455 | int i; | 2465 | int i; |
2456 | 2466 | ||
2457 | ASSERT_RTNL(); | 2467 | ASSERT_RTNL(); |
@@ -2459,7 +2469,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2459 | if (dev == init_net.loopback_dev && how == 1) | 2469 | if (dev == init_net.loopback_dev && how == 1) |
2460 | how = 0; | 2470 | how = 0; |
2461 | 2471 | ||
2462 | rt6_ifdown(dev); | 2472 | rt6_ifdown(net, dev); |
2463 | neigh_ifdown(&nd_tbl, dev); | 2473 | neigh_ifdown(&nd_tbl, dev); |
2464 | 2474 | ||
2465 | idev = __in6_dev_get(dev); | 2475 | idev = __in6_dev_get(dev); |
@@ -2775,12 +2785,12 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq) | |||
2775 | { | 2785 | { |
2776 | struct inet6_ifaddr *ifa = NULL; | 2786 | struct inet6_ifaddr *ifa = NULL; |
2777 | struct if6_iter_state *state = seq->private; | 2787 | struct if6_iter_state *state = seq->private; |
2778 | struct net *net = state->p.net; | 2788 | struct net *net = seq_file_net(seq); |
2779 | 2789 | ||
2780 | for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { | 2790 | for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { |
2781 | ifa = inet6_addr_lst[state->bucket]; | 2791 | ifa = inet6_addr_lst[state->bucket]; |
2782 | 2792 | ||
2783 | while (ifa && ifa->idev->dev->nd_net != net) | 2793 | while (ifa && !net_eq(dev_net(ifa->idev->dev), net)) |
2784 | ifa = ifa->lst_next; | 2794 | ifa = ifa->lst_next; |
2785 | if (ifa) | 2795 | if (ifa) |
2786 | break; | 2796 | break; |
@@ -2791,12 +2801,12 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq) | |||
2791 | static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa) | 2801 | static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa) |
2792 | { | 2802 | { |
2793 | struct if6_iter_state *state = seq->private; | 2803 | struct if6_iter_state *state = seq->private; |
2794 | struct net *net = state->p.net; | 2804 | struct net *net = seq_file_net(seq); |
2795 | 2805 | ||
2796 | ifa = ifa->lst_next; | 2806 | ifa = ifa->lst_next; |
2797 | try_again: | 2807 | try_again: |
2798 | if (ifa) { | 2808 | if (ifa) { |
2799 | if (ifa->idev->dev->nd_net != net) { | 2809 | if (!net_eq(dev_net(ifa->idev->dev), net)) { |
2800 | ifa = ifa->lst_next; | 2810 | ifa = ifa->lst_next; |
2801 | goto try_again; | 2811 | goto try_again; |
2802 | } | 2812 | } |
@@ -2914,7 +2924,7 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) | |||
2914 | u8 hash = ipv6_addr_hash(addr); | 2924 | u8 hash = ipv6_addr_hash(addr); |
2915 | read_lock_bh(&addrconf_hash_lock); | 2925 | read_lock_bh(&addrconf_hash_lock); |
2916 | for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) { | 2926 | for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) { |
2917 | if (ifp->idev->dev->nd_net != net) | 2927 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
2918 | continue; | 2928 | continue; |
2919 | if (ipv6_addr_cmp(&ifp->addr, addr) == 0 && | 2929 | if (ipv6_addr_cmp(&ifp->addr, addr) == 0 && |
2920 | (ifp->flags & IFA_F_HOMEADDRESS)) { | 2930 | (ifp->flags & IFA_F_HOMEADDRESS)) { |
@@ -3063,15 +3073,12 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { | |||
3063 | static int | 3073 | static int |
3064 | inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 3074 | inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
3065 | { | 3075 | { |
3066 | struct net *net = skb->sk->sk_net; | 3076 | struct net *net = sock_net(skb->sk); |
3067 | struct ifaddrmsg *ifm; | 3077 | struct ifaddrmsg *ifm; |
3068 | struct nlattr *tb[IFA_MAX+1]; | 3078 | struct nlattr *tb[IFA_MAX+1]; |
3069 | struct in6_addr *pfx; | 3079 | struct in6_addr *pfx; |
3070 | int err; | 3080 | int err; |
3071 | 3081 | ||
3072 | if (net != &init_net) | ||
3073 | return -EINVAL; | ||
3074 | |||
3075 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3082 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3076 | if (err < 0) | 3083 | if (err < 0) |
3077 | return err; | 3084 | return err; |
@@ -3081,7 +3088,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3081 | if (pfx == NULL) | 3088 | if (pfx == NULL) |
3082 | return -EINVAL; | 3089 | return -EINVAL; |
3083 | 3090 | ||
3084 | return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen); | 3091 | return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); |
3085 | } | 3092 | } |
3086 | 3093 | ||
3087 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | 3094 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, |
@@ -3124,7 +3131,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | |||
3124 | static int | 3131 | static int |
3125 | inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 3132 | inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
3126 | { | 3133 | { |
3127 | struct net *net = skb->sk->sk_net; | 3134 | struct net *net = sock_net(skb->sk); |
3128 | struct ifaddrmsg *ifm; | 3135 | struct ifaddrmsg *ifm; |
3129 | struct nlattr *tb[IFA_MAX+1]; | 3136 | struct nlattr *tb[IFA_MAX+1]; |
3130 | struct in6_addr *pfx; | 3137 | struct in6_addr *pfx; |
@@ -3134,9 +3141,6 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3134 | u8 ifa_flags; | 3141 | u8 ifa_flags; |
3135 | int err; | 3142 | int err; |
3136 | 3143 | ||
3137 | if (net != &init_net) | ||
3138 | return -EINVAL; | ||
3139 | |||
3140 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3144 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3141 | if (err < 0) | 3145 | if (err < 0) |
3142 | return err; | 3146 | return err; |
@@ -3157,7 +3161,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3157 | valid_lft = INFINITY_LIFE_TIME; | 3161 | valid_lft = INFINITY_LIFE_TIME; |
3158 | } | 3162 | } |
3159 | 3163 | ||
3160 | dev = __dev_get_by_index(&init_net, ifm->ifa_index); | 3164 | dev = __dev_get_by_index(net, ifm->ifa_index); |
3161 | if (dev == NULL) | 3165 | if (dev == NULL) |
3162 | return -ENODEV; | 3166 | return -ENODEV; |
3163 | 3167 | ||
@@ -3170,8 +3174,9 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3170 | * It would be best to check for !NLM_F_CREATE here but | 3174 | * It would be best to check for !NLM_F_CREATE here but |
3171 | * userspace alreay relies on not having to provide this. | 3175 | * userspace alreay relies on not having to provide this. |
3172 | */ | 3176 | */ |
3173 | return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, | 3177 | return inet6_addr_add(net, ifm->ifa_index, pfx, |
3174 | ifa_flags, preferred_lft, valid_lft); | 3178 | ifm->ifa_prefixlen, ifa_flags, |
3179 | preferred_lft, valid_lft); | ||
3175 | } | 3180 | } |
3176 | 3181 | ||
3177 | if (nlh->nlmsg_flags & NLM_F_EXCL || | 3182 | if (nlh->nlmsg_flags & NLM_F_EXCL || |
@@ -3336,12 +3341,13 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
3336 | struct inet6_ifaddr *ifa; | 3341 | struct inet6_ifaddr *ifa; |
3337 | struct ifmcaddr6 *ifmca; | 3342 | struct ifmcaddr6 *ifmca; |
3338 | struct ifacaddr6 *ifaca; | 3343 | struct ifacaddr6 *ifaca; |
3344 | struct net *net = sock_net(skb->sk); | ||
3339 | 3345 | ||
3340 | s_idx = cb->args[0]; | 3346 | s_idx = cb->args[0]; |
3341 | s_ip_idx = ip_idx = cb->args[1]; | 3347 | s_ip_idx = ip_idx = cb->args[1]; |
3342 | 3348 | ||
3343 | idx = 0; | 3349 | idx = 0; |
3344 | for_each_netdev(&init_net, dev) { | 3350 | for_each_netdev(net, dev) { |
3345 | if (idx < s_idx) | 3351 | if (idx < s_idx) |
3346 | goto cont; | 3352 | goto cont; |
3347 | if (idx > s_idx) | 3353 | if (idx > s_idx) |
@@ -3408,42 +3414,30 @@ cont: | |||
3408 | 3414 | ||
3409 | static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3415 | static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3410 | { | 3416 | { |
3411 | struct net *net = skb->sk->sk_net; | ||
3412 | enum addr_type_t type = UNICAST_ADDR; | 3417 | enum addr_type_t type = UNICAST_ADDR; |
3413 | 3418 | ||
3414 | if (net != &init_net) | ||
3415 | return 0; | ||
3416 | |||
3417 | return inet6_dump_addr(skb, cb, type); | 3419 | return inet6_dump_addr(skb, cb, type); |
3418 | } | 3420 | } |
3419 | 3421 | ||
3420 | static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3422 | static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3421 | { | 3423 | { |
3422 | struct net *net = skb->sk->sk_net; | ||
3423 | enum addr_type_t type = MULTICAST_ADDR; | 3424 | enum addr_type_t type = MULTICAST_ADDR; |
3424 | 3425 | ||
3425 | if (net != &init_net) | ||
3426 | return 0; | ||
3427 | |||
3428 | return inet6_dump_addr(skb, cb, type); | 3426 | return inet6_dump_addr(skb, cb, type); |
3429 | } | 3427 | } |
3430 | 3428 | ||
3431 | 3429 | ||
3432 | static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3430 | static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3433 | { | 3431 | { |
3434 | struct net *net = skb->sk->sk_net; | ||
3435 | enum addr_type_t type = ANYCAST_ADDR; | 3432 | enum addr_type_t type = ANYCAST_ADDR; |
3436 | 3433 | ||
3437 | if (net != &init_net) | ||
3438 | return 0; | ||
3439 | |||
3440 | return inet6_dump_addr(skb, cb, type); | 3434 | return inet6_dump_addr(skb, cb, type); |
3441 | } | 3435 | } |
3442 | 3436 | ||
3443 | static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | 3437 | static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, |
3444 | void *arg) | 3438 | void *arg) |
3445 | { | 3439 | { |
3446 | struct net *net = in_skb->sk->sk_net; | 3440 | struct net *net = sock_net(in_skb->sk); |
3447 | struct ifaddrmsg *ifm; | 3441 | struct ifaddrmsg *ifm; |
3448 | struct nlattr *tb[IFA_MAX+1]; | 3442 | struct nlattr *tb[IFA_MAX+1]; |
3449 | struct in6_addr *addr = NULL; | 3443 | struct in6_addr *addr = NULL; |
@@ -3452,9 +3446,6 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3452 | struct sk_buff *skb; | 3446 | struct sk_buff *skb; |
3453 | int err; | 3447 | int err; |
3454 | 3448 | ||
3455 | if (net != &init_net) | ||
3456 | return -EINVAL; | ||
3457 | |||
3458 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3449 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3459 | if (err < 0) | 3450 | if (err < 0) |
3460 | goto errout; | 3451 | goto errout; |
@@ -3467,7 +3458,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3467 | 3458 | ||
3468 | ifm = nlmsg_data(nlh); | 3459 | ifm = nlmsg_data(nlh); |
3469 | if (ifm->ifa_index) | 3460 | if (ifm->ifa_index) |
3470 | dev = __dev_get_by_index(&init_net, ifm->ifa_index); | 3461 | dev = __dev_get_by_index(net, ifm->ifa_index); |
3471 | 3462 | ||
3472 | if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) { | 3463 | if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) { |
3473 | err = -EADDRNOTAVAIL; | 3464 | err = -EADDRNOTAVAIL; |
@@ -3487,7 +3478,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3487 | kfree_skb(skb); | 3478 | kfree_skb(skb); |
3488 | goto errout_ifa; | 3479 | goto errout_ifa; |
3489 | } | 3480 | } |
3490 | err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); | 3481 | err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); |
3491 | errout_ifa: | 3482 | errout_ifa: |
3492 | in6_ifa_put(ifa); | 3483 | in6_ifa_put(ifa); |
3493 | errout: | 3484 | errout: |
@@ -3497,6 +3488,7 @@ errout: | |||
3497 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | 3488 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) |
3498 | { | 3489 | { |
3499 | struct sk_buff *skb; | 3490 | struct sk_buff *skb; |
3491 | struct net *net = dev_net(ifa->idev->dev); | ||
3500 | int err = -ENOBUFS; | 3492 | int err = -ENOBUFS; |
3501 | 3493 | ||
3502 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); | 3494 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); |
@@ -3510,10 +3502,10 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | |||
3510 | kfree_skb(skb); | 3502 | kfree_skb(skb); |
3511 | goto errout; | 3503 | goto errout; |
3512 | } | 3504 | } |
3513 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 3505 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); |
3514 | errout: | 3506 | errout: |
3515 | if (err < 0) | 3507 | if (err < 0) |
3516 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err); | 3508 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); |
3517 | } | 3509 | } |
3518 | 3510 | ||
3519 | static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | 3511 | static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, |
@@ -3672,18 +3664,15 @@ nla_put_failure: | |||
3672 | 3664 | ||
3673 | static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | 3665 | static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) |
3674 | { | 3666 | { |
3675 | struct net *net = skb->sk->sk_net; | 3667 | struct net *net = sock_net(skb->sk); |
3676 | int idx, err; | 3668 | int idx, err; |
3677 | int s_idx = cb->args[0]; | 3669 | int s_idx = cb->args[0]; |
3678 | struct net_device *dev; | 3670 | struct net_device *dev; |
3679 | struct inet6_dev *idev; | 3671 | struct inet6_dev *idev; |
3680 | 3672 | ||
3681 | if (net != &init_net) | ||
3682 | return 0; | ||
3683 | |||
3684 | read_lock(&dev_base_lock); | 3673 | read_lock(&dev_base_lock); |
3685 | idx = 0; | 3674 | idx = 0; |
3686 | for_each_netdev(&init_net, dev) { | 3675 | for_each_netdev(net, dev) { |
3687 | if (idx < s_idx) | 3676 | if (idx < s_idx) |
3688 | goto cont; | 3677 | goto cont; |
3689 | if ((idev = in6_dev_get(dev)) == NULL) | 3678 | if ((idev = in6_dev_get(dev)) == NULL) |
@@ -3705,6 +3694,7 @@ cont: | |||
3705 | void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | 3694 | void inet6_ifinfo_notify(int event, struct inet6_dev *idev) |
3706 | { | 3695 | { |
3707 | struct sk_buff *skb; | 3696 | struct sk_buff *skb; |
3697 | struct net *net = dev_net(idev->dev); | ||
3708 | int err = -ENOBUFS; | 3698 | int err = -ENOBUFS; |
3709 | 3699 | ||
3710 | skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC); | 3700 | skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC); |
@@ -3718,10 +3708,10 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | |||
3718 | kfree_skb(skb); | 3708 | kfree_skb(skb); |
3719 | goto errout; | 3709 | goto errout; |
3720 | } | 3710 | } |
3721 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 3711 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); |
3722 | errout: | 3712 | errout: |
3723 | if (err < 0) | 3713 | if (err < 0) |
3724 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err); | 3714 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); |
3725 | } | 3715 | } |
3726 | 3716 | ||
3727 | static inline size_t inet6_prefix_nlmsg_size(void) | 3717 | static inline size_t inet6_prefix_nlmsg_size(void) |
@@ -3774,6 +3764,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3774 | struct prefix_info *pinfo) | 3764 | struct prefix_info *pinfo) |
3775 | { | 3765 | { |
3776 | struct sk_buff *skb; | 3766 | struct sk_buff *skb; |
3767 | struct net *net = dev_net(idev->dev); | ||
3777 | int err = -ENOBUFS; | 3768 | int err = -ENOBUFS; |
3778 | 3769 | ||
3779 | skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC); | 3770 | skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC); |
@@ -3787,10 +3778,10 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3787 | kfree_skb(skb); | 3778 | kfree_skb(skb); |
3788 | goto errout; | 3779 | goto errout; |
3789 | } | 3780 | } |
3790 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); | 3781 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); |
3791 | errout: | 3782 | errout: |
3792 | if (err < 0) | 3783 | if (err < 0) |
3793 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_PREFIX, err); | 3784 | rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err); |
3794 | } | 3785 | } |
3795 | 3786 | ||
3796 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | 3787 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) |
@@ -4185,7 +4176,7 @@ static void addrconf_sysctl_register(struct inet6_dev *idev) | |||
4185 | NET_IPV6_NEIGH, "ipv6", | 4176 | NET_IPV6_NEIGH, "ipv6", |
4186 | &ndisc_ifinfo_sysctl_change, | 4177 | &ndisc_ifinfo_sysctl_change, |
4187 | NULL); | 4178 | NULL); |
4188 | __addrconf_sysctl_register(idev->dev->nd_net, idev->dev->name, | 4179 | __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, |
4189 | idev->dev->ifindex, idev, &idev->cnf); | 4180 | idev->dev->ifindex, idev, &idev->cnf); |
4190 | } | 4181 | } |
4191 | 4182 | ||
@@ -4280,6 +4271,32 @@ int unregister_inet6addr_notifier(struct notifier_block *nb) | |||
4280 | 4271 | ||
4281 | EXPORT_SYMBOL(unregister_inet6addr_notifier); | 4272 | EXPORT_SYMBOL(unregister_inet6addr_notifier); |
4282 | 4273 | ||
4274 | |||
4275 | static int addrconf_net_init(struct net *net) | ||
4276 | { | ||
4277 | return 0; | ||
4278 | } | ||
4279 | |||
4280 | static void addrconf_net_exit(struct net *net) | ||
4281 | { | ||
4282 | struct net_device *dev; | ||
4283 | |||
4284 | rtnl_lock(); | ||
4285 | /* clean dev list */ | ||
4286 | for_each_netdev(net, dev) { | ||
4287 | if (__in6_dev_get(dev) == NULL) | ||
4288 | continue; | ||
4289 | addrconf_ifdown(dev, 1); | ||
4290 | } | ||
4291 | addrconf_ifdown(net->loopback_dev, 2); | ||
4292 | rtnl_unlock(); | ||
4293 | } | ||
4294 | |||
4295 | static struct pernet_operations addrconf_net_ops = { | ||
4296 | .init = addrconf_net_init, | ||
4297 | .exit = addrconf_net_exit, | ||
4298 | }; | ||
4299 | |||
4283 | /* | 4300 | /* |
4284 | * Init / cleanup code | 4301 | * Init / cleanup code |
4285 | */ | 4302 | */ |
@@ -4321,14 +4338,9 @@ int __init addrconf_init(void) | |||
4321 | if (err) | 4338 | if (err) |
4322 | goto errlo; | 4339 | goto errlo; |
4323 | 4340 | ||
4324 | ip6_null_entry.u.dst.dev = init_net.loopback_dev; | 4341 | err = register_pernet_device(&addrconf_net_ops); |
4325 | ip6_null_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); | 4342 | if (err) |
4326 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 4343 | return err; |
4327 | ip6_prohibit_entry.u.dst.dev = init_net.loopback_dev; | ||
4328 | ip6_prohibit_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); | ||
4329 | ip6_blk_hole_entry.u.dst.dev = init_net.loopback_dev; | ||
4330 | ip6_blk_hole_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); | ||
4331 | #endif | ||
4332 | 4344 | ||
4333 | register_netdevice_notifier(&ipv6_dev_notf); | 4345 | register_netdevice_notifier(&ipv6_dev_notf); |
4334 | 4346 | ||
@@ -4358,31 +4370,19 @@ errlo: | |||
4358 | 4370 | ||
4359 | void addrconf_cleanup(void) | 4371 | void addrconf_cleanup(void) |
4360 | { | 4372 | { |
4361 | struct net_device *dev; | ||
4362 | struct inet6_ifaddr *ifa; | 4373 | struct inet6_ifaddr *ifa; |
4363 | int i; | 4374 | int i; |
4364 | 4375 | ||
4365 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4376 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4377 | unregister_pernet_device(&addrconf_net_ops); | ||
4366 | 4378 | ||
4367 | unregister_pernet_subsys(&addrconf_ops); | 4379 | unregister_pernet_subsys(&addrconf_ops); |
4368 | 4380 | ||
4369 | rtnl_lock(); | 4381 | rtnl_lock(); |
4370 | 4382 | ||
4371 | /* | 4383 | /* |
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. | 4384 | * Check hash table. |
4384 | */ | 4385 | */ |
4385 | |||
4386 | write_lock_bh(&addrconf_hash_lock); | 4386 | write_lock_bh(&addrconf_hash_lock); |
4387 | for (i=0; i < IN6_ADDR_HSIZE; i++) { | 4387 | for (i=0; i < IN6_ADDR_HSIZE; i++) { |
4388 | for (ifa=inet6_addr_lst[i]; ifa; ) { | 4388 | for (ifa=inet6_addr_lst[i]; ifa; ) { |
@@ -4399,6 +4399,7 @@ void addrconf_cleanup(void) | |||
4399 | write_unlock_bh(&addrconf_hash_lock); | 4399 | write_unlock_bh(&addrconf_hash_lock); |
4400 | 4400 | ||
4401 | del_timer(&addr_chk_timer); | 4401 | del_timer(&addr_chk_timer); |
4402 | |||
4403 | rtnl_unlock(); | 4402 | rtnl_unlock(); |
4403 | |||
4404 | unregister_pernet_subsys(&addrconf_net_ops); | ||
4404 | } | 4405 | } |