aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c434
1 files changed, 287 insertions, 147 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 2c5f57299d63..ddcf7754eec2 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -35,6 +35,9 @@
35 * YOSHIFUJI Hideaki @USAGI : ARCnet support 35 * YOSHIFUJI Hideaki @USAGI : ARCnet support
36 * YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to 36 * YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to
37 * seq_file. 37 * seq_file.
38 * YOSHIFUJI Hideaki @USAGI : improved source address
39 * selection; consider scope,
40 * status etc.
38 */ 41 */
39 42
40#include <linux/config.h> 43#include <linux/config.h>
@@ -193,46 +196,51 @@ const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
193#endif 196#endif
194const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; 197const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
195 198
196int ipv6_addr_type(const struct in6_addr *addr) 199#define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16)
200
201static inline unsigned ipv6_addr_scope2type(unsigned scope)
202{
203 switch(scope) {
204 case IPV6_ADDR_SCOPE_NODELOCAL:
205 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) |
206 IPV6_ADDR_LOOPBACK);
207 case IPV6_ADDR_SCOPE_LINKLOCAL:
208 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL) |
209 IPV6_ADDR_LINKLOCAL);
210 case IPV6_ADDR_SCOPE_SITELOCAL:
211 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL) |
212 IPV6_ADDR_SITELOCAL);
213 }
214 return IPV6_ADDR_SCOPE_TYPE(scope);
215}
216
217int __ipv6_addr_type(const struct in6_addr *addr)
197{ 218{
198 int type;
199 u32 st; 219 u32 st;
200 220
201 st = addr->s6_addr32[0]; 221 st = addr->s6_addr32[0];
202 222
203 if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
204 type = IPV6_ADDR_MULTICAST;
205
206 switch((st & htonl(0x00FF0000))) {
207 case __constant_htonl(0x00010000):
208 type |= IPV6_ADDR_LOOPBACK;
209 break;
210
211 case __constant_htonl(0x00020000):
212 type |= IPV6_ADDR_LINKLOCAL;
213 break;
214
215 case __constant_htonl(0x00050000):
216 type |= IPV6_ADDR_SITELOCAL;
217 break;
218 };
219 return type;
220 }
221
222 type = IPV6_ADDR_UNICAST;
223
224 /* Consider all addresses with the first three bits different of 223 /* Consider all addresses with the first three bits different of
225 000 and 111 as finished. 224 000 and 111 as unicasts.
226 */ 225 */
227 if ((st & htonl(0xE0000000)) != htonl(0x00000000) && 226 if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
228 (st & htonl(0xE0000000)) != htonl(0xE0000000)) 227 (st & htonl(0xE0000000)) != htonl(0xE0000000))
229 return type; 228 return (IPV6_ADDR_UNICAST |
230 229 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));
231 if ((st & htonl(0xFFC00000)) == htonl(0xFE800000)) 230
232 return (IPV6_ADDR_LINKLOCAL | type); 231 if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
232 /* multicast */
233 /* addr-select 3.1 */
234 return (IPV6_ADDR_MULTICAST |
235 ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr)));
236 }
233 237
238 if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
239 return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST |
240 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.1 */
234 if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000)) 241 if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
235 return (IPV6_ADDR_SITELOCAL | type); 242 return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST |
243 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL)); /* addr-select 3.1 */
236 244
237 if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) { 245 if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
238 if (addr->s6_addr32[2] == 0) { 246 if (addr->s6_addr32[2] == 0) {
@@ -240,24 +248,20 @@ int ipv6_addr_type(const struct in6_addr *addr)
240 return IPV6_ADDR_ANY; 248 return IPV6_ADDR_ANY;
241 249
242 if (addr->s6_addr32[3] == htonl(0x00000001)) 250 if (addr->s6_addr32[3] == htonl(0x00000001))
243 return (IPV6_ADDR_LOOPBACK | type); 251 return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |
252 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.4 */
244 253
245 return (IPV6_ADDR_COMPATv4 | type); 254 return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST |
255 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
246 } 256 }
247 257
248 if (addr->s6_addr32[2] == htonl(0x0000ffff)) 258 if (addr->s6_addr32[2] == htonl(0x0000ffff))
249 return IPV6_ADDR_MAPPED; 259 return (IPV6_ADDR_MAPPED |
260 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
250 } 261 }
251 262
252 st &= htonl(0xFF000000); 263 return (IPV6_ADDR_RESERVED |
253 if (st == 0) 264 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.4 */
254 return IPV6_ADDR_RESERVED;
255 st &= htonl(0xFE000000);
256 if (st == htonl(0x02000000))
257 return IPV6_ADDR_RESERVED; /* for NSAP */
258 if (st == htonl(0x04000000))
259 return IPV6_ADDR_RESERVED; /* for IPX */
260 return type;
261} 265}
262 266
263static void addrconf_del_timer(struct inet6_ifaddr *ifp) 267static void addrconf_del_timer(struct inet6_ifaddr *ifp)
@@ -805,138 +809,275 @@ out:
805#endif 809#endif
806 810
807/* 811/*
808 * Choose an appropriate source address 812 * Choose an appropriate source address (RFC3484)
809 * should do:
810 * i) get an address with an appropriate scope
811 * ii) see if there is a specific route for the destination and use
812 * an address of the attached interface
813 * iii) don't use deprecated addresses
814 */ 813 */
815static int inline ipv6_saddr_pref(const struct inet6_ifaddr *ifp, u8 invpref) 814struct ipv6_saddr_score {
815 int addr_type;
816 unsigned int attrs;
817 int matchlen;
818 unsigned int scope;
819 unsigned int rule;
820};
821
822#define IPV6_SADDR_SCORE_LOCAL 0x0001
823#define IPV6_SADDR_SCORE_PREFERRED 0x0004
824#define IPV6_SADDR_SCORE_HOA 0x0008
825#define IPV6_SADDR_SCORE_OIF 0x0010
826#define IPV6_SADDR_SCORE_LABEL 0x0020
827#define IPV6_SADDR_SCORE_PRIVACY 0x0040
828
829static int inline ipv6_saddr_preferred(int type)
816{ 830{
817 int pref; 831 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
818 pref = ifp->flags&IFA_F_DEPRECATED ? 0 : 2; 832 IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
819#ifdef CONFIG_IPV6_PRIVACY 833 return 1;
820 pref |= (ifp->flags^invpref)&IFA_F_TEMPORARY ? 0 : 1; 834 return 0;
821#endif
822 return pref;
823} 835}
824 836
825#ifdef CONFIG_IPV6_PRIVACY 837/* static matching label */
826#define IPV6_GET_SADDR_MAXSCORE(score) ((score) == 3) 838static int inline ipv6_saddr_label(const struct in6_addr *addr, int type)
827#else 839{
828#define IPV6_GET_SADDR_MAXSCORE(score) (score) 840 /*
829#endif 841 * prefix (longest match) label
842 * -----------------------------
843 * ::1/128 0
844 * ::/0 1
845 * 2002::/16 2
846 * ::/96 3
847 * ::ffff:0:0/96 4
848 */
849 if (type & IPV6_ADDR_LOOPBACK)
850 return 0;
851 else if (type & IPV6_ADDR_COMPATv4)
852 return 3;
853 else if (type & IPV6_ADDR_MAPPED)
854 return 4;
855 else if (addr->s6_addr16[0] == htons(0x2002))
856 return 2;
857 return 1;
858}
830 859
831int ipv6_dev_get_saddr(struct net_device *dev, 860int ipv6_dev_get_saddr(struct net_device *daddr_dev,
832 struct in6_addr *daddr, struct in6_addr *saddr) 861 struct in6_addr *daddr, struct in6_addr *saddr)
833{ 862{
834 struct inet6_ifaddr *ifp = NULL; 863 struct ipv6_saddr_score hiscore;
835 struct inet6_ifaddr *match = NULL; 864 struct inet6_ifaddr *ifa_result = NULL;
836 struct inet6_dev *idev; 865 int daddr_type = __ipv6_addr_type(daddr);
837 int scope; 866 int daddr_scope = __ipv6_addr_src_scope(daddr_type);
838 int err; 867 u32 daddr_label = ipv6_saddr_label(daddr, daddr_type);
839 int hiscore = -1, score; 868 struct net_device *dev;
840 869
841 scope = ipv6_addr_scope(daddr); 870 memset(&hiscore, 0, sizeof(hiscore));
842 871
843 /* 872 read_lock(&dev_base_lock);
844 * known dev 873 read_lock(&addrconf_lock);
845 * search dev and walk through dev addresses
846 */
847 874
848 if (dev) { 875 for (dev = dev_base; dev; dev=dev->next) {
849 if (dev->flags & IFF_LOOPBACK) 876 struct inet6_dev *idev;
850 scope = IFA_HOST; 877 struct inet6_ifaddr *ifa;
878
879 /* Rule 0: Candidate Source Address (section 4)
880 * - multicast and link-local destination address,
881 * the set of candidate source address MUST only
882 * include addresses assigned to interfaces
883 * belonging to the same link as the outgoing
884 * interface.
885 * (- For site-local destination addresses, the
886 * set of candidate source addresses MUST only
887 * include addresses assigned to interfaces
888 * belonging to the same site as the outgoing
889 * interface.)
890 */
891 if ((daddr_type & IPV6_ADDR_MULTICAST ||
892 daddr_scope <= IPV6_ADDR_SCOPE_LINKLOCAL) &&
893 daddr_dev && dev != daddr_dev)
894 continue;
851 895
852 read_lock(&addrconf_lock);
853 idev = __in6_dev_get(dev); 896 idev = __in6_dev_get(dev);
854 if (idev) { 897 if (!idev)
855 read_lock_bh(&idev->lock); 898 continue;
856 for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
857 if (ifp->scope == scope) {
858 if (ifp->flags&IFA_F_TENTATIVE)
859 continue;
860#ifdef CONFIG_IPV6_PRIVACY
861 score = ipv6_saddr_pref(ifp, idev->cnf.use_tempaddr > 1 ? IFA_F_TEMPORARY : 0);
862#else
863 score = ipv6_saddr_pref(ifp, 0);
864#endif
865 if (score <= hiscore)
866 continue;
867 899
868 if (match) 900 read_lock_bh(&idev->lock);
869 in6_ifa_put(match); 901 for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) {
870 match = ifp; 902 struct ipv6_saddr_score score;
871 hiscore = score;
872 in6_ifa_hold(ifp);
873 903
874 if (IPV6_GET_SADDR_MAXSCORE(score)) { 904 score.addr_type = __ipv6_addr_type(&ifa->addr);
875 read_unlock_bh(&idev->lock); 905
876 read_unlock(&addrconf_lock); 906 /* Rule 0: Candidate Source Address (section 4)
877 goto out; 907 * - In any case, anycast addresses, multicast
878 } 908 * addresses, and the unspecified address MUST
909 * NOT be included in a candidate set.
910 */
911 if (unlikely(score.addr_type == IPV6_ADDR_ANY ||
912 score.addr_type & IPV6_ADDR_MULTICAST)) {
913 LIMIT_NETDEBUG(KERN_DEBUG
914 "ADDRCONF: unspecified / multicast address"
915 "assigned as unicast address on %s",
916 dev->name);
917 continue;
918 }
919
920 score.attrs = 0;
921 score.matchlen = 0;
922 score.scope = 0;
923 score.rule = 0;
924
925 if (ifa_result == NULL) {
926 /* record it if the first available entry */
927 goto record_it;
928 }
929
930 /* Rule 1: Prefer same address */
931 if (hiscore.rule < 1) {
932 if (ipv6_addr_equal(&ifa_result->addr, daddr))
933 hiscore.attrs |= IPV6_SADDR_SCORE_LOCAL;
934 hiscore.rule++;
935 }
936 if (ipv6_addr_equal(&ifa->addr, daddr)) {
937 score.attrs |= IPV6_SADDR_SCORE_LOCAL;
938 if (!(hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)) {
939 score.rule = 1;
940 goto record_it;
879 } 941 }
942 } else {
943 if (hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)
944 continue;
880 } 945 }
881 read_unlock_bh(&idev->lock);
882 }
883 read_unlock(&addrconf_lock);
884 }
885 946
886 if (scope == IFA_LINK) 947 /* Rule 2: Prefer appropriate scope */
887 goto out; 948 if (hiscore.rule < 2) {
949 hiscore.scope = __ipv6_addr_src_scope(hiscore.addr_type);
950 hiscore.rule++;
951 }
952 score.scope = __ipv6_addr_src_scope(score.addr_type);
953 if (hiscore.scope < score.scope) {
954 if (hiscore.scope < daddr_scope) {
955 score.rule = 2;
956 goto record_it;
957 } else
958 continue;
959 } else if (score.scope < hiscore.scope) {
960 if (score.scope < daddr_scope)
961 continue;
962 else {
963 score.rule = 2;
964 goto record_it;
965 }
966 }
888 967
889 /* 968 /* Rule 3: Avoid deprecated address */
890 * dev == NULL or search failed for specified dev 969 if (hiscore.rule < 3) {
891 */ 970 if (ipv6_saddr_preferred(hiscore.addr_type) ||
971 !(ifa_result->flags & IFA_F_DEPRECATED))
972 hiscore.attrs |= IPV6_SADDR_SCORE_PREFERRED;
973 hiscore.rule++;
974 }
975 if (ipv6_saddr_preferred(score.addr_type) ||
976 !(ifa->flags & IFA_F_DEPRECATED)) {
977 score.attrs |= IPV6_SADDR_SCORE_PREFERRED;
978 if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) {
979 score.rule = 3;
980 goto record_it;
981 }
982 } else {
983 if (hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)
984 continue;
985 }
892 986
893 read_lock(&dev_base_lock); 987 /* Rule 4: Prefer home address -- not implemented yet */
894 read_lock(&addrconf_lock);
895 for (dev = dev_base; dev; dev=dev->next) {
896 idev = __in6_dev_get(dev);
897 if (idev) {
898 read_lock_bh(&idev->lock);
899 for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
900 if (ifp->scope == scope) {
901 if (ifp->flags&IFA_F_TENTATIVE)
902 continue;
903#ifdef CONFIG_IPV6_PRIVACY
904 score = ipv6_saddr_pref(ifp, idev->cnf.use_tempaddr > 1 ? IFA_F_TEMPORARY : 0);
905#else
906 score = ipv6_saddr_pref(ifp, 0);
907#endif
908 if (score <= hiscore)
909 continue;
910 988
911 if (match) 989 /* Rule 5: Prefer outgoing interface */
912 in6_ifa_put(match); 990 if (hiscore.rule < 5) {
913 match = ifp; 991 if (daddr_dev == NULL ||
914 hiscore = score; 992 daddr_dev == ifa_result->idev->dev)
915 in6_ifa_hold(ifp); 993 hiscore.attrs |= IPV6_SADDR_SCORE_OIF;
994 hiscore.rule++;
995 }
996 if (daddr_dev == NULL ||
997 daddr_dev == ifa->idev->dev) {
998 score.attrs |= IPV6_SADDR_SCORE_OIF;
999 if (!(hiscore.attrs & IPV6_SADDR_SCORE_OIF)) {
1000 score.rule = 5;
1001 goto record_it;
1002 }
1003 } else {
1004 if (hiscore.attrs & IPV6_SADDR_SCORE_OIF)
1005 continue;
1006 }
916 1007
917 if (IPV6_GET_SADDR_MAXSCORE(score)) { 1008 /* Rule 6: Prefer matching label */
918 read_unlock_bh(&idev->lock); 1009 if (hiscore.rule < 6) {
919 goto out_unlock_base; 1010 if (ipv6_saddr_label(&ifa_result->addr, hiscore.addr_type) == daddr_label)
920 } 1011 hiscore.attrs |= IPV6_SADDR_SCORE_LABEL;
1012 hiscore.rule++;
1013 }
1014 if (ipv6_saddr_label(&ifa->addr, score.addr_type) == daddr_label) {
1015 score.attrs |= IPV6_SADDR_SCORE_LABEL;
1016 if (!(hiscore.attrs & IPV6_SADDR_SCORE_LABEL)) {
1017 score.rule = 6;
1018 goto record_it;
921 } 1019 }
1020 } else {
1021 if (hiscore.attrs & IPV6_SADDR_SCORE_LABEL)
1022 continue;
922 } 1023 }
923 read_unlock_bh(&idev->lock); 1024
1025#ifdef CONFIG_IPV6_PRIVACY
1026 /* Rule 7: Prefer public address
1027 * Note: prefer temprary address if use_tempaddr >= 2
1028 */
1029 if (hiscore.rule < 7) {
1030 if ((!(ifa_result->flags & IFA_F_TEMPORARY)) ^
1031 (ifa_result->idev->cnf.use_tempaddr >= 2))
1032 hiscore.attrs |= IPV6_SADDR_SCORE_PRIVACY;
1033 hiscore.rule++;
1034 }
1035 if ((!(ifa->flags & IFA_F_TEMPORARY)) ^
1036 (ifa->idev->cnf.use_tempaddr >= 2)) {
1037 score.attrs |= IPV6_SADDR_SCORE_PRIVACY;
1038 if (!(hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)) {
1039 score.rule = 7;
1040 goto record_it;
1041 }
1042 } else {
1043 if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
1044 continue;
1045 }
1046#endif
1047 /* Rule 8: Use longest matching prefix */
1048 if (hiscore.rule < 8)
1049 hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);
1050 score.rule++;
1051 score.matchlen = ipv6_addr_diff(&ifa->addr, daddr);
1052 if (score.matchlen > hiscore.matchlen) {
1053 score.rule = 8;
1054 goto record_it;
1055 }
1056#if 0
1057 else if (score.matchlen < hiscore.matchlen)
1058 continue;
1059#endif
1060
1061 /* Final Rule: choose first available one */
1062 continue;
1063record_it:
1064 if (ifa_result)
1065 in6_ifa_put(ifa_result);
1066 in6_ifa_hold(ifa);
1067 ifa_result = ifa;
1068 hiscore = score;
924 } 1069 }
1070 read_unlock_bh(&idev->lock);
925 } 1071 }
926
927out_unlock_base:
928 read_unlock(&addrconf_lock); 1072 read_unlock(&addrconf_lock);
929 read_unlock(&dev_base_lock); 1073 read_unlock(&dev_base_lock);
930 1074
931out: 1075 if (!ifa_result)
932 err = -EADDRNOTAVAIL; 1076 return -EADDRNOTAVAIL;
933 if (match) { 1077
934 ipv6_addr_copy(saddr, &match->addr); 1078 ipv6_addr_copy(saddr, &ifa_result->addr);
935 err = 0; 1079 in6_ifa_put(ifa_result);
936 in6_ifa_put(match); 1080 return 0;
937 }
938
939 return err;
940} 1081}
941 1082
942 1083
@@ -2950,8 +3091,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
2950 3091
2951nlmsg_failure: 3092nlmsg_failure:
2952rtattr_failure: 3093rtattr_failure:
2953 if (array) 3094 kfree(array);
2954 kfree(array);
2955 skb_trim(skb, b - skb->data); 3095 skb_trim(skb, b - skb->data);
2956 return -1; 3096 return -1;
2957} 3097}