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 101e0e70ba27..5ab9973571ef 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) { |
@@ -877,20 +877,40 @@ out: | |||
877 | /* | 877 | /* |
878 | * Choose an appropriate source address (RFC3484) | 878 | * Choose an appropriate source address (RFC3484) |
879 | */ | 879 | */ |
880 | enum { | ||
881 | IPV6_SADDR_RULE_INIT = 0, | ||
882 | IPV6_SADDR_RULE_LOCAL, | ||
883 | IPV6_SADDR_RULE_SCOPE, | ||
884 | IPV6_SADDR_RULE_PREFERRED, | ||
885 | #ifdef CONFIG_IPV6_MIP6 | ||
886 | IPV6_SADDR_RULE_HOA, | ||
887 | #endif | ||
888 | IPV6_SADDR_RULE_OIF, | ||
889 | IPV6_SADDR_RULE_LABEL, | ||
890 | #ifdef CONFIG_IPV6_PRIVACY | ||
891 | IPV6_SADDR_RULE_PRIVACY, | ||
892 | #endif | ||
893 | IPV6_SADDR_RULE_ORCHID, | ||
894 | IPV6_SADDR_RULE_PREFIX, | ||
895 | IPV6_SADDR_RULE_MAX | ||
896 | }; | ||
897 | |||
880 | struct ipv6_saddr_score { | 898 | struct ipv6_saddr_score { |
881 | int addr_type; | 899 | int rule; |
882 | unsigned int attrs; | 900 | int addr_type; |
883 | int matchlen; | 901 | struct inet6_ifaddr *ifa; |
884 | int scope; | 902 | DECLARE_BITMAP(scorebits, IPV6_SADDR_RULE_MAX); |
885 | unsigned int rule; | 903 | int scopedist; |
904 | int matchlen; | ||
886 | }; | 905 | }; |
887 | 906 | ||
888 | #define IPV6_SADDR_SCORE_LOCAL 0x0001 | 907 | struct ipv6_saddr_dst { |
889 | #define IPV6_SADDR_SCORE_PREFERRED 0x0004 | 908 | struct in6_addr *addr; |
890 | #define IPV6_SADDR_SCORE_HOA 0x0008 | 909 | int ifindex; |
891 | #define IPV6_SADDR_SCORE_OIF 0x0010 | 910 | int scope; |
892 | #define IPV6_SADDR_SCORE_LABEL 0x0020 | 911 | int label; |
893 | #define IPV6_SADDR_SCORE_PRIVACY 0x0040 | 912 | unsigned int prefs; |
913 | }; | ||
894 | 914 | ||
895 | static inline int ipv6_saddr_preferred(int type) | 915 | static inline int ipv6_saddr_preferred(int type) |
896 | { | 916 | { |
@@ -900,27 +920,152 @@ static inline int ipv6_saddr_preferred(int type) | |||
900 | return 0; | 920 | return 0; |
901 | } | 921 | } |
902 | 922 | ||
903 | int ipv6_dev_get_saddr(struct net_device *daddr_dev, | 923 | static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, |
904 | struct in6_addr *daddr, struct in6_addr *saddr) | 924 | struct ipv6_saddr_dst *dst, |
925 | int i) | ||
905 | { | 926 | { |
906 | struct ipv6_saddr_score hiscore; | 927 | int ret; |
907 | struct inet6_ifaddr *ifa_result = NULL; | 928 | |
908 | int daddr_type = __ipv6_addr_type(daddr); | 929 | if (i <= score->rule) { |
909 | int daddr_scope = __ipv6_addr_src_scope(daddr_type); | 930 | switch (i) { |
910 | int daddr_ifindex = daddr_dev ? daddr_dev->ifindex : 0; | 931 | case IPV6_SADDR_RULE_SCOPE: |
911 | u32 daddr_label = ipv6_addr_label(daddr, daddr_type, daddr_ifindex); | 932 | ret = score->scopedist; |
933 | break; | ||
934 | case IPV6_SADDR_RULE_PREFIX: | ||
935 | ret = score->matchlen; | ||
936 | break; | ||
937 | default: | ||
938 | ret = !!test_bit(i, score->scorebits); | ||
939 | } | ||
940 | goto out; | ||
941 | } | ||
942 | |||
943 | switch (i) { | ||
944 | case IPV6_SADDR_RULE_INIT: | ||
945 | /* Rule 0: remember if hiscore is not ready yet */ | ||
946 | ret = !!score->ifa; | ||
947 | break; | ||
948 | case IPV6_SADDR_RULE_LOCAL: | ||
949 | /* Rule 1: Prefer same address */ | ||
950 | ret = ipv6_addr_equal(&score->ifa->addr, dst->addr); | ||
951 | break; | ||
952 | case IPV6_SADDR_RULE_SCOPE: | ||
953 | /* Rule 2: Prefer appropriate scope | ||
954 | * | ||
955 | * ret | ||
956 | * ^ | ||
957 | * -1 | d 15 | ||
958 | * ---+--+-+---> scope | ||
959 | * | | ||
960 | * | d is scope of the destination. | ||
961 | * B-d | \ | ||
962 | * | \ <- smaller scope is better if | ||
963 | * B-15 | \ if scope is enough for destinaion. | ||
964 | * | ret = B - scope (-1 <= scope >= d <= 15). | ||
965 | * d-C-1 | / | ||
966 | * |/ <- greater is better | ||
967 | * -C / if scope is not enough for destination. | ||
968 | * /| ret = scope - C (-1 <= d < scope <= 15). | ||
969 | * | ||
970 | * d - C - 1 < B -15 (for all -1 <= d <= 15). | ||
971 | * C > d + 14 - B >= 15 + 14 - B = 29 - B. | ||
972 | * Assume B = 0 and we get C > 29. | ||
973 | */ | ||
974 | ret = __ipv6_addr_src_scope(score->addr_type); | ||
975 | if (ret >= dst->scope) | ||
976 | ret = -ret; | ||
977 | else | ||
978 | ret -= 128; /* 30 is enough */ | ||
979 | score->scopedist = ret; | ||
980 | break; | ||
981 | case IPV6_SADDR_RULE_PREFERRED: | ||
982 | /* Rule 3: Avoid deprecated and optimistic addresses */ | ||
983 | ret = ipv6_saddr_preferred(score->addr_type) || | ||
984 | !(score->ifa->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)); | ||
985 | break; | ||
986 | #ifdef CONFIG_IPV6_MIP6 | ||
987 | case IPV6_SADDR_RULE_HOA: | ||
988 | { | ||
989 | /* Rule 4: Prefer home address */ | ||
990 | int prefhome = !(dst->prefs & IPV6_PREFER_SRC_COA); | ||
991 | ret = !(score->ifa->flags & IFA_F_HOMEADDRESS) ^ prefhome; | ||
992 | break; | ||
993 | } | ||
994 | #endif | ||
995 | case IPV6_SADDR_RULE_OIF: | ||
996 | /* Rule 5: Prefer outgoing interface */ | ||
997 | ret = (!dst->ifindex || | ||
998 | dst->ifindex == score->ifa->idev->dev->ifindex); | ||
999 | break; | ||
1000 | case IPV6_SADDR_RULE_LABEL: | ||
1001 | /* Rule 6: Prefer matching label */ | ||
1002 | ret = ipv6_addr_label(&score->ifa->addr, score->addr_type, | ||
1003 | score->ifa->idev->dev->ifindex) == dst->label; | ||
1004 | break; | ||
1005 | #ifdef CONFIG_IPV6_PRIVACY | ||
1006 | case IPV6_SADDR_RULE_PRIVACY: | ||
1007 | { | ||
1008 | /* Rule 7: Prefer public address | ||
1009 | * Note: prefer temprary address if use_tempaddr >= 2 | ||
1010 | */ | ||
1011 | int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP) ? | ||
1012 | !!(dst->prefs & IPV6_PREFER_SRC_TMP) : | ||
1013 | score->ifa->idev->cnf.use_tempaddr >= 2; | ||
1014 | ret = (!(score->ifa->flags & IFA_F_TEMPORARY)) ^ preftmp; | ||
1015 | break; | ||
1016 | } | ||
1017 | #endif | ||
1018 | case IPV6_SADDR_RULE_ORCHID: | ||
1019 | /* Rule 8-: Prefer ORCHID vs ORCHID or | ||
1020 | * non-ORCHID vs non-ORCHID | ||
1021 | */ | ||
1022 | ret = !(ipv6_addr_orchid(&score->ifa->addr) ^ | ||
1023 | ipv6_addr_orchid(dst->addr)); | ||
1024 | break; | ||
1025 | case IPV6_SADDR_RULE_PREFIX: | ||
1026 | /* Rule 8: Use longest matching prefix */ | ||
1027 | score->matchlen = ret = ipv6_addr_diff(&score->ifa->addr, | ||
1028 | dst->addr); | ||
1029 | break; | ||
1030 | default: | ||
1031 | ret = 0; | ||
1032 | } | ||
1033 | |||
1034 | if (ret) | ||
1035 | __set_bit(i, score->scorebits); | ||
1036 | score->rule = i; | ||
1037 | out: | ||
1038 | return ret; | ||
1039 | } | ||
1040 | |||
1041 | int ipv6_dev_get_saddr(struct net_device *dst_dev, | ||
1042 | struct in6_addr *daddr, unsigned int prefs, | ||
1043 | struct in6_addr *saddr) | ||
1044 | { | ||
1045 | struct ipv6_saddr_score scores[2], | ||
1046 | *score = &scores[0], *hiscore = &scores[1]; | ||
1047 | struct net *net = dev_net(dst_dev); | ||
1048 | struct ipv6_saddr_dst dst; | ||
912 | struct net_device *dev; | 1049 | struct net_device *dev; |
1050 | int dst_type; | ||
1051 | |||
1052 | dst_type = __ipv6_addr_type(daddr); | ||
1053 | dst.addr = daddr; | ||
1054 | dst.ifindex = dst_dev ? dst_dev->ifindex : 0; | ||
1055 | dst.scope = __ipv6_addr_src_scope(dst_type); | ||
1056 | dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex); | ||
1057 | dst.prefs = prefs; | ||
913 | 1058 | ||
914 | memset(&hiscore, 0, sizeof(hiscore)); | 1059 | hiscore->rule = -1; |
1060 | hiscore->ifa = NULL; | ||
915 | 1061 | ||
916 | read_lock(&dev_base_lock); | 1062 | read_lock(&dev_base_lock); |
917 | rcu_read_lock(); | 1063 | rcu_read_lock(); |
918 | 1064 | ||
919 | for_each_netdev(&init_net, dev) { | 1065 | for_each_netdev(net, dev) { |
920 | struct inet6_dev *idev; | 1066 | struct inet6_dev *idev; |
921 | struct inet6_ifaddr *ifa; | ||
922 | 1067 | ||
923 | /* Rule 0: Candidate Source Address (section 4) | 1068 | /* Candidate Source Address (section 4) |
924 | * - multicast and link-local destination address, | 1069 | * - multicast and link-local destination address, |
925 | * the set of candidate source address MUST only | 1070 | * the set of candidate source address MUST only |
926 | * include addresses assigned to interfaces | 1071 | * include addresses assigned to interfaces |
@@ -932,9 +1077,9 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
932 | * belonging to the same site as the outgoing | 1077 | * belonging to the same site as the outgoing |
933 | * interface.) | 1078 | * interface.) |
934 | */ | 1079 | */ |
935 | if ((daddr_type & IPV6_ADDR_MULTICAST || | 1080 | if (((dst_type & IPV6_ADDR_MULTICAST) || |
936 | daddr_scope <= IPV6_ADDR_SCOPE_LINKLOCAL) && | 1081 | dst.scope <= IPV6_ADDR_SCOPE_LINKLOCAL) && |
937 | daddr_dev && dev != daddr_dev) | 1082 | dst.ifindex && dev->ifindex != dst.ifindex) |
938 | continue; | 1083 | continue; |
939 | 1084 | ||
940 | idev = __in6_dev_get(dev); | 1085 | idev = __in6_dev_get(dev); |
@@ -942,12 +1087,10 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
942 | continue; | 1087 | continue; |
943 | 1088 | ||
944 | read_lock_bh(&idev->lock); | 1089 | read_lock_bh(&idev->lock); |
945 | for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) { | 1090 | for (score->ifa = idev->addr_list; score->ifa; score->ifa = score->ifa->if_next) { |
946 | struct ipv6_saddr_score score; | 1091 | int i; |
947 | |||
948 | score.addr_type = __ipv6_addr_type(&ifa->addr); | ||
949 | 1092 | ||
950 | /* Rule 0: | 1093 | /* |
951 | * - Tentative Address (RFC2462 section 5.4) | 1094 | * - Tentative Address (RFC2462 section 5.4) |
952 | * - A tentative address is not considered | 1095 | * - A tentative address is not considered |
953 | * "assigned to an interface" in the traditional | 1096 | * "assigned to an interface" in the traditional |
@@ -957,11 +1100,14 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
957 | * addresses, and the unspecified address MUST | 1100 | * addresses, and the unspecified address MUST |
958 | * NOT be included in a candidate set. | 1101 | * NOT be included in a candidate set. |
959 | */ | 1102 | */ |
960 | if ((ifa->flags & IFA_F_TENTATIVE) && | 1103 | if ((score->ifa->flags & IFA_F_TENTATIVE) && |
961 | (!(ifa->flags & IFA_F_OPTIMISTIC))) | 1104 | (!(score->ifa->flags & IFA_F_OPTIMISTIC))) |
962 | continue; | 1105 | continue; |
963 | if (unlikely(score.addr_type == IPV6_ADDR_ANY || | 1106 | |
964 | score.addr_type & IPV6_ADDR_MULTICAST)) { | 1107 | score->addr_type = __ipv6_addr_type(&score->ifa->addr); |
1108 | |||
1109 | if (unlikely(score->addr_type == IPV6_ADDR_ANY || | ||
1110 | score->addr_type & IPV6_ADDR_MULTICAST)) { | ||
965 | LIMIT_NETDEBUG(KERN_DEBUG | 1111 | LIMIT_NETDEBUG(KERN_DEBUG |
966 | "ADDRCONF: unspecified / multicast address " | 1112 | "ADDRCONF: unspecified / multicast address " |
967 | "assigned as unicast address on %s", | 1113 | "assigned as unicast address on %s", |
@@ -969,207 +1115,63 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
969 | continue; | 1115 | continue; |
970 | } | 1116 | } |
971 | 1117 | ||
972 | score.attrs = 0; | 1118 | score->rule = -1; |
973 | score.matchlen = 0; | 1119 | bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX); |
974 | score.scope = 0; | 1120 | |
975 | score.rule = 0; | 1121 | for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) { |
976 | 1122 | int minihiscore, miniscore; | |
977 | if (ifa_result == NULL) { | 1123 | |
978 | /* record it if the first available entry */ | 1124 | minihiscore = ipv6_get_saddr_eval(hiscore, &dst, i); |
979 | goto record_it; | 1125 | miniscore = ipv6_get_saddr_eval(score, &dst, i); |
980 | } | 1126 | |
981 | 1127 | if (minihiscore > miniscore) { | |
982 | /* Rule 1: Prefer same address */ | 1128 | if (i == IPV6_SADDR_RULE_SCOPE && |
983 | if (hiscore.rule < 1) { | 1129 | score->scopedist > 0) { |
984 | if (ipv6_addr_equal(&ifa_result->addr, daddr)) | 1130 | /* |
985 | hiscore.attrs |= IPV6_SADDR_SCORE_LOCAL; | 1131 | * special case: |
986 | hiscore.rule++; | 1132 | * each remaining entry |
987 | } | 1133 | * has too small (not enough) |
988 | if (ipv6_addr_equal(&ifa->addr, daddr)) { | 1134 | * scope, because ifa entries |
989 | score.attrs |= IPV6_SADDR_SCORE_LOCAL; | 1135 | * are sorted by their scope |
990 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)) { | 1136 | * values. |
991 | score.rule = 1; | 1137 | */ |
992 | goto record_it; | 1138 | goto try_nextdev; |
993 | } | 1139 | } |
994 | } else { | 1140 | break; |
995 | if (hiscore.attrs & IPV6_SADDR_SCORE_LOCAL) | 1141 | } else if (minihiscore < miniscore) { |
996 | continue; | 1142 | struct ipv6_saddr_score *tmp; |
997 | } | ||
998 | |||
999 | /* Rule 2: Prefer appropriate scope */ | ||
1000 | if (hiscore.rule < 2) { | ||
1001 | hiscore.scope = __ipv6_addr_src_scope(hiscore.addr_type); | ||
1002 | hiscore.rule++; | ||
1003 | } | ||
1004 | score.scope = __ipv6_addr_src_scope(score.addr_type); | ||
1005 | if (hiscore.scope < score.scope) { | ||
1006 | if (hiscore.scope < daddr_scope) { | ||
1007 | score.rule = 2; | ||
1008 | goto record_it; | ||
1009 | } else | ||
1010 | continue; | ||
1011 | } else if (score.scope < hiscore.scope) { | ||
1012 | if (score.scope < daddr_scope) | ||
1013 | break; /* addresses sorted by scope */ | ||
1014 | else { | ||
1015 | score.rule = 2; | ||
1016 | goto record_it; | ||
1017 | } | ||
1018 | } | ||
1019 | 1143 | ||
1020 | /* Rule 3: Avoid deprecated and optimistic addresses */ | 1144 | if (hiscore->ifa) |
1021 | if (hiscore.rule < 3) { | 1145 | in6_ifa_put(hiscore->ifa); |
1022 | if (ipv6_saddr_preferred(hiscore.addr_type) || | ||
1023 | (((ifa_result->flags & | ||
1024 | (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0))) | ||
1025 | hiscore.attrs |= IPV6_SADDR_SCORE_PREFERRED; | ||
1026 | hiscore.rule++; | ||
1027 | } | ||
1028 | if (ipv6_saddr_preferred(score.addr_type) || | ||
1029 | (((ifa->flags & | ||
1030 | (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0))) { | ||
1031 | score.attrs |= IPV6_SADDR_SCORE_PREFERRED; | ||
1032 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) { | ||
1033 | score.rule = 3; | ||
1034 | goto record_it; | ||
1035 | } | ||
1036 | } else { | ||
1037 | if (hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED) | ||
1038 | continue; | ||
1039 | } | ||
1040 | 1146 | ||
1041 | /* Rule 4: Prefer home address */ | 1147 | in6_ifa_hold(score->ifa); |
1042 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | ||
1043 | if (hiscore.rule < 4) { | ||
1044 | if (ifa_result->flags & IFA_F_HOMEADDRESS) | ||
1045 | hiscore.attrs |= IPV6_SADDR_SCORE_HOA; | ||
1046 | hiscore.rule++; | ||
1047 | } | ||
1048 | if (ifa->flags & IFA_F_HOMEADDRESS) { | ||
1049 | score.attrs |= IPV6_SADDR_SCORE_HOA; | ||
1050 | if (!(ifa_result->flags & IFA_F_HOMEADDRESS)) { | ||
1051 | score.rule = 4; | ||
1052 | goto record_it; | ||
1053 | } | ||
1054 | } else { | ||
1055 | if (hiscore.attrs & IPV6_SADDR_SCORE_HOA) | ||
1056 | continue; | ||
1057 | } | ||
1058 | #else | ||
1059 | if (hiscore.rule < 4) | ||
1060 | hiscore.rule++; | ||
1061 | #endif | ||
1062 | 1148 | ||
1063 | /* Rule 5: Prefer outgoing interface */ | 1149 | tmp = hiscore; |
1064 | if (hiscore.rule < 5) { | 1150 | hiscore = score; |
1065 | if (daddr_dev == NULL || | 1151 | score = tmp; |
1066 | daddr_dev == ifa_result->idev->dev) | ||
1067 | hiscore.attrs |= IPV6_SADDR_SCORE_OIF; | ||
1068 | hiscore.rule++; | ||
1069 | } | ||
1070 | if (daddr_dev == NULL || | ||
1071 | daddr_dev == ifa->idev->dev) { | ||
1072 | score.attrs |= IPV6_SADDR_SCORE_OIF; | ||
1073 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_OIF)) { | ||
1074 | score.rule = 5; | ||
1075 | goto record_it; | ||
1076 | } | ||
1077 | } else { | ||
1078 | if (hiscore.attrs & IPV6_SADDR_SCORE_OIF) | ||
1079 | continue; | ||
1080 | } | ||
1081 | 1152 | ||
1082 | /* Rule 6: Prefer matching label */ | 1153 | /* restore our iterator */ |
1083 | if (hiscore.rule < 6) { | 1154 | score->ifa = hiscore->ifa; |
1084 | if (ipv6_addr_label(&ifa_result->addr, | ||
1085 | hiscore.addr_type, | ||
1086 | ifa_result->idev->dev->ifindex) == daddr_label) | ||
1087 | hiscore.attrs |= IPV6_SADDR_SCORE_LABEL; | ||
1088 | hiscore.rule++; | ||
1089 | } | ||
1090 | if (ipv6_addr_label(&ifa->addr, | ||
1091 | score.addr_type, | ||
1092 | ifa->idev->dev->ifindex) == daddr_label) { | ||
1093 | score.attrs |= IPV6_SADDR_SCORE_LABEL; | ||
1094 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_LABEL)) { | ||
1095 | score.rule = 6; | ||
1096 | goto record_it; | ||
1097 | } | ||
1098 | } else { | ||
1099 | if (hiscore.attrs & IPV6_SADDR_SCORE_LABEL) | ||
1100 | continue; | ||
1101 | } | ||
1102 | 1155 | ||
1103 | #ifdef CONFIG_IPV6_PRIVACY | 1156 | break; |
1104 | /* Rule 7: Prefer public address | ||
1105 | * Note: prefer temprary address if use_tempaddr >= 2 | ||
1106 | */ | ||
1107 | if (hiscore.rule < 7) { | ||
1108 | if ((!(ifa_result->flags & IFA_F_TEMPORARY)) ^ | ||
1109 | (ifa_result->idev->cnf.use_tempaddr >= 2)) | ||
1110 | hiscore.attrs |= IPV6_SADDR_SCORE_PRIVACY; | ||
1111 | hiscore.rule++; | ||
1112 | } | ||
1113 | if ((!(ifa->flags & IFA_F_TEMPORARY)) ^ | ||
1114 | (ifa->idev->cnf.use_tempaddr >= 2)) { | ||
1115 | score.attrs |= IPV6_SADDR_SCORE_PRIVACY; | ||
1116 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)) { | ||
1117 | score.rule = 7; | ||
1118 | goto record_it; | ||
1119 | } | 1157 | } |
1120 | } else { | ||
1121 | if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY) | ||
1122 | continue; | ||
1123 | } | ||
1124 | #else | ||
1125 | if (hiscore.rule < 7) | ||
1126 | hiscore.rule++; | ||
1127 | #endif | ||
1128 | /* Rule 8: Use longest matching prefix */ | ||
1129 | if (hiscore.rule < 8) { | ||
1130 | hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr); | ||
1131 | hiscore.rule++; | ||
1132 | } | ||
1133 | score.matchlen = ipv6_addr_diff(&ifa->addr, daddr); | ||
1134 | if (score.matchlen > hiscore.matchlen) { | ||
1135 | score.rule = 8; | ||
1136 | goto record_it; | ||
1137 | } | 1158 | } |
1138 | #if 0 | ||
1139 | else if (score.matchlen < hiscore.matchlen) | ||
1140 | continue; | ||
1141 | #endif | ||
1142 | |||
1143 | /* Final Rule: choose first available one */ | ||
1144 | continue; | ||
1145 | record_it: | ||
1146 | if (ifa_result) | ||
1147 | in6_ifa_put(ifa_result); | ||
1148 | in6_ifa_hold(ifa); | ||
1149 | ifa_result = ifa; | ||
1150 | hiscore = score; | ||
1151 | } | 1159 | } |
1160 | try_nextdev: | ||
1152 | read_unlock_bh(&idev->lock); | 1161 | read_unlock_bh(&idev->lock); |
1153 | } | 1162 | } |
1154 | rcu_read_unlock(); | 1163 | rcu_read_unlock(); |
1155 | read_unlock(&dev_base_lock); | 1164 | read_unlock(&dev_base_lock); |
1156 | 1165 | ||
1157 | if (!ifa_result) | 1166 | if (!hiscore->ifa) |
1158 | return -EADDRNOTAVAIL; | 1167 | return -EADDRNOTAVAIL; |
1159 | 1168 | ||
1160 | ipv6_addr_copy(saddr, &ifa_result->addr); | 1169 | ipv6_addr_copy(saddr, &hiscore->ifa->addr); |
1161 | in6_ifa_put(ifa_result); | 1170 | in6_ifa_put(hiscore->ifa); |
1162 | return 0; | 1171 | return 0; |
1163 | } | 1172 | } |
1164 | 1173 | ||
1165 | 1174 | EXPORT_SYMBOL(ipv6_dev_get_saddr); | |
1166 | int ipv6_get_saddr(struct dst_entry *dst, | ||
1167 | struct in6_addr *daddr, struct in6_addr *saddr) | ||
1168 | { | ||
1169 | return ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, daddr, saddr); | ||
1170 | } | ||
1171 | |||
1172 | EXPORT_SYMBOL(ipv6_get_saddr); | ||
1173 | 1175 | ||
1174 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, | 1176 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, |
1175 | unsigned char banned_flags) | 1177 | unsigned char banned_flags) |
@@ -1215,7 +1217,7 @@ int ipv6_chk_addr(struct net *net, struct in6_addr *addr, | |||
1215 | 1217 | ||
1216 | read_lock_bh(&addrconf_hash_lock); | 1218 | read_lock_bh(&addrconf_hash_lock); |
1217 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1219 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { |
1218 | if (ifp->idev->dev->nd_net != net) | 1220 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1219 | continue; | 1221 | continue; |
1220 | if (ipv6_addr_equal(&ifp->addr, addr) && | 1222 | if (ipv6_addr_equal(&ifp->addr, addr) && |
1221 | !(ifp->flags&IFA_F_TENTATIVE)) { | 1223 | !(ifp->flags&IFA_F_TENTATIVE)) { |
@@ -1237,7 +1239,7 @@ int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, | |||
1237 | u8 hash = ipv6_addr_hash(addr); | 1239 | u8 hash = ipv6_addr_hash(addr); |
1238 | 1240 | ||
1239 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1241 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { |
1240 | if (ifp->idev->dev->nd_net != net) | 1242 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1241 | continue; | 1243 | continue; |
1242 | if (ipv6_addr_equal(&ifp->addr, addr)) { | 1244 | if (ipv6_addr_equal(&ifp->addr, addr)) { |
1243 | if (dev == NULL || ifp->idev->dev == dev) | 1245 | if (dev == NULL || ifp->idev->dev == dev) |
@@ -1255,7 +1257,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr, | |||
1255 | 1257 | ||
1256 | read_lock_bh(&addrconf_hash_lock); | 1258 | read_lock_bh(&addrconf_hash_lock); |
1257 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1259 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { |
1258 | if (ifp->idev->dev->nd_net != net) | 1260 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1259 | continue; | 1261 | continue; |
1260 | if (ipv6_addr_equal(&ifp->addr, addr)) { | 1262 | if (ipv6_addr_equal(&ifp->addr, addr)) { |
1261 | if (dev == NULL || ifp->idev->dev == dev || | 1263 | if (dev == NULL || ifp->idev->dev == dev || |
@@ -1557,7 +1559,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
1557 | .fc_expires = expires, | 1559 | .fc_expires = expires, |
1558 | .fc_dst_len = plen, | 1560 | .fc_dst_len = plen, |
1559 | .fc_flags = RTF_UP | flags, | 1561 | .fc_flags = RTF_UP | flags, |
1560 | .fc_nlinfo.nl_net = &init_net, | 1562 | .fc_nlinfo.nl_net = dev_net(dev), |
1561 | }; | 1563 | }; |
1562 | 1564 | ||
1563 | ipv6_addr_copy(&cfg.fc_dst, pfx); | 1565 | ipv6_addr_copy(&cfg.fc_dst, pfx); |
@@ -1584,7 +1586,7 @@ static void addrconf_add_mroute(struct net_device *dev) | |||
1584 | .fc_ifindex = dev->ifindex, | 1586 | .fc_ifindex = dev->ifindex, |
1585 | .fc_dst_len = 8, | 1587 | .fc_dst_len = 8, |
1586 | .fc_flags = RTF_UP, | 1588 | .fc_flags = RTF_UP, |
1587 | .fc_nlinfo.nl_net = &init_net, | 1589 | .fc_nlinfo.nl_net = dev_net(dev), |
1588 | }; | 1590 | }; |
1589 | 1591 | ||
1590 | ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); | 1592 | ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); |
@@ -1601,7 +1603,7 @@ static void sit_route_add(struct net_device *dev) | |||
1601 | .fc_ifindex = dev->ifindex, | 1603 | .fc_ifindex = dev->ifindex, |
1602 | .fc_dst_len = 96, | 1604 | .fc_dst_len = 96, |
1603 | .fc_flags = RTF_UP | RTF_NONEXTHOP, | 1605 | .fc_flags = RTF_UP | RTF_NONEXTHOP, |
1604 | .fc_nlinfo.nl_net = &init_net, | 1606 | .fc_nlinfo.nl_net = dev_net(dev), |
1605 | }; | 1607 | }; |
1606 | 1608 | ||
1607 | /* prefix length - 96 bits "::d.d.d.d" */ | 1609 | /* prefix length - 96 bits "::d.d.d.d" */ |
@@ -1702,7 +1704,8 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1702 | 1704 | ||
1703 | if (pinfo->onlink) { | 1705 | if (pinfo->onlink) { |
1704 | struct rt6_info *rt; | 1706 | struct rt6_info *rt; |
1705 | rt = rt6_lookup(&pinfo->prefix, NULL, dev->ifindex, 1); | 1707 | rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, |
1708 | dev->ifindex, 1); | ||
1706 | 1709 | ||
1707 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { | 1710 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { |
1708 | if (rt->rt6i_flags&RTF_EXPIRES) { | 1711 | if (rt->rt6i_flags&RTF_EXPIRES) { |
@@ -1745,7 +1748,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1745 | 1748 | ||
1746 | ok: | 1749 | ok: |
1747 | 1750 | ||
1748 | ifp = ipv6_get_ifaddr(&init_net, &addr, dev, 1); | 1751 | ifp = ipv6_get_ifaddr(dev_net(dev), &addr, dev, 1); |
1749 | 1752 | ||
1750 | if (ifp == NULL && valid_lft) { | 1753 | if (ifp == NULL && valid_lft) { |
1751 | int max_addresses = in6_dev->cnf.max_addresses; | 1754 | int max_addresses = in6_dev->cnf.max_addresses; |
@@ -1868,7 +1871,7 @@ ok: | |||
1868 | * Special case for SIT interfaces where we create a new "virtual" | 1871 | * Special case for SIT interfaces where we create a new "virtual" |
1869 | * device. | 1872 | * device. |
1870 | */ | 1873 | */ |
1871 | int addrconf_set_dstaddr(void __user *arg) | 1874 | int addrconf_set_dstaddr(struct net *net, void __user *arg) |
1872 | { | 1875 | { |
1873 | struct in6_ifreq ireq; | 1876 | struct in6_ifreq ireq; |
1874 | struct net_device *dev; | 1877 | struct net_device *dev; |
@@ -1880,7 +1883,7 @@ int addrconf_set_dstaddr(void __user *arg) | |||
1880 | if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) | 1883 | if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) |
1881 | goto err_exit; | 1884 | goto err_exit; |
1882 | 1885 | ||
1883 | dev = __dev_get_by_index(&init_net, ireq.ifr6_ifindex); | 1886 | dev = __dev_get_by_index(net, ireq.ifr6_ifindex); |
1884 | 1887 | ||
1885 | err = -ENODEV; | 1888 | err = -ENODEV; |
1886 | if (dev == NULL) | 1889 | if (dev == NULL) |
@@ -1911,7 +1914,8 @@ int addrconf_set_dstaddr(void __user *arg) | |||
1911 | 1914 | ||
1912 | if (err == 0) { | 1915 | if (err == 0) { |
1913 | err = -ENOBUFS; | 1916 | err = -ENOBUFS; |
1914 | if ((dev = __dev_get_by_name(&init_net, p.name)) == NULL) | 1917 | dev = __dev_get_by_name(net, p.name); |
1918 | if (!dev) | ||
1915 | goto err_exit; | 1919 | goto err_exit; |
1916 | err = dev_open(dev); | 1920 | err = dev_open(dev); |
1917 | } | 1921 | } |
@@ -1926,8 +1930,9 @@ err_exit: | |||
1926 | /* | 1930 | /* |
1927 | * Manual configuration of address on an interface | 1931 | * Manual configuration of address on an interface |
1928 | */ | 1932 | */ |
1929 | static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | 1933 | static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, |
1930 | __u8 ifa_flags, __u32 prefered_lft, __u32 valid_lft) | 1934 | int plen, __u8 ifa_flags, __u32 prefered_lft, |
1935 | __u32 valid_lft) | ||
1931 | { | 1936 | { |
1932 | struct inet6_ifaddr *ifp; | 1937 | struct inet6_ifaddr *ifp; |
1933 | struct inet6_dev *idev; | 1938 | struct inet6_dev *idev; |
@@ -1941,7 +1946,8 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | |||
1941 | if (!valid_lft || prefered_lft > valid_lft) | 1946 | if (!valid_lft || prefered_lft > valid_lft) |
1942 | return -EINVAL; | 1947 | return -EINVAL; |
1943 | 1948 | ||
1944 | if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL) | 1949 | dev = __dev_get_by_index(net, ifindex); |
1950 | if (!dev) | ||
1945 | return -ENODEV; | 1951 | return -ENODEV; |
1946 | 1952 | ||
1947 | if ((idev = addrconf_add_dev(dev)) == NULL) | 1953 | if ((idev = addrconf_add_dev(dev)) == NULL) |
@@ -1986,13 +1992,15 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | |||
1986 | return PTR_ERR(ifp); | 1992 | return PTR_ERR(ifp); |
1987 | } | 1993 | } |
1988 | 1994 | ||
1989 | static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) | 1995 | static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, |
1996 | int plen) | ||
1990 | { | 1997 | { |
1991 | struct inet6_ifaddr *ifp; | 1998 | struct inet6_ifaddr *ifp; |
1992 | struct inet6_dev *idev; | 1999 | struct inet6_dev *idev; |
1993 | struct net_device *dev; | 2000 | struct net_device *dev; |
1994 | 2001 | ||
1995 | if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL) | 2002 | dev = __dev_get_by_index(net, ifindex); |
2003 | if (!dev) | ||
1996 | return -ENODEV; | 2004 | return -ENODEV; |
1997 | 2005 | ||
1998 | if ((idev = __in6_dev_get(dev)) == NULL) | 2006 | if ((idev = __in6_dev_get(dev)) == NULL) |
@@ -2020,7 +2028,7 @@ static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) | |||
2020 | } | 2028 | } |
2021 | 2029 | ||
2022 | 2030 | ||
2023 | int addrconf_add_ifaddr(void __user *arg) | 2031 | int addrconf_add_ifaddr(struct net *net, void __user *arg) |
2024 | { | 2032 | { |
2025 | struct in6_ifreq ireq; | 2033 | struct in6_ifreq ireq; |
2026 | int err; | 2034 | int err; |
@@ -2032,13 +2040,14 @@ int addrconf_add_ifaddr(void __user *arg) | |||
2032 | return -EFAULT; | 2040 | return -EFAULT; |
2033 | 2041 | ||
2034 | rtnl_lock(); | 2042 | rtnl_lock(); |
2035 | err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen, | 2043 | err = inet6_addr_add(net, ireq.ifr6_ifindex, &ireq.ifr6_addr, |
2036 | IFA_F_PERMANENT, INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); | 2044 | ireq.ifr6_prefixlen, IFA_F_PERMANENT, |
2045 | INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); | ||
2037 | rtnl_unlock(); | 2046 | rtnl_unlock(); |
2038 | return err; | 2047 | return err; |
2039 | } | 2048 | } |
2040 | 2049 | ||
2041 | int addrconf_del_ifaddr(void __user *arg) | 2050 | int addrconf_del_ifaddr(struct net *net, void __user *arg) |
2042 | { | 2051 | { |
2043 | struct in6_ifreq ireq; | 2052 | struct in6_ifreq ireq; |
2044 | int err; | 2053 | int err; |
@@ -2050,7 +2059,8 @@ int addrconf_del_ifaddr(void __user *arg) | |||
2050 | return -EFAULT; | 2059 | return -EFAULT; |
2051 | 2060 | ||
2052 | rtnl_lock(); | 2061 | rtnl_lock(); |
2053 | err = inet6_addr_del(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen); | 2062 | err = inet6_addr_del(net, ireq.ifr6_ifindex, &ireq.ifr6_addr, |
2063 | ireq.ifr6_prefixlen); | ||
2054 | rtnl_unlock(); | 2064 | rtnl_unlock(); |
2055 | return err; | 2065 | return err; |
2056 | } | 2066 | } |
@@ -2061,6 +2071,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2061 | struct inet6_ifaddr * ifp; | 2071 | struct inet6_ifaddr * ifp; |
2062 | struct in6_addr addr; | 2072 | struct in6_addr addr; |
2063 | struct net_device *dev; | 2073 | struct net_device *dev; |
2074 | struct net *net = dev_net(idev->dev); | ||
2064 | int scope; | 2075 | int scope; |
2065 | 2076 | ||
2066 | ASSERT_RTNL(); | 2077 | ASSERT_RTNL(); |
@@ -2087,7 +2098,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2087 | return; | 2098 | return; |
2088 | } | 2099 | } |
2089 | 2100 | ||
2090 | for_each_netdev(&init_net, dev) { | 2101 | for_each_netdev(net, dev) { |
2091 | struct in_device * in_dev = __in_dev_get_rtnl(dev); | 2102 | struct in_device * in_dev = __in_dev_get_rtnl(dev); |
2092 | if (in_dev && (dev->flags & IFF_UP)) { | 2103 | if (in_dev && (dev->flags & IFF_UP)) { |
2093 | struct in_ifaddr * ifa; | 2104 | struct in_ifaddr * ifa; |
@@ -2250,15 +2261,16 @@ ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) | |||
2250 | static void ip6_tnl_add_linklocal(struct inet6_dev *idev) | 2261 | static void ip6_tnl_add_linklocal(struct inet6_dev *idev) |
2251 | { | 2262 | { |
2252 | struct net_device *link_dev; | 2263 | struct net_device *link_dev; |
2264 | struct net *net = dev_net(idev->dev); | ||
2253 | 2265 | ||
2254 | /* first try to inherit the link-local address from the link device */ | 2266 | /* first try to inherit the link-local address from the link device */ |
2255 | if (idev->dev->iflink && | 2267 | if (idev->dev->iflink && |
2256 | (link_dev = __dev_get_by_index(&init_net, idev->dev->iflink))) { | 2268 | (link_dev = __dev_get_by_index(net, idev->dev->iflink))) { |
2257 | if (!ipv6_inherit_linklocal(idev, link_dev)) | 2269 | if (!ipv6_inherit_linklocal(idev, link_dev)) |
2258 | return; | 2270 | return; |
2259 | } | 2271 | } |
2260 | /* then try to inherit it from any device */ | 2272 | /* then try to inherit it from any device */ |
2261 | for_each_netdev(&init_net, link_dev) { | 2273 | for_each_netdev(net, link_dev) { |
2262 | if (!ipv6_inherit_linklocal(idev, link_dev)) | 2274 | if (!ipv6_inherit_linklocal(idev, link_dev)) |
2263 | return; | 2275 | return; |
2264 | } | 2276 | } |
@@ -2291,9 +2303,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2291 | int run_pending = 0; | 2303 | int run_pending = 0; |
2292 | int err; | 2304 | int err; |
2293 | 2305 | ||
2294 | if (dev->nd_net != &init_net) | ||
2295 | return NOTIFY_DONE; | ||
2296 | |||
2297 | switch(event) { | 2306 | switch(event) { |
2298 | case NETDEV_REGISTER: | 2307 | case NETDEV_REGISTER: |
2299 | if (!idev && dev->mtu >= IPV6_MIN_MTU) { | 2308 | if (!idev && dev->mtu >= IPV6_MIN_MTU) { |
@@ -2433,6 +2442,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2433 | { | 2442 | { |
2434 | struct inet6_dev *idev; | 2443 | struct inet6_dev *idev; |
2435 | struct inet6_ifaddr *ifa, **bifa; | 2444 | struct inet6_ifaddr *ifa, **bifa; |
2445 | struct net *net = dev_net(dev); | ||
2436 | int i; | 2446 | int i; |
2437 | 2447 | ||
2438 | ASSERT_RTNL(); | 2448 | ASSERT_RTNL(); |
@@ -2440,7 +2450,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2440 | if (dev == init_net.loopback_dev && how == 1) | 2450 | if (dev == init_net.loopback_dev && how == 1) |
2441 | how = 0; | 2451 | how = 0; |
2442 | 2452 | ||
2443 | rt6_ifdown(dev); | 2453 | rt6_ifdown(net, dev); |
2444 | neigh_ifdown(&nd_tbl, dev); | 2454 | neigh_ifdown(&nd_tbl, dev); |
2445 | 2455 | ||
2446 | idev = __in6_dev_get(dev); | 2456 | idev = __in6_dev_get(dev); |
@@ -2756,12 +2766,12 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq) | |||
2756 | { | 2766 | { |
2757 | struct inet6_ifaddr *ifa = NULL; | 2767 | struct inet6_ifaddr *ifa = NULL; |
2758 | struct if6_iter_state *state = seq->private; | 2768 | struct if6_iter_state *state = seq->private; |
2759 | struct net *net = state->p.net; | 2769 | struct net *net = seq_file_net(seq); |
2760 | 2770 | ||
2761 | for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { | 2771 | for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { |
2762 | ifa = inet6_addr_lst[state->bucket]; | 2772 | ifa = inet6_addr_lst[state->bucket]; |
2763 | 2773 | ||
2764 | while (ifa && ifa->idev->dev->nd_net != net) | 2774 | while (ifa && !net_eq(dev_net(ifa->idev->dev), net)) |
2765 | ifa = ifa->lst_next; | 2775 | ifa = ifa->lst_next; |
2766 | if (ifa) | 2776 | if (ifa) |
2767 | break; | 2777 | break; |
@@ -2772,12 +2782,12 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq) | |||
2772 | static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa) | 2782 | static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa) |
2773 | { | 2783 | { |
2774 | struct if6_iter_state *state = seq->private; | 2784 | struct if6_iter_state *state = seq->private; |
2775 | struct net *net = state->p.net; | 2785 | struct net *net = seq_file_net(seq); |
2776 | 2786 | ||
2777 | ifa = ifa->lst_next; | 2787 | ifa = ifa->lst_next; |
2778 | try_again: | 2788 | try_again: |
2779 | if (ifa) { | 2789 | if (ifa) { |
2780 | if (ifa->idev->dev->nd_net != net) { | 2790 | if (!net_eq(dev_net(ifa->idev->dev), net)) { |
2781 | ifa = ifa->lst_next; | 2791 | ifa = ifa->lst_next; |
2782 | goto try_again; | 2792 | goto try_again; |
2783 | } | 2793 | } |
@@ -2895,7 +2905,7 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) | |||
2895 | u8 hash = ipv6_addr_hash(addr); | 2905 | u8 hash = ipv6_addr_hash(addr); |
2896 | read_lock_bh(&addrconf_hash_lock); | 2906 | read_lock_bh(&addrconf_hash_lock); |
2897 | for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) { | 2907 | for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) { |
2898 | if (ifp->idev->dev->nd_net != net) | 2908 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
2899 | continue; | 2909 | continue; |
2900 | if (ipv6_addr_cmp(&ifp->addr, addr) == 0 && | 2910 | if (ipv6_addr_cmp(&ifp->addr, addr) == 0 && |
2901 | (ifp->flags & IFA_F_HOMEADDRESS)) { | 2911 | (ifp->flags & IFA_F_HOMEADDRESS)) { |
@@ -3044,15 +3054,12 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { | |||
3044 | static int | 3054 | static int |
3045 | inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 3055 | inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
3046 | { | 3056 | { |
3047 | struct net *net = skb->sk->sk_net; | 3057 | struct net *net = sock_net(skb->sk); |
3048 | struct ifaddrmsg *ifm; | 3058 | struct ifaddrmsg *ifm; |
3049 | struct nlattr *tb[IFA_MAX+1]; | 3059 | struct nlattr *tb[IFA_MAX+1]; |
3050 | struct in6_addr *pfx; | 3060 | struct in6_addr *pfx; |
3051 | int err; | 3061 | int err; |
3052 | 3062 | ||
3053 | if (net != &init_net) | ||
3054 | return -EINVAL; | ||
3055 | |||
3056 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3063 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3057 | if (err < 0) | 3064 | if (err < 0) |
3058 | return err; | 3065 | return err; |
@@ -3062,7 +3069,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3062 | if (pfx == NULL) | 3069 | if (pfx == NULL) |
3063 | return -EINVAL; | 3070 | return -EINVAL; |
3064 | 3071 | ||
3065 | return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen); | 3072 | return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); |
3066 | } | 3073 | } |
3067 | 3074 | ||
3068 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | 3075 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, |
@@ -3105,7 +3112,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | |||
3105 | static int | 3112 | static int |
3106 | inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 3113 | inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
3107 | { | 3114 | { |
3108 | struct net *net = skb->sk->sk_net; | 3115 | struct net *net = sock_net(skb->sk); |
3109 | struct ifaddrmsg *ifm; | 3116 | struct ifaddrmsg *ifm; |
3110 | struct nlattr *tb[IFA_MAX+1]; | 3117 | struct nlattr *tb[IFA_MAX+1]; |
3111 | struct in6_addr *pfx; | 3118 | struct in6_addr *pfx; |
@@ -3115,9 +3122,6 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3115 | u8 ifa_flags; | 3122 | u8 ifa_flags; |
3116 | int err; | 3123 | int err; |
3117 | 3124 | ||
3118 | if (net != &init_net) | ||
3119 | return -EINVAL; | ||
3120 | |||
3121 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3125 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3122 | if (err < 0) | 3126 | if (err < 0) |
3123 | return err; | 3127 | return err; |
@@ -3138,7 +3142,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3138 | valid_lft = INFINITY_LIFE_TIME; | 3142 | valid_lft = INFINITY_LIFE_TIME; |
3139 | } | 3143 | } |
3140 | 3144 | ||
3141 | dev = __dev_get_by_index(&init_net, ifm->ifa_index); | 3145 | dev = __dev_get_by_index(net, ifm->ifa_index); |
3142 | if (dev == NULL) | 3146 | if (dev == NULL) |
3143 | return -ENODEV; | 3147 | return -ENODEV; |
3144 | 3148 | ||
@@ -3151,8 +3155,9 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3151 | * It would be best to check for !NLM_F_CREATE here but | 3155 | * It would be best to check for !NLM_F_CREATE here but |
3152 | * userspace alreay relies on not having to provide this. | 3156 | * userspace alreay relies on not having to provide this. |
3153 | */ | 3157 | */ |
3154 | return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, | 3158 | return inet6_addr_add(net, ifm->ifa_index, pfx, |
3155 | ifa_flags, preferred_lft, valid_lft); | 3159 | ifm->ifa_prefixlen, ifa_flags, |
3160 | preferred_lft, valid_lft); | ||
3156 | } | 3161 | } |
3157 | 3162 | ||
3158 | if (nlh->nlmsg_flags & NLM_F_EXCL || | 3163 | if (nlh->nlmsg_flags & NLM_F_EXCL || |
@@ -3317,12 +3322,13 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
3317 | struct inet6_ifaddr *ifa; | 3322 | struct inet6_ifaddr *ifa; |
3318 | struct ifmcaddr6 *ifmca; | 3323 | struct ifmcaddr6 *ifmca; |
3319 | struct ifacaddr6 *ifaca; | 3324 | struct ifacaddr6 *ifaca; |
3325 | struct net *net = sock_net(skb->sk); | ||
3320 | 3326 | ||
3321 | s_idx = cb->args[0]; | 3327 | s_idx = cb->args[0]; |
3322 | s_ip_idx = ip_idx = cb->args[1]; | 3328 | s_ip_idx = ip_idx = cb->args[1]; |
3323 | 3329 | ||
3324 | idx = 0; | 3330 | idx = 0; |
3325 | for_each_netdev(&init_net, dev) { | 3331 | for_each_netdev(net, dev) { |
3326 | if (idx < s_idx) | 3332 | if (idx < s_idx) |
3327 | goto cont; | 3333 | goto cont; |
3328 | if (idx > s_idx) | 3334 | if (idx > s_idx) |
@@ -3389,42 +3395,30 @@ cont: | |||
3389 | 3395 | ||
3390 | static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3396 | static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3391 | { | 3397 | { |
3392 | struct net *net = skb->sk->sk_net; | ||
3393 | enum addr_type_t type = UNICAST_ADDR; | 3398 | enum addr_type_t type = UNICAST_ADDR; |
3394 | 3399 | ||
3395 | if (net != &init_net) | ||
3396 | return 0; | ||
3397 | |||
3398 | return inet6_dump_addr(skb, cb, type); | 3400 | return inet6_dump_addr(skb, cb, type); |
3399 | } | 3401 | } |
3400 | 3402 | ||
3401 | static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3403 | static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3402 | { | 3404 | { |
3403 | struct net *net = skb->sk->sk_net; | ||
3404 | enum addr_type_t type = MULTICAST_ADDR; | 3405 | enum addr_type_t type = MULTICAST_ADDR; |
3405 | 3406 | ||
3406 | if (net != &init_net) | ||
3407 | return 0; | ||
3408 | |||
3409 | return inet6_dump_addr(skb, cb, type); | 3407 | return inet6_dump_addr(skb, cb, type); |
3410 | } | 3408 | } |
3411 | 3409 | ||
3412 | 3410 | ||
3413 | static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) | 3411 | static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) |
3414 | { | 3412 | { |
3415 | struct net *net = skb->sk->sk_net; | ||
3416 | enum addr_type_t type = ANYCAST_ADDR; | 3413 | enum addr_type_t type = ANYCAST_ADDR; |
3417 | 3414 | ||
3418 | if (net != &init_net) | ||
3419 | return 0; | ||
3420 | |||
3421 | return inet6_dump_addr(skb, cb, type); | 3415 | return inet6_dump_addr(skb, cb, type); |
3422 | } | 3416 | } |
3423 | 3417 | ||
3424 | static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | 3418 | static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, |
3425 | void *arg) | 3419 | void *arg) |
3426 | { | 3420 | { |
3427 | struct net *net = in_skb->sk->sk_net; | 3421 | struct net *net = sock_net(in_skb->sk); |
3428 | struct ifaddrmsg *ifm; | 3422 | struct ifaddrmsg *ifm; |
3429 | struct nlattr *tb[IFA_MAX+1]; | 3423 | struct nlattr *tb[IFA_MAX+1]; |
3430 | struct in6_addr *addr = NULL; | 3424 | struct in6_addr *addr = NULL; |
@@ -3433,9 +3427,6 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3433 | struct sk_buff *skb; | 3427 | struct sk_buff *skb; |
3434 | int err; | 3428 | int err; |
3435 | 3429 | ||
3436 | if (net != &init_net) | ||
3437 | return -EINVAL; | ||
3438 | |||
3439 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3430 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3440 | if (err < 0) | 3431 | if (err < 0) |
3441 | goto errout; | 3432 | goto errout; |
@@ -3448,7 +3439,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3448 | 3439 | ||
3449 | ifm = nlmsg_data(nlh); | 3440 | ifm = nlmsg_data(nlh); |
3450 | if (ifm->ifa_index) | 3441 | if (ifm->ifa_index) |
3451 | dev = __dev_get_by_index(&init_net, ifm->ifa_index); | 3442 | dev = __dev_get_by_index(net, ifm->ifa_index); |
3452 | 3443 | ||
3453 | if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) { | 3444 | if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) { |
3454 | err = -EADDRNOTAVAIL; | 3445 | err = -EADDRNOTAVAIL; |
@@ -3468,7 +3459,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3468 | kfree_skb(skb); | 3459 | kfree_skb(skb); |
3469 | goto errout_ifa; | 3460 | goto errout_ifa; |
3470 | } | 3461 | } |
3471 | err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); | 3462 | err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); |
3472 | errout_ifa: | 3463 | errout_ifa: |
3473 | in6_ifa_put(ifa); | 3464 | in6_ifa_put(ifa); |
3474 | errout: | 3465 | errout: |
@@ -3478,6 +3469,7 @@ errout: | |||
3478 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | 3469 | static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) |
3479 | { | 3470 | { |
3480 | struct sk_buff *skb; | 3471 | struct sk_buff *skb; |
3472 | struct net *net = dev_net(ifa->idev->dev); | ||
3481 | int err = -ENOBUFS; | 3473 | int err = -ENOBUFS; |
3482 | 3474 | ||
3483 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); | 3475 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); |
@@ -3491,10 +3483,10 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | |||
3491 | kfree_skb(skb); | 3483 | kfree_skb(skb); |
3492 | goto errout; | 3484 | goto errout; |
3493 | } | 3485 | } |
3494 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 3486 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); |
3495 | errout: | 3487 | errout: |
3496 | if (err < 0) | 3488 | if (err < 0) |
3497 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err); | 3489 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); |
3498 | } | 3490 | } |
3499 | 3491 | ||
3500 | static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | 3492 | static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, |
@@ -3653,18 +3645,15 @@ nla_put_failure: | |||
3653 | 3645 | ||
3654 | static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | 3646 | static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) |
3655 | { | 3647 | { |
3656 | struct net *net = skb->sk->sk_net; | 3648 | struct net *net = sock_net(skb->sk); |
3657 | int idx, err; | 3649 | int idx, err; |
3658 | int s_idx = cb->args[0]; | 3650 | int s_idx = cb->args[0]; |
3659 | struct net_device *dev; | 3651 | struct net_device *dev; |
3660 | struct inet6_dev *idev; | 3652 | struct inet6_dev *idev; |
3661 | 3653 | ||
3662 | if (net != &init_net) | ||
3663 | return 0; | ||
3664 | |||
3665 | read_lock(&dev_base_lock); | 3654 | read_lock(&dev_base_lock); |
3666 | idx = 0; | 3655 | idx = 0; |
3667 | for_each_netdev(&init_net, dev) { | 3656 | for_each_netdev(net, dev) { |
3668 | if (idx < s_idx) | 3657 | if (idx < s_idx) |
3669 | goto cont; | 3658 | goto cont; |
3670 | if ((idev = in6_dev_get(dev)) == NULL) | 3659 | if ((idev = in6_dev_get(dev)) == NULL) |
@@ -3686,6 +3675,7 @@ cont: | |||
3686 | void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | 3675 | void inet6_ifinfo_notify(int event, struct inet6_dev *idev) |
3687 | { | 3676 | { |
3688 | struct sk_buff *skb; | 3677 | struct sk_buff *skb; |
3678 | struct net *net = dev_net(idev->dev); | ||
3689 | int err = -ENOBUFS; | 3679 | int err = -ENOBUFS; |
3690 | 3680 | ||
3691 | skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC); | 3681 | skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC); |
@@ -3699,10 +3689,10 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | |||
3699 | kfree_skb(skb); | 3689 | kfree_skb(skb); |
3700 | goto errout; | 3690 | goto errout; |
3701 | } | 3691 | } |
3702 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 3692 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); |
3703 | errout: | 3693 | errout: |
3704 | if (err < 0) | 3694 | if (err < 0) |
3705 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err); | 3695 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); |
3706 | } | 3696 | } |
3707 | 3697 | ||
3708 | static inline size_t inet6_prefix_nlmsg_size(void) | 3698 | static inline size_t inet6_prefix_nlmsg_size(void) |
@@ -3755,6 +3745,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3755 | struct prefix_info *pinfo) | 3745 | struct prefix_info *pinfo) |
3756 | { | 3746 | { |
3757 | struct sk_buff *skb; | 3747 | struct sk_buff *skb; |
3748 | struct net *net = dev_net(idev->dev); | ||
3758 | int err = -ENOBUFS; | 3749 | int err = -ENOBUFS; |
3759 | 3750 | ||
3760 | skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC); | 3751 | skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC); |
@@ -3768,10 +3759,10 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3768 | kfree_skb(skb); | 3759 | kfree_skb(skb); |
3769 | goto errout; | 3760 | goto errout; |
3770 | } | 3761 | } |
3771 | err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); | 3762 | err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); |
3772 | errout: | 3763 | errout: |
3773 | if (err < 0) | 3764 | if (err < 0) |
3774 | rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_PREFIX, err); | 3765 | rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err); |
3775 | } | 3766 | } |
3776 | 3767 | ||
3777 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | 3768 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) |
@@ -4166,7 +4157,7 @@ static void addrconf_sysctl_register(struct inet6_dev *idev) | |||
4166 | NET_IPV6_NEIGH, "ipv6", | 4157 | NET_IPV6_NEIGH, "ipv6", |
4167 | &ndisc_ifinfo_sysctl_change, | 4158 | &ndisc_ifinfo_sysctl_change, |
4168 | NULL); | 4159 | NULL); |
4169 | __addrconf_sysctl_register(idev->dev->nd_net, idev->dev->name, | 4160 | __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, |
4170 | idev->dev->ifindex, idev, &idev->cnf); | 4161 | idev->dev->ifindex, idev, &idev->cnf); |
4171 | } | 4162 | } |
4172 | 4163 | ||
@@ -4261,6 +4252,32 @@ int unregister_inet6addr_notifier(struct notifier_block *nb) | |||
4261 | 4252 | ||
4262 | EXPORT_SYMBOL(unregister_inet6addr_notifier); | 4253 | EXPORT_SYMBOL(unregister_inet6addr_notifier); |
4263 | 4254 | ||
4255 | |||
4256 | static int addrconf_net_init(struct net *net) | ||
4257 | { | ||
4258 | return 0; | ||
4259 | } | ||
4260 | |||
4261 | static void addrconf_net_exit(struct net *net) | ||
4262 | { | ||
4263 | struct net_device *dev; | ||
4264 | |||
4265 | rtnl_lock(); | ||
4266 | /* clean dev list */ | ||
4267 | for_each_netdev(net, dev) { | ||
4268 | if (__in6_dev_get(dev) == NULL) | ||
4269 | continue; | ||
4270 | addrconf_ifdown(dev, 1); | ||
4271 | } | ||
4272 | addrconf_ifdown(net->loopback_dev, 2); | ||
4273 | rtnl_unlock(); | ||
4274 | } | ||
4275 | |||
4276 | static struct pernet_operations addrconf_net_ops = { | ||
4277 | .init = addrconf_net_init, | ||
4278 | .exit = addrconf_net_exit, | ||
4279 | }; | ||
4280 | |||
4264 | /* | 4281 | /* |
4265 | * Init / cleanup code | 4282 | * Init / cleanup code |
4266 | */ | 4283 | */ |
@@ -4302,14 +4319,9 @@ int __init addrconf_init(void) | |||
4302 | if (err) | 4319 | if (err) |
4303 | goto errlo; | 4320 | goto errlo; |
4304 | 4321 | ||
4305 | ip6_null_entry.u.dst.dev = init_net.loopback_dev; | 4322 | err = register_pernet_device(&addrconf_net_ops); |
4306 | ip6_null_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); | 4323 | if (err) |
4307 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 4324 | return err; |
4308 | ip6_prohibit_entry.u.dst.dev = init_net.loopback_dev; | ||
4309 | ip6_prohibit_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); | ||
4310 | ip6_blk_hole_entry.u.dst.dev = init_net.loopback_dev; | ||
4311 | ip6_blk_hole_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); | ||
4312 | #endif | ||
4313 | 4325 | ||
4314 | register_netdevice_notifier(&ipv6_dev_notf); | 4326 | register_netdevice_notifier(&ipv6_dev_notf); |
4315 | 4327 | ||
@@ -4339,31 +4351,19 @@ errlo: | |||
4339 | 4351 | ||
4340 | void addrconf_cleanup(void) | 4352 | void addrconf_cleanup(void) |
4341 | { | 4353 | { |
4342 | struct net_device *dev; | ||
4343 | struct inet6_ifaddr *ifa; | 4354 | struct inet6_ifaddr *ifa; |
4344 | int i; | 4355 | int i; |
4345 | 4356 | ||
4346 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4357 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4358 | unregister_pernet_device(&addrconf_net_ops); | ||
4347 | 4359 | ||
4348 | unregister_pernet_subsys(&addrconf_ops); | 4360 | unregister_pernet_subsys(&addrconf_ops); |
4349 | 4361 | ||
4350 | rtnl_lock(); | 4362 | rtnl_lock(); |
4351 | 4363 | ||
4352 | /* | 4364 | /* |
4353 | * clean dev list. | ||
4354 | */ | ||
4355 | |||
4356 | for_each_netdev(&init_net, dev) { | ||
4357 | if (__in6_dev_get(dev) == NULL) | ||
4358 | continue; | ||
4359 | addrconf_ifdown(dev, 1); | ||
4360 | } | ||
4361 | addrconf_ifdown(init_net.loopback_dev, 2); | ||
4362 | |||
4363 | /* | ||
4364 | * Check hash table. | 4365 | * Check hash table. |
4365 | */ | 4366 | */ |
4366 | |||
4367 | write_lock_bh(&addrconf_hash_lock); | 4367 | write_lock_bh(&addrconf_hash_lock); |
4368 | for (i=0; i < IN6_ADDR_HSIZE; i++) { | 4368 | for (i=0; i < IN6_ADDR_HSIZE; i++) { |
4369 | for (ifa=inet6_addr_lst[i]; ifa; ) { | 4369 | for (ifa=inet6_addr_lst[i]; ifa; ) { |
@@ -4380,6 +4380,7 @@ void addrconf_cleanup(void) | |||
4380 | write_unlock_bh(&addrconf_hash_lock); | 4380 | write_unlock_bh(&addrconf_hash_lock); |
4381 | 4381 | ||
4382 | del_timer(&addr_chk_timer); | 4382 | del_timer(&addr_chk_timer); |
4383 | |||
4384 | rtnl_unlock(); | 4383 | rtnl_unlock(); |
4384 | |||
4385 | unregister_pernet_subsys(&addrconf_net_ops); | ||
4385 | } | 4386 | } |