diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 556 |
1 files changed, 348 insertions, 208 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index abe46a4228ce..344e972426df 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -442,6 +442,8 @@ static int inet6_netconf_msgsize_devconf(int type) | |||
442 | if (type == -1 || type == NETCONFA_MC_FORWARDING) | 442 | if (type == -1 || type == NETCONFA_MC_FORWARDING) |
443 | size += nla_total_size(4); | 443 | size += nla_total_size(4); |
444 | #endif | 444 | #endif |
445 | if (type == -1 || type == NETCONFA_PROXY_NEIGH) | ||
446 | size += nla_total_size(4); | ||
445 | 447 | ||
446 | return size; | 448 | return size; |
447 | } | 449 | } |
@@ -475,6 +477,10 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex, | |||
475 | devconf->mc_forwarding) < 0) | 477 | devconf->mc_forwarding) < 0) |
476 | goto nla_put_failure; | 478 | goto nla_put_failure; |
477 | #endif | 479 | #endif |
480 | if ((type == -1 || type == NETCONFA_PROXY_NEIGH) && | ||
481 | nla_put_s32(skb, NETCONFA_PROXY_NEIGH, devconf->proxy_ndp) < 0) | ||
482 | goto nla_put_failure; | ||
483 | |||
478 | return nlmsg_end(skb, nlh); | 484 | return nlmsg_end(skb, nlh); |
479 | 485 | ||
480 | nla_put_failure: | 486 | nla_put_failure: |
@@ -509,6 +515,7 @@ errout: | |||
509 | static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = { | 515 | static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = { |
510 | [NETCONFA_IFINDEX] = { .len = sizeof(int) }, | 516 | [NETCONFA_IFINDEX] = { .len = sizeof(int) }, |
511 | [NETCONFA_FORWARDING] = { .len = sizeof(int) }, | 517 | [NETCONFA_FORWARDING] = { .len = sizeof(int) }, |
518 | [NETCONFA_PROXY_NEIGH] = { .len = sizeof(int) }, | ||
512 | }; | 519 | }; |
513 | 520 | ||
514 | static int inet6_netconf_get_devconf(struct sk_buff *in_skb, | 521 | static int inet6_netconf_get_devconf(struct sk_buff *in_skb, |
@@ -834,6 +841,8 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, | |||
834 | goto out; | 841 | goto out; |
835 | } | 842 | } |
836 | 843 | ||
844 | neigh_parms_data_state_setall(idev->nd_parms); | ||
845 | |||
837 | ifa->addr = *addr; | 846 | ifa->addr = *addr; |
838 | if (peer_addr) | 847 | if (peer_addr) |
839 | ifa->peer_addr = *peer_addr; | 848 | ifa->peer_addr = *peer_addr; |
@@ -891,15 +900,95 @@ out: | |||
891 | goto out2; | 900 | goto out2; |
892 | } | 901 | } |
893 | 902 | ||
903 | enum cleanup_prefix_rt_t { | ||
904 | CLEANUP_PREFIX_RT_NOP, /* no cleanup action for prefix route */ | ||
905 | CLEANUP_PREFIX_RT_DEL, /* delete the prefix route */ | ||
906 | CLEANUP_PREFIX_RT_EXPIRE, /* update the lifetime of the prefix route */ | ||
907 | }; | ||
908 | |||
909 | /* | ||
910 | * Check, whether the prefix for ifp would still need a prefix route | ||
911 | * after deleting ifp. The function returns one of the CLEANUP_PREFIX_RT_* | ||
912 | * constants. | ||
913 | * | ||
914 | * 1) we don't purge prefix if address was not permanent. | ||
915 | * prefix is managed by its own lifetime. | ||
916 | * 2) we also don't purge, if the address was IFA_F_NOPREFIXROUTE. | ||
917 | * 3) if there are no addresses, delete prefix. | ||
918 | * 4) if there are still other permanent address(es), | ||
919 | * corresponding prefix is still permanent. | ||
920 | * 5) if there are still other addresses with IFA_F_NOPREFIXROUTE, | ||
921 | * don't purge the prefix, assume user space is managing it. | ||
922 | * 6) otherwise, update prefix lifetime to the | ||
923 | * longest valid lifetime among the corresponding | ||
924 | * addresses on the device. | ||
925 | * Note: subsequent RA will update lifetime. | ||
926 | **/ | ||
927 | static enum cleanup_prefix_rt_t | ||
928 | check_cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long *expires) | ||
929 | { | ||
930 | struct inet6_ifaddr *ifa; | ||
931 | struct inet6_dev *idev = ifp->idev; | ||
932 | unsigned long lifetime; | ||
933 | enum cleanup_prefix_rt_t action = CLEANUP_PREFIX_RT_DEL; | ||
934 | |||
935 | *expires = jiffies; | ||
936 | |||
937 | list_for_each_entry(ifa, &idev->addr_list, if_list) { | ||
938 | if (ifa == ifp) | ||
939 | continue; | ||
940 | if (!ipv6_prefix_equal(&ifa->addr, &ifp->addr, | ||
941 | ifp->prefix_len)) | ||
942 | continue; | ||
943 | if (ifa->flags & (IFA_F_PERMANENT | IFA_F_NOPREFIXROUTE)) | ||
944 | return CLEANUP_PREFIX_RT_NOP; | ||
945 | |||
946 | action = CLEANUP_PREFIX_RT_EXPIRE; | ||
947 | |||
948 | spin_lock(&ifa->lock); | ||
949 | |||
950 | lifetime = addrconf_timeout_fixup(ifa->valid_lft, HZ); | ||
951 | /* | ||
952 | * Note: Because this address is | ||
953 | * not permanent, lifetime < | ||
954 | * LONG_MAX / HZ here. | ||
955 | */ | ||
956 | if (time_before(*expires, ifa->tstamp + lifetime * HZ)) | ||
957 | *expires = ifa->tstamp + lifetime * HZ; | ||
958 | spin_unlock(&ifa->lock); | ||
959 | } | ||
960 | |||
961 | return action; | ||
962 | } | ||
963 | |||
964 | static void | ||
965 | cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, bool del_rt) | ||
966 | { | ||
967 | struct rt6_info *rt; | ||
968 | |||
969 | rt = addrconf_get_prefix_route(&ifp->addr, | ||
970 | ifp->prefix_len, | ||
971 | ifp->idev->dev, | ||
972 | 0, RTF_GATEWAY | RTF_DEFAULT); | ||
973 | if (rt) { | ||
974 | if (del_rt) | ||
975 | ip6_del_rt(rt); | ||
976 | else { | ||
977 | if (!(rt->rt6i_flags & RTF_EXPIRES)) | ||
978 | rt6_set_expires(rt, expires); | ||
979 | ip6_rt_put(rt); | ||
980 | } | ||
981 | } | ||
982 | } | ||
983 | |||
984 | |||
894 | /* This function wants to get referenced ifp and releases it before return */ | 985 | /* This function wants to get referenced ifp and releases it before return */ |
895 | 986 | ||
896 | static void ipv6_del_addr(struct inet6_ifaddr *ifp) | 987 | static void ipv6_del_addr(struct inet6_ifaddr *ifp) |
897 | { | 988 | { |
898 | struct inet6_ifaddr *ifa, *ifn; | ||
899 | struct inet6_dev *idev = ifp->idev; | ||
900 | int state; | 989 | int state; |
901 | int deleted = 0, onlink = 0; | 990 | enum cleanup_prefix_rt_t action = CLEANUP_PREFIX_RT_NOP; |
902 | unsigned long expires = jiffies; | 991 | unsigned long expires; |
903 | 992 | ||
904 | spin_lock_bh(&ifp->state_lock); | 993 | spin_lock_bh(&ifp->state_lock); |
905 | state = ifp->state; | 994 | state = ifp->state; |
@@ -913,7 +1002,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
913 | hlist_del_init_rcu(&ifp->addr_lst); | 1002 | hlist_del_init_rcu(&ifp->addr_lst); |
914 | spin_unlock_bh(&addrconf_hash_lock); | 1003 | spin_unlock_bh(&addrconf_hash_lock); |
915 | 1004 | ||
916 | write_lock_bh(&idev->lock); | 1005 | write_lock_bh(&ifp->idev->lock); |
917 | 1006 | ||
918 | if (ifp->flags&IFA_F_TEMPORARY) { | 1007 | if (ifp->flags&IFA_F_TEMPORARY) { |
919 | list_del(&ifp->tmp_list); | 1008 | list_del(&ifp->tmp_list); |
@@ -924,45 +1013,13 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
924 | __in6_ifa_put(ifp); | 1013 | __in6_ifa_put(ifp); |
925 | } | 1014 | } |
926 | 1015 | ||
927 | list_for_each_entry_safe(ifa, ifn, &idev->addr_list, if_list) { | 1016 | if (ifp->flags & IFA_F_PERMANENT && !(ifp->flags & IFA_F_NOPREFIXROUTE)) |
928 | if (ifa == ifp) { | 1017 | action = check_cleanup_prefix_route(ifp, &expires); |
929 | list_del_init(&ifp->if_list); | ||
930 | __in6_ifa_put(ifp); | ||
931 | 1018 | ||
932 | if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0) | 1019 | list_del_init(&ifp->if_list); |
933 | break; | 1020 | __in6_ifa_put(ifp); |
934 | deleted = 1; | 1021 | |
935 | continue; | 1022 | write_unlock_bh(&ifp->idev->lock); |
936 | } else if (ifp->flags & IFA_F_PERMANENT) { | ||
937 | if (ipv6_prefix_equal(&ifa->addr, &ifp->addr, | ||
938 | ifp->prefix_len)) { | ||
939 | if (ifa->flags & IFA_F_PERMANENT) { | ||
940 | onlink = 1; | ||
941 | if (deleted) | ||
942 | break; | ||
943 | } else { | ||
944 | unsigned long lifetime; | ||
945 | |||
946 | if (!onlink) | ||
947 | onlink = -1; | ||
948 | |||
949 | spin_lock(&ifa->lock); | ||
950 | |||
951 | lifetime = addrconf_timeout_fixup(ifa->valid_lft, HZ); | ||
952 | /* | ||
953 | * Note: Because this address is | ||
954 | * not permanent, lifetime < | ||
955 | * LONG_MAX / HZ here. | ||
956 | */ | ||
957 | if (time_before(expires, | ||
958 | ifa->tstamp + lifetime * HZ)) | ||
959 | expires = ifa->tstamp + lifetime * HZ; | ||
960 | spin_unlock(&ifa->lock); | ||
961 | } | ||
962 | } | ||
963 | } | ||
964 | } | ||
965 | write_unlock_bh(&idev->lock); | ||
966 | 1023 | ||
967 | addrconf_del_dad_timer(ifp); | 1024 | addrconf_del_dad_timer(ifp); |
968 | 1025 | ||
@@ -970,41 +1027,9 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
970 | 1027 | ||
971 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifp); | 1028 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifp); |
972 | 1029 | ||
973 | /* | 1030 | if (action != CLEANUP_PREFIX_RT_NOP) { |
974 | * Purge or update corresponding prefix | 1031 | cleanup_prefix_route(ifp, expires, |
975 | * | 1032 | action == CLEANUP_PREFIX_RT_DEL); |
976 | * 1) we don't purge prefix here if address was not permanent. | ||
977 | * prefix is managed by its own lifetime. | ||
978 | * 2) if there're no addresses, delete prefix. | ||
979 | * 3) if there're still other permanent address(es), | ||
980 | * corresponding prefix is still permanent. | ||
981 | * 4) otherwise, update prefix lifetime to the | ||
982 | * longest valid lifetime among the corresponding | ||
983 | * addresses on the device. | ||
984 | * Note: subsequent RA will update lifetime. | ||
985 | * | ||
986 | * --yoshfuji | ||
987 | */ | ||
988 | if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) { | ||
989 | struct in6_addr prefix; | ||
990 | struct rt6_info *rt; | ||
991 | |||
992 | ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); | ||
993 | |||
994 | rt = addrconf_get_prefix_route(&prefix, | ||
995 | ifp->prefix_len, | ||
996 | ifp->idev->dev, | ||
997 | 0, RTF_GATEWAY | RTF_DEFAULT); | ||
998 | |||
999 | if (rt) { | ||
1000 | if (onlink == 0) { | ||
1001 | ip6_del_rt(rt); | ||
1002 | rt = NULL; | ||
1003 | } else if (!(rt->rt6i_flags & RTF_EXPIRES)) { | ||
1004 | rt6_set_expires(rt, expires); | ||
1005 | } | ||
1006 | } | ||
1007 | ip6_rt_put(rt); | ||
1008 | } | 1033 | } |
1009 | 1034 | ||
1010 | /* clean up prefsrc entries */ | 1035 | /* clean up prefsrc entries */ |
@@ -1024,7 +1049,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i | |||
1024 | u32 addr_flags; | 1049 | u32 addr_flags; |
1025 | unsigned long now = jiffies; | 1050 | unsigned long now = jiffies; |
1026 | 1051 | ||
1027 | write_lock(&idev->lock); | 1052 | write_lock_bh(&idev->lock); |
1028 | if (ift) { | 1053 | if (ift) { |
1029 | spin_lock_bh(&ift->lock); | 1054 | spin_lock_bh(&ift->lock); |
1030 | memcpy(&addr.s6_addr[8], &ift->addr.s6_addr[8], 8); | 1055 | memcpy(&addr.s6_addr[8], &ift->addr.s6_addr[8], 8); |
@@ -1036,7 +1061,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i | |||
1036 | retry: | 1061 | retry: |
1037 | in6_dev_hold(idev); | 1062 | in6_dev_hold(idev); |
1038 | if (idev->cnf.use_tempaddr <= 0) { | 1063 | if (idev->cnf.use_tempaddr <= 0) { |
1039 | write_unlock(&idev->lock); | 1064 | write_unlock_bh(&idev->lock); |
1040 | pr_info("%s: use_tempaddr is disabled\n", __func__); | 1065 | pr_info("%s: use_tempaddr is disabled\n", __func__); |
1041 | in6_dev_put(idev); | 1066 | in6_dev_put(idev); |
1042 | ret = -1; | 1067 | ret = -1; |
@@ -1046,7 +1071,7 @@ retry: | |||
1046 | if (ifp->regen_count++ >= idev->cnf.regen_max_retry) { | 1071 | if (ifp->regen_count++ >= idev->cnf.regen_max_retry) { |
1047 | idev->cnf.use_tempaddr = -1; /*XXX*/ | 1072 | idev->cnf.use_tempaddr = -1; /*XXX*/ |
1048 | spin_unlock_bh(&ifp->lock); | 1073 | spin_unlock_bh(&ifp->lock); |
1049 | write_unlock(&idev->lock); | 1074 | write_unlock_bh(&idev->lock); |
1050 | pr_warn("%s: regeneration time exceeded - disabled temporary address support\n", | 1075 | pr_warn("%s: regeneration time exceeded - disabled temporary address support\n", |
1051 | __func__); | 1076 | __func__); |
1052 | in6_dev_put(idev); | 1077 | in6_dev_put(idev); |
@@ -1071,15 +1096,18 @@ retry: | |||
1071 | 1096 | ||
1072 | regen_advance = idev->cnf.regen_max_retry * | 1097 | regen_advance = idev->cnf.regen_max_retry * |
1073 | idev->cnf.dad_transmits * | 1098 | idev->cnf.dad_transmits * |
1074 | idev->nd_parms->retrans_time / HZ; | 1099 | NEIGH_VAR(idev->nd_parms, RETRANS_TIME) / HZ; |
1075 | write_unlock(&idev->lock); | 1100 | write_unlock_bh(&idev->lock); |
1076 | 1101 | ||
1077 | /* A temporary address is created only if this calculated Preferred | 1102 | /* A temporary address is created only if this calculated Preferred |
1078 | * Lifetime is greater than REGEN_ADVANCE time units. In particular, | 1103 | * Lifetime is greater than REGEN_ADVANCE time units. In particular, |
1079 | * an implementation must not create a temporary address with a zero | 1104 | * an implementation must not create a temporary address with a zero |
1080 | * Preferred Lifetime. | 1105 | * Preferred Lifetime. |
1106 | * Use age calculation as in addrconf_verify to avoid unnecessary | ||
1107 | * temporary addresses being generated. | ||
1081 | */ | 1108 | */ |
1082 | if (tmp_prefered_lft <= regen_advance) { | 1109 | age = (now - tmp_tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ; |
1110 | if (tmp_prefered_lft <= regen_advance + age) { | ||
1083 | in6_ifa_put(ifp); | 1111 | in6_ifa_put(ifp); |
1084 | in6_dev_put(idev); | 1112 | in6_dev_put(idev); |
1085 | ret = -1; | 1113 | ret = -1; |
@@ -1099,7 +1127,7 @@ retry: | |||
1099 | in6_dev_put(idev); | 1127 | in6_dev_put(idev); |
1100 | pr_info("%s: retry temporary address regeneration\n", __func__); | 1128 | pr_info("%s: retry temporary address regeneration\n", __func__); |
1101 | tmpaddr = &addr; | 1129 | tmpaddr = &addr; |
1102 | write_lock(&idev->lock); | 1130 | write_lock_bh(&idev->lock); |
1103 | goto retry; | 1131 | goto retry; |
1104 | } | 1132 | } |
1105 | 1133 | ||
@@ -1200,7 +1228,7 @@ static int ipv6_get_saddr_eval(struct net *net, | |||
1200 | * | d is scope of the destination. | 1228 | * | d is scope of the destination. |
1201 | * B-d | \ | 1229 | * B-d | \ |
1202 | * | \ <- smaller scope is better if | 1230 | * | \ <- smaller scope is better if |
1203 | * B-15 | \ if scope is enough for destinaion. | 1231 | * B-15 | \ if scope is enough for destination. |
1204 | * | ret = B - scope (-1 <= scope >= d <= 15). | 1232 | * | ret = B - scope (-1 <= scope >= d <= 15). |
1205 | * d-C-1 | / | 1233 | * d-C-1 | / |
1206 | * |/ <- greater is better | 1234 | * |/ <- greater is better |
@@ -1407,12 +1435,14 @@ try_nextdev: | |||
1407 | EXPORT_SYMBOL(ipv6_dev_get_saddr); | 1435 | EXPORT_SYMBOL(ipv6_dev_get_saddr); |
1408 | 1436 | ||
1409 | int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, | 1437 | int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, |
1410 | unsigned char banned_flags) | 1438 | u32 banned_flags) |
1411 | { | 1439 | { |
1412 | struct inet6_ifaddr *ifp; | 1440 | struct inet6_ifaddr *ifp; |
1413 | int err = -EADDRNOTAVAIL; | 1441 | int err = -EADDRNOTAVAIL; |
1414 | 1442 | ||
1415 | list_for_each_entry(ifp, &idev->addr_list, if_list) { | 1443 | list_for_each_entry_reverse(ifp, &idev->addr_list, if_list) { |
1444 | if (ifp->scope > IFA_LINK) | ||
1445 | break; | ||
1416 | if (ifp->scope == IFA_LINK && | 1446 | if (ifp->scope == IFA_LINK && |
1417 | !(ifp->flags & banned_flags)) { | 1447 | !(ifp->flags & banned_flags)) { |
1418 | *addr = ifp->addr; | 1448 | *addr = ifp->addr; |
@@ -1424,7 +1454,7 @@ int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, | |||
1424 | } | 1454 | } |
1425 | 1455 | ||
1426 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, | 1456 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, |
1427 | unsigned char banned_flags) | 1457 | u32 banned_flags) |
1428 | { | 1458 | { |
1429 | struct inet6_dev *idev; | 1459 | struct inet6_dev *idev; |
1430 | int err = -EADDRNOTAVAIL; | 1460 | int err = -EADDRNOTAVAIL; |
@@ -1816,6 +1846,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) | |||
1816 | return addrconf_ifid_sit(eui, dev); | 1846 | return addrconf_ifid_sit(eui, dev); |
1817 | case ARPHRD_IPGRE: | 1847 | case ARPHRD_IPGRE: |
1818 | return addrconf_ifid_gre(eui, dev); | 1848 | return addrconf_ifid_gre(eui, dev); |
1849 | case ARPHRD_6LOWPAN: | ||
1819 | case ARPHRD_IEEE802154: | 1850 | case ARPHRD_IEEE802154: |
1820 | return addrconf_ifid_eui64(eui, dev); | 1851 | return addrconf_ifid_eui64(eui, dev); |
1821 | case ARPHRD_IEEE1394: | 1852 | case ARPHRD_IEEE1394: |
@@ -1832,7 +1863,9 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev) | |||
1832 | struct inet6_ifaddr *ifp; | 1863 | struct inet6_ifaddr *ifp; |
1833 | 1864 | ||
1834 | read_lock_bh(&idev->lock); | 1865 | read_lock_bh(&idev->lock); |
1835 | list_for_each_entry(ifp, &idev->addr_list, if_list) { | 1866 | list_for_each_entry_reverse(ifp, &idev->addr_list, if_list) { |
1867 | if (ifp->scope > IFA_LINK) | ||
1868 | break; | ||
1836 | if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { | 1869 | if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { |
1837 | memcpy(eui, ifp->addr.s6_addr+8, 8); | 1870 | memcpy(eui, ifp->addr.s6_addr+8, 8); |
1838 | err = 0; | 1871 | err = 0; |
@@ -1888,7 +1921,8 @@ static void ipv6_regen_rndid(unsigned long data) | |||
1888 | 1921 | ||
1889 | expires = jiffies + | 1922 | expires = jiffies + |
1890 | idev->cnf.temp_prefered_lft * HZ - | 1923 | idev->cnf.temp_prefered_lft * HZ - |
1891 | idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - | 1924 | idev->cnf.regen_max_retry * idev->cnf.dad_transmits * |
1925 | NEIGH_VAR(idev->nd_parms, RETRANS_TIME) - | ||
1892 | idev->cnf.max_desync_factor * HZ; | 1926 | idev->cnf.max_desync_factor * HZ; |
1893 | if (time_before(expires, jiffies)) { | 1927 | if (time_before(expires, jiffies)) { |
1894 | pr_warn("%s: too short regeneration interval; timer disabled for %s\n", | 1928 | pr_warn("%s: too short regeneration interval; timer disabled for %s\n", |
@@ -2016,6 +2050,73 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev) | |||
2016 | return idev; | 2050 | return idev; |
2017 | } | 2051 | } |
2018 | 2052 | ||
2053 | static void manage_tempaddrs(struct inet6_dev *idev, | ||
2054 | struct inet6_ifaddr *ifp, | ||
2055 | __u32 valid_lft, __u32 prefered_lft, | ||
2056 | bool create, unsigned long now) | ||
2057 | { | ||
2058 | u32 flags; | ||
2059 | struct inet6_ifaddr *ift; | ||
2060 | |||
2061 | read_lock_bh(&idev->lock); | ||
2062 | /* update all temporary addresses in the list */ | ||
2063 | list_for_each_entry(ift, &idev->tempaddr_list, tmp_list) { | ||
2064 | int age, max_valid, max_prefered; | ||
2065 | |||
2066 | if (ifp != ift->ifpub) | ||
2067 | continue; | ||
2068 | |||
2069 | /* RFC 4941 section 3.3: | ||
2070 | * If a received option will extend the lifetime of a public | ||
2071 | * address, the lifetimes of temporary addresses should | ||
2072 | * be extended, subject to the overall constraint that no | ||
2073 | * temporary addresses should ever remain "valid" or "preferred" | ||
2074 | * for a time longer than (TEMP_VALID_LIFETIME) or | ||
2075 | * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR), respectively. | ||
2076 | */ | ||
2077 | age = (now - ift->cstamp) / HZ; | ||
2078 | max_valid = idev->cnf.temp_valid_lft - age; | ||
2079 | if (max_valid < 0) | ||
2080 | max_valid = 0; | ||
2081 | |||
2082 | max_prefered = idev->cnf.temp_prefered_lft - | ||
2083 | idev->cnf.max_desync_factor - age; | ||
2084 | if (max_prefered < 0) | ||
2085 | max_prefered = 0; | ||
2086 | |||
2087 | if (valid_lft > max_valid) | ||
2088 | valid_lft = max_valid; | ||
2089 | |||
2090 | if (prefered_lft > max_prefered) | ||
2091 | prefered_lft = max_prefered; | ||
2092 | |||
2093 | spin_lock(&ift->lock); | ||
2094 | flags = ift->flags; | ||
2095 | ift->valid_lft = valid_lft; | ||
2096 | ift->prefered_lft = prefered_lft; | ||
2097 | ift->tstamp = now; | ||
2098 | if (prefered_lft > 0) | ||
2099 | ift->flags &= ~IFA_F_DEPRECATED; | ||
2100 | |||
2101 | spin_unlock(&ift->lock); | ||
2102 | if (!(flags&IFA_F_TENTATIVE)) | ||
2103 | ipv6_ifa_notify(0, ift); | ||
2104 | } | ||
2105 | |||
2106 | if ((create || list_empty(&idev->tempaddr_list)) && | ||
2107 | idev->cnf.use_tempaddr > 0) { | ||
2108 | /* When a new public address is created as described | ||
2109 | * in [ADDRCONF], also create a new temporary address. | ||
2110 | * Also create a temporary address if it's enabled but | ||
2111 | * no temporary address currently exists. | ||
2112 | */ | ||
2113 | read_unlock_bh(&idev->lock); | ||
2114 | ipv6_create_tempaddr(ifp, NULL); | ||
2115 | } else { | ||
2116 | read_unlock_bh(&idev->lock); | ||
2117 | } | ||
2118 | } | ||
2119 | |||
2019 | void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) | 2120 | void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) |
2020 | { | 2121 | { |
2021 | struct prefix_info *pinfo; | 2122 | struct prefix_info *pinfo; |
@@ -2170,6 +2271,7 @@ ok: | |||
2170 | return; | 2271 | return; |
2171 | } | 2272 | } |
2172 | 2273 | ||
2274 | ifp->flags |= IFA_F_MANAGETEMPADDR; | ||
2173 | update_lft = 0; | 2275 | update_lft = 0; |
2174 | create = 1; | 2276 | create = 1; |
2175 | ifp->cstamp = jiffies; | 2277 | ifp->cstamp = jiffies; |
@@ -2178,9 +2280,8 @@ ok: | |||
2178 | } | 2280 | } |
2179 | 2281 | ||
2180 | if (ifp) { | 2282 | if (ifp) { |
2181 | int flags; | 2283 | u32 flags; |
2182 | unsigned long now; | 2284 | unsigned long now; |
2183 | struct inet6_ifaddr *ift; | ||
2184 | u32 stored_lft; | 2285 | u32 stored_lft; |
2185 | 2286 | ||
2186 | /* update lifetime (RFC2462 5.5.3 e) */ | 2287 | /* update lifetime (RFC2462 5.5.3 e) */ |
@@ -2221,70 +2322,8 @@ ok: | |||
2221 | } else | 2322 | } else |
2222 | spin_unlock(&ifp->lock); | 2323 | spin_unlock(&ifp->lock); |
2223 | 2324 | ||
2224 | read_lock_bh(&in6_dev->lock); | 2325 | manage_tempaddrs(in6_dev, ifp, valid_lft, prefered_lft, |
2225 | /* update all temporary addresses in the list */ | 2326 | create, now); |
2226 | list_for_each_entry(ift, &in6_dev->tempaddr_list, | ||
2227 | tmp_list) { | ||
2228 | int age, max_valid, max_prefered; | ||
2229 | |||
2230 | if (ifp != ift->ifpub) | ||
2231 | continue; | ||
2232 | |||
2233 | /* | ||
2234 | * RFC 4941 section 3.3: | ||
2235 | * If a received option will extend the lifetime | ||
2236 | * of a public address, the lifetimes of | ||
2237 | * temporary addresses should be extended, | ||
2238 | * subject to the overall constraint that no | ||
2239 | * temporary addresses should ever remain | ||
2240 | * "valid" or "preferred" for a time longer than | ||
2241 | * (TEMP_VALID_LIFETIME) or | ||
2242 | * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR), | ||
2243 | * respectively. | ||
2244 | */ | ||
2245 | age = (now - ift->cstamp) / HZ; | ||
2246 | max_valid = in6_dev->cnf.temp_valid_lft - age; | ||
2247 | if (max_valid < 0) | ||
2248 | max_valid = 0; | ||
2249 | |||
2250 | max_prefered = in6_dev->cnf.temp_prefered_lft - | ||
2251 | in6_dev->cnf.max_desync_factor - | ||
2252 | age; | ||
2253 | if (max_prefered < 0) | ||
2254 | max_prefered = 0; | ||
2255 | |||
2256 | if (valid_lft > max_valid) | ||
2257 | valid_lft = max_valid; | ||
2258 | |||
2259 | if (prefered_lft > max_prefered) | ||
2260 | prefered_lft = max_prefered; | ||
2261 | |||
2262 | spin_lock(&ift->lock); | ||
2263 | flags = ift->flags; | ||
2264 | ift->valid_lft = valid_lft; | ||
2265 | ift->prefered_lft = prefered_lft; | ||
2266 | ift->tstamp = now; | ||
2267 | if (prefered_lft > 0) | ||
2268 | ift->flags &= ~IFA_F_DEPRECATED; | ||
2269 | |||
2270 | spin_unlock(&ift->lock); | ||
2271 | if (!(flags&IFA_F_TENTATIVE)) | ||
2272 | ipv6_ifa_notify(0, ift); | ||
2273 | } | ||
2274 | |||
2275 | if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) { | ||
2276 | /* | ||
2277 | * When a new public address is created as | ||
2278 | * described in [ADDRCONF], also create a new | ||
2279 | * temporary address. Also create a temporary | ||
2280 | * address if it's enabled but no temporary | ||
2281 | * address currently exists. | ||
2282 | */ | ||
2283 | read_unlock_bh(&in6_dev->lock); | ||
2284 | ipv6_create_tempaddr(ifp, NULL); | ||
2285 | } else { | ||
2286 | read_unlock_bh(&in6_dev->lock); | ||
2287 | } | ||
2288 | 2327 | ||
2289 | in6_ifa_put(ifp); | 2328 | in6_ifa_put(ifp); |
2290 | addrconf_verify(0); | 2329 | addrconf_verify(0); |
@@ -2363,10 +2402,11 @@ err_exit: | |||
2363 | /* | 2402 | /* |
2364 | * Manual configuration of address on an interface | 2403 | * Manual configuration of address on an interface |
2365 | */ | 2404 | */ |
2366 | static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *pfx, | 2405 | static int inet6_addr_add(struct net *net, int ifindex, |
2406 | const struct in6_addr *pfx, | ||
2367 | const struct in6_addr *peer_pfx, | 2407 | const struct in6_addr *peer_pfx, |
2368 | unsigned int plen, __u8 ifa_flags, __u32 prefered_lft, | 2408 | unsigned int plen, __u32 ifa_flags, |
2369 | __u32 valid_lft) | 2409 | __u32 prefered_lft, __u32 valid_lft) |
2370 | { | 2410 | { |
2371 | struct inet6_ifaddr *ifp; | 2411 | struct inet6_ifaddr *ifp; |
2372 | struct inet6_dev *idev; | 2412 | struct inet6_dev *idev; |
@@ -2385,6 +2425,9 @@ static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *p | |||
2385 | if (!valid_lft || prefered_lft > valid_lft) | 2425 | if (!valid_lft || prefered_lft > valid_lft) |
2386 | return -EINVAL; | 2426 | return -EINVAL; |
2387 | 2427 | ||
2428 | if (ifa_flags & IFA_F_MANAGETEMPADDR && plen != 64) | ||
2429 | return -EINVAL; | ||
2430 | |||
2388 | dev = __dev_get_by_index(net, ifindex); | 2431 | dev = __dev_get_by_index(net, ifindex); |
2389 | if (!dev) | 2432 | if (!dev) |
2390 | return -ENODEV; | 2433 | return -ENODEV; |
@@ -2417,14 +2460,20 @@ static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *p | |||
2417 | valid_lft, prefered_lft); | 2460 | valid_lft, prefered_lft); |
2418 | 2461 | ||
2419 | if (!IS_ERR(ifp)) { | 2462 | if (!IS_ERR(ifp)) { |
2420 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, | 2463 | if (!(ifa_flags & IFA_F_NOPREFIXROUTE)) { |
2421 | expires, flags); | 2464 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, |
2465 | expires, flags); | ||
2466 | } | ||
2467 | |||
2422 | /* | 2468 | /* |
2423 | * Note that section 3.1 of RFC 4429 indicates | 2469 | * Note that section 3.1 of RFC 4429 indicates |
2424 | * that the Optimistic flag should not be set for | 2470 | * that the Optimistic flag should not be set for |
2425 | * manually configured addresses | 2471 | * manually configured addresses |
2426 | */ | 2472 | */ |
2427 | addrconf_dad_start(ifp); | 2473 | addrconf_dad_start(ifp); |
2474 | if (ifa_flags & IFA_F_MANAGETEMPADDR) | ||
2475 | manage_tempaddrs(idev, ifp, valid_lft, prefered_lft, | ||
2476 | true, jiffies); | ||
2428 | in6_ifa_put(ifp); | 2477 | in6_ifa_put(ifp); |
2429 | addrconf_verify(0); | 2478 | addrconf_verify(0); |
2430 | return 0; | 2479 | return 0; |
@@ -2611,8 +2660,18 @@ static void init_loopback(struct net_device *dev) | |||
2611 | if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) | 2660 | if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) |
2612 | continue; | 2661 | continue; |
2613 | 2662 | ||
2614 | if (sp_ifa->rt) | 2663 | if (sp_ifa->rt) { |
2615 | continue; | 2664 | /* This dst has been added to garbage list when |
2665 | * lo device down, release this obsolete dst and | ||
2666 | * reallocate a new router for ifa. | ||
2667 | */ | ||
2668 | if (sp_ifa->rt->dst.obsolete > 0) { | ||
2669 | ip6_rt_put(sp_ifa->rt); | ||
2670 | sp_ifa->rt = NULL; | ||
2671 | } else { | ||
2672 | continue; | ||
2673 | } | ||
2674 | } | ||
2616 | 2675 | ||
2617 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, false); | 2676 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, false); |
2618 | 2677 | ||
@@ -2660,7 +2719,8 @@ static void addrconf_dev_config(struct net_device *dev) | |||
2660 | (dev->type != ARPHRD_INFINIBAND) && | 2719 | (dev->type != ARPHRD_INFINIBAND) && |
2661 | (dev->type != ARPHRD_IEEE802154) && | 2720 | (dev->type != ARPHRD_IEEE802154) && |
2662 | (dev->type != ARPHRD_IEEE1394) && | 2721 | (dev->type != ARPHRD_IEEE1394) && |
2663 | (dev->type != ARPHRD_TUNNEL6)) { | 2722 | (dev->type != ARPHRD_TUNNEL6) && |
2723 | (dev->type != ARPHRD_6LOWPAN)) { | ||
2664 | /* Alas, we support only Ethernet autoconfiguration. */ | 2724 | /* Alas, we support only Ethernet autoconfiguration. */ |
2665 | return; | 2725 | return; |
2666 | } | 2726 | } |
@@ -2726,6 +2786,8 @@ static void addrconf_gre_config(struct net_device *dev) | |||
2726 | ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); | 2786 | ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); |
2727 | if (!ipv6_generate_eui64(addr.s6_addr + 8, dev)) | 2787 | if (!ipv6_generate_eui64(addr.s6_addr + 8, dev)) |
2728 | addrconf_add_linklocal(idev, &addr); | 2788 | addrconf_add_linklocal(idev, &addr); |
2789 | else | ||
2790 | addrconf_prefix_route(&addr, 64, dev, 0, 0); | ||
2729 | } | 2791 | } |
2730 | #endif | 2792 | #endif |
2731 | 2793 | ||
@@ -2857,7 +2919,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2857 | } | 2919 | } |
2858 | 2920 | ||
2859 | /* | 2921 | /* |
2860 | * MTU falled under IPV6_MIN_MTU. | 2922 | * if MTU under IPV6_MIN_MTU. |
2861 | * Stop IPv6 on this interface. | 2923 | * Stop IPv6 on this interface. |
2862 | */ | 2924 | */ |
2863 | 2925 | ||
@@ -3083,7 +3145,7 @@ static void addrconf_dad_kick(struct inet6_ifaddr *ifp) | |||
3083 | if (ifp->flags & IFA_F_OPTIMISTIC) | 3145 | if (ifp->flags & IFA_F_OPTIMISTIC) |
3084 | rand_num = 0; | 3146 | rand_num = 0; |
3085 | else | 3147 | else |
3086 | rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1); | 3148 | rand_num = prandom_u32() % (idev->cnf.rtr_solicit_delay ? : 1); |
3087 | 3149 | ||
3088 | ifp->dad_probes = idev->cnf.dad_transmits; | 3150 | ifp->dad_probes = idev->cnf.dad_transmits; |
3089 | addrconf_mod_dad_timer(ifp, rand_num); | 3151 | addrconf_mod_dad_timer(ifp, rand_num); |
@@ -3096,7 +3158,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp) | |||
3096 | 3158 | ||
3097 | addrconf_join_solict(dev, &ifp->addr); | 3159 | addrconf_join_solict(dev, &ifp->addr); |
3098 | 3160 | ||
3099 | net_srandom(ifp->addr.s6_addr32[3]); | 3161 | prandom_seed((__force u32) ifp->addr.s6_addr32[3]); |
3100 | 3162 | ||
3101 | read_lock_bh(&idev->lock); | 3163 | read_lock_bh(&idev->lock); |
3102 | spin_lock(&ifp->lock); | 3164 | spin_lock(&ifp->lock); |
@@ -3178,7 +3240,8 @@ static void addrconf_dad_timer(unsigned long data) | |||
3178 | } | 3240 | } |
3179 | 3241 | ||
3180 | ifp->dad_probes--; | 3242 | ifp->dad_probes--; |
3181 | addrconf_mod_dad_timer(ifp, ifp->idev->nd_parms->retrans_time); | 3243 | addrconf_mod_dad_timer(ifp, |
3244 | NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME)); | ||
3182 | spin_unlock(&ifp->lock); | 3245 | spin_unlock(&ifp->lock); |
3183 | write_unlock(&idev->lock); | 3246 | write_unlock(&idev->lock); |
3184 | 3247 | ||
@@ -3189,6 +3252,24 @@ out: | |||
3189 | in6_ifa_put(ifp); | 3252 | in6_ifa_put(ifp); |
3190 | } | 3253 | } |
3191 | 3254 | ||
3255 | /* ifp->idev must be at least read locked */ | ||
3256 | static bool ipv6_lonely_lladdr(struct inet6_ifaddr *ifp) | ||
3257 | { | ||
3258 | struct inet6_ifaddr *ifpiter; | ||
3259 | struct inet6_dev *idev = ifp->idev; | ||
3260 | |||
3261 | list_for_each_entry_reverse(ifpiter, &idev->addr_list, if_list) { | ||
3262 | if (ifpiter->scope > IFA_LINK) | ||
3263 | break; | ||
3264 | if (ifp != ifpiter && ifpiter->scope == IFA_LINK && | ||
3265 | (ifpiter->flags & (IFA_F_PERMANENT|IFA_F_TENTATIVE| | ||
3266 | IFA_F_OPTIMISTIC|IFA_F_DADFAILED)) == | ||
3267 | IFA_F_PERMANENT) | ||
3268 | return false; | ||
3269 | } | ||
3270 | return true; | ||
3271 | } | ||
3272 | |||
3192 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp) | 3273 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp) |
3193 | { | 3274 | { |
3194 | struct net_device *dev = ifp->idev->dev; | 3275 | struct net_device *dev = ifp->idev->dev; |
@@ -3208,14 +3289,11 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) | |||
3208 | */ | 3289 | */ |
3209 | 3290 | ||
3210 | read_lock_bh(&ifp->idev->lock); | 3291 | read_lock_bh(&ifp->idev->lock); |
3211 | spin_lock(&ifp->lock); | 3292 | send_mld = ifp->scope == IFA_LINK && ipv6_lonely_lladdr(ifp); |
3212 | send_mld = ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL && | ||
3213 | ifp->idev->valid_ll_addr_cnt == 1; | ||
3214 | send_rs = send_mld && | 3293 | send_rs = send_mld && |
3215 | ipv6_accept_ra(ifp->idev) && | 3294 | ipv6_accept_ra(ifp->idev) && |
3216 | ifp->idev->cnf.rtr_solicits > 0 && | 3295 | ifp->idev->cnf.rtr_solicits > 0 && |
3217 | (dev->flags&IFF_LOOPBACK) == 0; | 3296 | (dev->flags&IFF_LOOPBACK) == 0; |
3218 | spin_unlock(&ifp->lock); | ||
3219 | read_unlock_bh(&ifp->idev->lock); | 3297 | read_unlock_bh(&ifp->idev->lock); |
3220 | 3298 | ||
3221 | /* While dad is in progress mld report's source address is in6_addrany. | 3299 | /* While dad is in progress mld report's source address is in6_addrany. |
@@ -3358,7 +3436,7 @@ static int if6_seq_show(struct seq_file *seq, void *v) | |||
3358 | ifp->idev->dev->ifindex, | 3436 | ifp->idev->dev->ifindex, |
3359 | ifp->prefix_len, | 3437 | ifp->prefix_len, |
3360 | ifp->scope, | 3438 | ifp->scope, |
3361 | ifp->flags, | 3439 | (u8) ifp->flags, |
3362 | ifp->idev->dev->name); | 3440 | ifp->idev->dev->name); |
3363 | return 0; | 3441 | return 0; |
3364 | } | 3442 | } |
@@ -3505,7 +3583,7 @@ restart: | |||
3505 | !(ifp->flags&IFA_F_TENTATIVE)) { | 3583 | !(ifp->flags&IFA_F_TENTATIVE)) { |
3506 | unsigned long regen_advance = ifp->idev->cnf.regen_max_retry * | 3584 | unsigned long regen_advance = ifp->idev->cnf.regen_max_retry * |
3507 | ifp->idev->cnf.dad_transmits * | 3585 | ifp->idev->cnf.dad_transmits * |
3508 | ifp->idev->nd_parms->retrans_time / HZ; | 3586 | NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME) / HZ; |
3509 | 3587 | ||
3510 | if (age >= ifp->prefered_lft - regen_advance) { | 3588 | if (age >= ifp->prefered_lft - regen_advance) { |
3511 | struct inet6_ifaddr *ifpub = ifp->ifpub; | 3589 | struct inet6_ifaddr *ifpub = ifp->ifpub; |
@@ -3580,6 +3658,7 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { | |||
3580 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, | 3658 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, |
3581 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, | 3659 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, |
3582 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, | 3660 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, |
3661 | [IFA_FLAGS] = { .len = sizeof(u32) }, | ||
3583 | }; | 3662 | }; |
3584 | 3663 | ||
3585 | static int | 3664 | static int |
@@ -3603,16 +3682,22 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
3603 | return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); | 3682 | return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); |
3604 | } | 3683 | } |
3605 | 3684 | ||
3606 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | 3685 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, |
3607 | u32 prefered_lft, u32 valid_lft) | 3686 | u32 prefered_lft, u32 valid_lft) |
3608 | { | 3687 | { |
3609 | u32 flags; | 3688 | u32 flags; |
3610 | clock_t expires; | 3689 | clock_t expires; |
3611 | unsigned long timeout; | 3690 | unsigned long timeout; |
3691 | bool was_managetempaddr; | ||
3692 | bool had_prefixroute; | ||
3612 | 3693 | ||
3613 | if (!valid_lft || (prefered_lft > valid_lft)) | 3694 | if (!valid_lft || (prefered_lft > valid_lft)) |
3614 | return -EINVAL; | 3695 | return -EINVAL; |
3615 | 3696 | ||
3697 | if (ifa_flags & IFA_F_MANAGETEMPADDR && | ||
3698 | (ifp->flags & IFA_F_TEMPORARY || ifp->prefix_len != 64)) | ||
3699 | return -EINVAL; | ||
3700 | |||
3616 | timeout = addrconf_timeout_fixup(valid_lft, HZ); | 3701 | timeout = addrconf_timeout_fixup(valid_lft, HZ); |
3617 | if (addrconf_finite_timeout(timeout)) { | 3702 | if (addrconf_finite_timeout(timeout)) { |
3618 | expires = jiffies_to_clock_t(timeout * HZ); | 3703 | expires = jiffies_to_clock_t(timeout * HZ); |
@@ -3632,7 +3717,13 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | |||
3632 | } | 3717 | } |
3633 | 3718 | ||
3634 | spin_lock_bh(&ifp->lock); | 3719 | spin_lock_bh(&ifp->lock); |
3635 | ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS)) | ifa_flags; | 3720 | was_managetempaddr = ifp->flags & IFA_F_MANAGETEMPADDR; |
3721 | had_prefixroute = ifp->flags & IFA_F_PERMANENT && | ||
3722 | !(ifp->flags & IFA_F_NOPREFIXROUTE); | ||
3723 | ifp->flags &= ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | | ||
3724 | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR | | ||
3725 | IFA_F_NOPREFIXROUTE); | ||
3726 | ifp->flags |= ifa_flags; | ||
3636 | ifp->tstamp = jiffies; | 3727 | ifp->tstamp = jiffies; |
3637 | ifp->valid_lft = valid_lft; | 3728 | ifp->valid_lft = valid_lft; |
3638 | ifp->prefered_lft = prefered_lft; | 3729 | ifp->prefered_lft = prefered_lft; |
@@ -3641,8 +3732,30 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | |||
3641 | if (!(ifp->flags&IFA_F_TENTATIVE)) | 3732 | if (!(ifp->flags&IFA_F_TENTATIVE)) |
3642 | ipv6_ifa_notify(0, ifp); | 3733 | ipv6_ifa_notify(0, ifp); |
3643 | 3734 | ||
3644 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, ifp->idev->dev, | 3735 | if (!(ifa_flags & IFA_F_NOPREFIXROUTE)) { |
3645 | expires, flags); | 3736 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, ifp->idev->dev, |
3737 | expires, flags); | ||
3738 | } else if (had_prefixroute) { | ||
3739 | enum cleanup_prefix_rt_t action; | ||
3740 | unsigned long rt_expires; | ||
3741 | |||
3742 | write_lock_bh(&ifp->idev->lock); | ||
3743 | action = check_cleanup_prefix_route(ifp, &rt_expires); | ||
3744 | write_unlock_bh(&ifp->idev->lock); | ||
3745 | |||
3746 | if (action != CLEANUP_PREFIX_RT_NOP) { | ||
3747 | cleanup_prefix_route(ifp, rt_expires, | ||
3748 | action == CLEANUP_PREFIX_RT_DEL); | ||
3749 | } | ||
3750 | } | ||
3751 | |||
3752 | if (was_managetempaddr || ifp->flags & IFA_F_MANAGETEMPADDR) { | ||
3753 | if (was_managetempaddr && !(ifp->flags & IFA_F_MANAGETEMPADDR)) | ||
3754 | valid_lft = prefered_lft = 0; | ||
3755 | manage_tempaddrs(ifp->idev, ifp, valid_lft, prefered_lft, | ||
3756 | !was_managetempaddr, jiffies); | ||
3757 | } | ||
3758 | |||
3646 | addrconf_verify(0); | 3759 | addrconf_verify(0); |
3647 | 3760 | ||
3648 | return 0; | 3761 | return 0; |
@@ -3658,7 +3771,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
3658 | struct inet6_ifaddr *ifa; | 3771 | struct inet6_ifaddr *ifa; |
3659 | struct net_device *dev; | 3772 | struct net_device *dev; |
3660 | u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME; | 3773 | u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME; |
3661 | u8 ifa_flags; | 3774 | u32 ifa_flags; |
3662 | int err; | 3775 | int err; |
3663 | 3776 | ||
3664 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3777 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
@@ -3685,14 +3798,17 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
3685 | if (dev == NULL) | 3798 | if (dev == NULL) |
3686 | return -ENODEV; | 3799 | return -ENODEV; |
3687 | 3800 | ||
3801 | ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags; | ||
3802 | |||
3688 | /* We ignore other flags so far. */ | 3803 | /* We ignore other flags so far. */ |
3689 | ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS); | 3804 | ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR | |
3805 | IFA_F_NOPREFIXROUTE; | ||
3690 | 3806 | ||
3691 | ifa = ipv6_get_ifaddr(net, pfx, dev, 1); | 3807 | ifa = ipv6_get_ifaddr(net, pfx, dev, 1); |
3692 | if (ifa == NULL) { | 3808 | if (ifa == NULL) { |
3693 | /* | 3809 | /* |
3694 | * It would be best to check for !NLM_F_CREATE here but | 3810 | * It would be best to check for !NLM_F_CREATE here but |
3695 | * userspace alreay relies on not having to provide this. | 3811 | * userspace already relies on not having to provide this. |
3696 | */ | 3812 | */ |
3697 | return inet6_addr_add(net, ifm->ifa_index, pfx, peer_pfx, | 3813 | return inet6_addr_add(net, ifm->ifa_index, pfx, peer_pfx, |
3698 | ifm->ifa_prefixlen, ifa_flags, | 3814 | ifm->ifa_prefixlen, ifa_flags, |
@@ -3710,7 +3826,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
3710 | return err; | 3826 | return err; |
3711 | } | 3827 | } |
3712 | 3828 | ||
3713 | static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u8 flags, | 3829 | static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u32 flags, |
3714 | u8 scope, int ifindex) | 3830 | u8 scope, int ifindex) |
3715 | { | 3831 | { |
3716 | struct ifaddrmsg *ifm; | 3832 | struct ifaddrmsg *ifm; |
@@ -3753,7 +3869,8 @@ static inline int inet6_ifaddr_msgsize(void) | |||
3753 | return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) | 3869 | return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) |
3754 | + nla_total_size(16) /* IFA_LOCAL */ | 3870 | + nla_total_size(16) /* IFA_LOCAL */ |
3755 | + nla_total_size(16) /* IFA_ADDRESS */ | 3871 | + nla_total_size(16) /* IFA_ADDRESS */ |
3756 | + nla_total_size(sizeof(struct ifa_cacheinfo)); | 3872 | + nla_total_size(sizeof(struct ifa_cacheinfo)) |
3873 | + nla_total_size(4) /* IFA_FLAGS */; | ||
3757 | } | 3874 | } |
3758 | 3875 | ||
3759 | static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | 3876 | static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, |
@@ -3802,6 +3919,9 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | |||
3802 | if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) | 3919 | if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) |
3803 | goto error; | 3920 | goto error; |
3804 | 3921 | ||
3922 | if (nla_put_u32(skb, IFA_FLAGS, ifa->flags) < 0) | ||
3923 | goto error; | ||
3924 | |||
3805 | return nlmsg_end(skb, nlh); | 3925 | return nlmsg_end(skb, nlh); |
3806 | 3926 | ||
3807 | error: | 3927 | error: |
@@ -4205,7 +4325,7 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev) | |||
4205 | ci.max_reasm_len = IPV6_MAXPLEN; | 4325 | ci.max_reasm_len = IPV6_MAXPLEN; |
4206 | ci.tstamp = cstamp_delta(idev->tstamp); | 4326 | ci.tstamp = cstamp_delta(idev->tstamp); |
4207 | ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time); | 4327 | ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time); |
4208 | ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time); | 4328 | ci.retrans_time = jiffies_to_msecs(NEIGH_VAR(idev->nd_parms, RETRANS_TIME)); |
4209 | if (nla_put(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci)) | 4329 | if (nla_put(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci)) |
4210 | goto nla_put_failure; | 4330 | goto nla_put_failure; |
4211 | nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); | 4331 | nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); |
@@ -4512,19 +4632,6 @@ errout: | |||
4512 | rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err); | 4632 | rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err); |
4513 | } | 4633 | } |
4514 | 4634 | ||
4515 | static void update_valid_ll_addr_cnt(struct inet6_ifaddr *ifp, int count) | ||
4516 | { | ||
4517 | write_lock_bh(&ifp->idev->lock); | ||
4518 | spin_lock(&ifp->lock); | ||
4519 | if (((ifp->flags & (IFA_F_PERMANENT|IFA_F_TENTATIVE|IFA_F_OPTIMISTIC| | ||
4520 | IFA_F_DADFAILED)) == IFA_F_PERMANENT) && | ||
4521 | (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) | ||
4522 | ifp->idev->valid_ll_addr_cnt += count; | ||
4523 | WARN_ON(ifp->idev->valid_ll_addr_cnt < 0); | ||
4524 | spin_unlock(&ifp->lock); | ||
4525 | write_unlock_bh(&ifp->idev->lock); | ||
4526 | } | ||
4527 | |||
4528 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | 4635 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) |
4529 | { | 4636 | { |
4530 | struct net *net = dev_net(ifp->idev->dev); | 4637 | struct net *net = dev_net(ifp->idev->dev); |
@@ -4533,8 +4640,6 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
4533 | 4640 | ||
4534 | switch (event) { | 4641 | switch (event) { |
4535 | case RTM_NEWADDR: | 4642 | case RTM_NEWADDR: |
4536 | update_valid_ll_addr_cnt(ifp, 1); | ||
4537 | |||
4538 | /* | 4643 | /* |
4539 | * If the address was optimistic | 4644 | * If the address was optimistic |
4540 | * we inserted the route at the start of | 4645 | * we inserted the route at the start of |
@@ -4550,8 +4655,6 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
4550 | ifp->idev->dev, 0, 0); | 4655 | ifp->idev->dev, 0, 0); |
4551 | break; | 4656 | break; |
4552 | case RTM_DELADDR: | 4657 | case RTM_DELADDR: |
4553 | update_valid_ll_addr_cnt(ifp, -1); | ||
4554 | |||
4555 | if (ifp->idev->cnf.forwarding) | 4658 | if (ifp->idev->cnf.forwarding) |
4556 | addrconf_leave_anycast(ifp); | 4659 | addrconf_leave_anycast(ifp); |
4557 | addrconf_leave_solict(ifp->idev, &ifp->addr); | 4660 | addrconf_leave_solict(ifp->idev, &ifp->addr); |
@@ -4698,6 +4801,46 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write, | |||
4698 | return ret; | 4801 | return ret; |
4699 | } | 4802 | } |
4700 | 4803 | ||
4804 | static | ||
4805 | int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write, | ||
4806 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
4807 | { | ||
4808 | int *valp = ctl->data; | ||
4809 | int ret; | ||
4810 | int old, new; | ||
4811 | |||
4812 | old = *valp; | ||
4813 | ret = proc_dointvec(ctl, write, buffer, lenp, ppos); | ||
4814 | new = *valp; | ||
4815 | |||
4816 | if (write && old != new) { | ||
4817 | struct net *net = ctl->extra2; | ||
4818 | |||
4819 | if (!rtnl_trylock()) | ||
4820 | return restart_syscall(); | ||
4821 | |||
4822 | if (valp == &net->ipv6.devconf_dflt->proxy_ndp) | ||
4823 | inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH, | ||
4824 | NETCONFA_IFINDEX_DEFAULT, | ||
4825 | net->ipv6.devconf_dflt); | ||
4826 | else if (valp == &net->ipv6.devconf_all->proxy_ndp) | ||
4827 | inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH, | ||
4828 | NETCONFA_IFINDEX_ALL, | ||
4829 | net->ipv6.devconf_all); | ||
4830 | else { | ||
4831 | struct inet6_dev *idev = ctl->extra1; | ||
4832 | |||
4833 | inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH, | ||
4834 | idev->dev->ifindex, | ||
4835 | &idev->cnf); | ||
4836 | } | ||
4837 | rtnl_unlock(); | ||
4838 | } | ||
4839 | |||
4840 | return ret; | ||
4841 | } | ||
4842 | |||
4843 | |||
4701 | static struct addrconf_sysctl_table | 4844 | static struct addrconf_sysctl_table |
4702 | { | 4845 | { |
4703 | struct ctl_table_header *sysctl_header; | 4846 | struct ctl_table_header *sysctl_header; |
@@ -4884,7 +5027,7 @@ static struct addrconf_sysctl_table | |||
4884 | .data = &ipv6_devconf.proxy_ndp, | 5027 | .data = &ipv6_devconf.proxy_ndp, |
4885 | .maxlen = sizeof(int), | 5028 | .maxlen = sizeof(int), |
4886 | .mode = 0644, | 5029 | .mode = 0644, |
4887 | .proc_handler = proc_dointvec, | 5030 | .proc_handler = addrconf_sysctl_proxy_ndp, |
4888 | }, | 5031 | }, |
4889 | { | 5032 | { |
4890 | .procname = "accept_source_route", | 5033 | .procname = "accept_source_route", |
@@ -5000,7 +5143,7 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p) | |||
5000 | 5143 | ||
5001 | static void addrconf_sysctl_register(struct inet6_dev *idev) | 5144 | static void addrconf_sysctl_register(struct inet6_dev *idev) |
5002 | { | 5145 | { |
5003 | neigh_sysctl_register(idev->dev, idev->nd_parms, "ipv6", | 5146 | neigh_sysctl_register(idev->dev, idev->nd_parms, |
5004 | &ndisc_ifinfo_sysctl_change); | 5147 | &ndisc_ifinfo_sysctl_change); |
5005 | __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, | 5148 | __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, |
5006 | idev, &idev->cnf); | 5149 | idev, &idev->cnf); |
@@ -5133,9 +5276,7 @@ int __init addrconf_init(void) | |||
5133 | 5276 | ||
5134 | addrconf_verify(0); | 5277 | addrconf_verify(0); |
5135 | 5278 | ||
5136 | err = rtnl_af_register(&inet6_ops); | 5279 | rtnl_af_register(&inet6_ops); |
5137 | if (err < 0) | ||
5138 | goto errout_af; | ||
5139 | 5280 | ||
5140 | err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo, | 5281 | err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo, |
5141 | NULL); | 5282 | NULL); |
@@ -5159,7 +5300,6 @@ int __init addrconf_init(void) | |||
5159 | return 0; | 5300 | return 0; |
5160 | errout: | 5301 | errout: |
5161 | rtnl_af_unregister(&inet6_ops); | 5302 | rtnl_af_unregister(&inet6_ops); |
5162 | errout_af: | ||
5163 | unregister_netdevice_notifier(&ipv6_dev_notf); | 5303 | unregister_netdevice_notifier(&ipv6_dev_notf); |
5164 | errlo: | 5304 | errlo: |
5165 | unregister_pernet_subsys(&addrconf_ops); | 5305 | unregister_pernet_subsys(&addrconf_ops); |