diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 513 |
1 files changed, 326 insertions, 187 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 4b6b720971b9..ad235690684c 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,8 +1096,8 @@ 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, |
@@ -1099,7 +1124,7 @@ retry: | |||
1099 | in6_dev_put(idev); | 1124 | in6_dev_put(idev); |
1100 | pr_info("%s: retry temporary address regeneration\n", __func__); | 1125 | pr_info("%s: retry temporary address regeneration\n", __func__); |
1101 | tmpaddr = &addr; | 1126 | tmpaddr = &addr; |
1102 | write_lock(&idev->lock); | 1127 | write_lock_bh(&idev->lock); |
1103 | goto retry; | 1128 | goto retry; |
1104 | } | 1129 | } |
1105 | 1130 | ||
@@ -1200,7 +1225,7 @@ static int ipv6_get_saddr_eval(struct net *net, | |||
1200 | * | d is scope of the destination. | 1225 | * | d is scope of the destination. |
1201 | * B-d | \ | 1226 | * B-d | \ |
1202 | * | \ <- smaller scope is better if | 1227 | * | \ <- smaller scope is better if |
1203 | * B-15 | \ if scope is enough for destinaion. | 1228 | * B-15 | \ if scope is enough for destination. |
1204 | * | ret = B - scope (-1 <= scope >= d <= 15). | 1229 | * | ret = B - scope (-1 <= scope >= d <= 15). |
1205 | * d-C-1 | / | 1230 | * d-C-1 | / |
1206 | * |/ <- greater is better | 1231 | * |/ <- greater is better |
@@ -1407,12 +1432,14 @@ try_nextdev: | |||
1407 | EXPORT_SYMBOL(ipv6_dev_get_saddr); | 1432 | EXPORT_SYMBOL(ipv6_dev_get_saddr); |
1408 | 1433 | ||
1409 | int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, | 1434 | int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, |
1410 | unsigned char banned_flags) | 1435 | u32 banned_flags) |
1411 | { | 1436 | { |
1412 | struct inet6_ifaddr *ifp; | 1437 | struct inet6_ifaddr *ifp; |
1413 | int err = -EADDRNOTAVAIL; | 1438 | int err = -EADDRNOTAVAIL; |
1414 | 1439 | ||
1415 | list_for_each_entry(ifp, &idev->addr_list, if_list) { | 1440 | list_for_each_entry_reverse(ifp, &idev->addr_list, if_list) { |
1441 | if (ifp->scope > IFA_LINK) | ||
1442 | break; | ||
1416 | if (ifp->scope == IFA_LINK && | 1443 | if (ifp->scope == IFA_LINK && |
1417 | !(ifp->flags & banned_flags)) { | 1444 | !(ifp->flags & banned_flags)) { |
1418 | *addr = ifp->addr; | 1445 | *addr = ifp->addr; |
@@ -1424,7 +1451,7 @@ int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, | |||
1424 | } | 1451 | } |
1425 | 1452 | ||
1426 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, | 1453 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, |
1427 | unsigned char banned_flags) | 1454 | u32 banned_flags) |
1428 | { | 1455 | { |
1429 | struct inet6_dev *idev; | 1456 | struct inet6_dev *idev; |
1430 | int err = -EADDRNOTAVAIL; | 1457 | int err = -EADDRNOTAVAIL; |
@@ -1816,6 +1843,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) | |||
1816 | return addrconf_ifid_sit(eui, dev); | 1843 | return addrconf_ifid_sit(eui, dev); |
1817 | case ARPHRD_IPGRE: | 1844 | case ARPHRD_IPGRE: |
1818 | return addrconf_ifid_gre(eui, dev); | 1845 | return addrconf_ifid_gre(eui, dev); |
1846 | case ARPHRD_6LOWPAN: | ||
1819 | case ARPHRD_IEEE802154: | 1847 | case ARPHRD_IEEE802154: |
1820 | return addrconf_ifid_eui64(eui, dev); | 1848 | return addrconf_ifid_eui64(eui, dev); |
1821 | case ARPHRD_IEEE1394: | 1849 | case ARPHRD_IEEE1394: |
@@ -1832,7 +1860,9 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev) | |||
1832 | struct inet6_ifaddr *ifp; | 1860 | struct inet6_ifaddr *ifp; |
1833 | 1861 | ||
1834 | read_lock_bh(&idev->lock); | 1862 | read_lock_bh(&idev->lock); |
1835 | list_for_each_entry(ifp, &idev->addr_list, if_list) { | 1863 | list_for_each_entry_reverse(ifp, &idev->addr_list, if_list) { |
1864 | if (ifp->scope > IFA_LINK) | ||
1865 | break; | ||
1836 | if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { | 1866 | if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { |
1837 | memcpy(eui, ifp->addr.s6_addr+8, 8); | 1867 | memcpy(eui, ifp->addr.s6_addr+8, 8); |
1838 | err = 0; | 1868 | err = 0; |
@@ -1888,7 +1918,8 @@ static void ipv6_regen_rndid(unsigned long data) | |||
1888 | 1918 | ||
1889 | expires = jiffies + | 1919 | expires = jiffies + |
1890 | idev->cnf.temp_prefered_lft * HZ - | 1920 | idev->cnf.temp_prefered_lft * HZ - |
1891 | idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - | 1921 | idev->cnf.regen_max_retry * idev->cnf.dad_transmits * |
1922 | NEIGH_VAR(idev->nd_parms, RETRANS_TIME) - | ||
1892 | idev->cnf.max_desync_factor * HZ; | 1923 | idev->cnf.max_desync_factor * HZ; |
1893 | if (time_before(expires, jiffies)) { | 1924 | if (time_before(expires, jiffies)) { |
1894 | pr_warn("%s: too short regeneration interval; timer disabled for %s\n", | 1925 | pr_warn("%s: too short regeneration interval; timer disabled for %s\n", |
@@ -2016,6 +2047,73 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev) | |||
2016 | return idev; | 2047 | return idev; |
2017 | } | 2048 | } |
2018 | 2049 | ||
2050 | static void manage_tempaddrs(struct inet6_dev *idev, | ||
2051 | struct inet6_ifaddr *ifp, | ||
2052 | __u32 valid_lft, __u32 prefered_lft, | ||
2053 | bool create, unsigned long now) | ||
2054 | { | ||
2055 | u32 flags; | ||
2056 | struct inet6_ifaddr *ift; | ||
2057 | |||
2058 | read_lock_bh(&idev->lock); | ||
2059 | /* update all temporary addresses in the list */ | ||
2060 | list_for_each_entry(ift, &idev->tempaddr_list, tmp_list) { | ||
2061 | int age, max_valid, max_prefered; | ||
2062 | |||
2063 | if (ifp != ift->ifpub) | ||
2064 | continue; | ||
2065 | |||
2066 | /* RFC 4941 section 3.3: | ||
2067 | * If a received option will extend the lifetime of a public | ||
2068 | * address, the lifetimes of temporary addresses should | ||
2069 | * be extended, subject to the overall constraint that no | ||
2070 | * temporary addresses should ever remain "valid" or "preferred" | ||
2071 | * for a time longer than (TEMP_VALID_LIFETIME) or | ||
2072 | * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR), respectively. | ||
2073 | */ | ||
2074 | age = (now - ift->cstamp) / HZ; | ||
2075 | max_valid = idev->cnf.temp_valid_lft - age; | ||
2076 | if (max_valid < 0) | ||
2077 | max_valid = 0; | ||
2078 | |||
2079 | max_prefered = idev->cnf.temp_prefered_lft - | ||
2080 | idev->cnf.max_desync_factor - age; | ||
2081 | if (max_prefered < 0) | ||
2082 | max_prefered = 0; | ||
2083 | |||
2084 | if (valid_lft > max_valid) | ||
2085 | valid_lft = max_valid; | ||
2086 | |||
2087 | if (prefered_lft > max_prefered) | ||
2088 | prefered_lft = max_prefered; | ||
2089 | |||
2090 | spin_lock(&ift->lock); | ||
2091 | flags = ift->flags; | ||
2092 | ift->valid_lft = valid_lft; | ||
2093 | ift->prefered_lft = prefered_lft; | ||
2094 | ift->tstamp = now; | ||
2095 | if (prefered_lft > 0) | ||
2096 | ift->flags &= ~IFA_F_DEPRECATED; | ||
2097 | |||
2098 | spin_unlock(&ift->lock); | ||
2099 | if (!(flags&IFA_F_TENTATIVE)) | ||
2100 | ipv6_ifa_notify(0, ift); | ||
2101 | } | ||
2102 | |||
2103 | if ((create || list_empty(&idev->tempaddr_list)) && | ||
2104 | idev->cnf.use_tempaddr > 0) { | ||
2105 | /* When a new public address is created as described | ||
2106 | * in [ADDRCONF], also create a new temporary address. | ||
2107 | * Also create a temporary address if it's enabled but | ||
2108 | * no temporary address currently exists. | ||
2109 | */ | ||
2110 | read_unlock_bh(&idev->lock); | ||
2111 | ipv6_create_tempaddr(ifp, NULL); | ||
2112 | } else { | ||
2113 | read_unlock_bh(&idev->lock); | ||
2114 | } | ||
2115 | } | ||
2116 | |||
2019 | void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) | 2117 | void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) |
2020 | { | 2118 | { |
2021 | struct prefix_info *pinfo; | 2119 | struct prefix_info *pinfo; |
@@ -2170,6 +2268,7 @@ ok: | |||
2170 | return; | 2268 | return; |
2171 | } | 2269 | } |
2172 | 2270 | ||
2271 | ifp->flags |= IFA_F_MANAGETEMPADDR; | ||
2173 | update_lft = 0; | 2272 | update_lft = 0; |
2174 | create = 1; | 2273 | create = 1; |
2175 | ifp->cstamp = jiffies; | 2274 | ifp->cstamp = jiffies; |
@@ -2178,9 +2277,8 @@ ok: | |||
2178 | } | 2277 | } |
2179 | 2278 | ||
2180 | if (ifp) { | 2279 | if (ifp) { |
2181 | int flags; | 2280 | u32 flags; |
2182 | unsigned long now; | 2281 | unsigned long now; |
2183 | struct inet6_ifaddr *ift; | ||
2184 | u32 stored_lft; | 2282 | u32 stored_lft; |
2185 | 2283 | ||
2186 | /* update lifetime (RFC2462 5.5.3 e) */ | 2284 | /* update lifetime (RFC2462 5.5.3 e) */ |
@@ -2221,70 +2319,8 @@ ok: | |||
2221 | } else | 2319 | } else |
2222 | spin_unlock(&ifp->lock); | 2320 | spin_unlock(&ifp->lock); |
2223 | 2321 | ||
2224 | read_lock_bh(&in6_dev->lock); | 2322 | manage_tempaddrs(in6_dev, ifp, valid_lft, prefered_lft, |
2225 | /* update all temporary addresses in the list */ | 2323 | 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 | 2324 | ||
2289 | in6_ifa_put(ifp); | 2325 | in6_ifa_put(ifp); |
2290 | addrconf_verify(0); | 2326 | addrconf_verify(0); |
@@ -2363,10 +2399,11 @@ err_exit: | |||
2363 | /* | 2399 | /* |
2364 | * Manual configuration of address on an interface | 2400 | * Manual configuration of address on an interface |
2365 | */ | 2401 | */ |
2366 | static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *pfx, | 2402 | static int inet6_addr_add(struct net *net, int ifindex, |
2403 | const struct in6_addr *pfx, | ||
2367 | const struct in6_addr *peer_pfx, | 2404 | const struct in6_addr *peer_pfx, |
2368 | unsigned int plen, __u8 ifa_flags, __u32 prefered_lft, | 2405 | unsigned int plen, __u32 ifa_flags, |
2369 | __u32 valid_lft) | 2406 | __u32 prefered_lft, __u32 valid_lft) |
2370 | { | 2407 | { |
2371 | struct inet6_ifaddr *ifp; | 2408 | struct inet6_ifaddr *ifp; |
2372 | struct inet6_dev *idev; | 2409 | struct inet6_dev *idev; |
@@ -2385,6 +2422,9 @@ static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *p | |||
2385 | if (!valid_lft || prefered_lft > valid_lft) | 2422 | if (!valid_lft || prefered_lft > valid_lft) |
2386 | return -EINVAL; | 2423 | return -EINVAL; |
2387 | 2424 | ||
2425 | if (ifa_flags & IFA_F_MANAGETEMPADDR && plen != 64) | ||
2426 | return -EINVAL; | ||
2427 | |||
2388 | dev = __dev_get_by_index(net, ifindex); | 2428 | dev = __dev_get_by_index(net, ifindex); |
2389 | if (!dev) | 2429 | if (!dev) |
2390 | return -ENODEV; | 2430 | return -ENODEV; |
@@ -2417,14 +2457,20 @@ static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *p | |||
2417 | valid_lft, prefered_lft); | 2457 | valid_lft, prefered_lft); |
2418 | 2458 | ||
2419 | if (!IS_ERR(ifp)) { | 2459 | if (!IS_ERR(ifp)) { |
2420 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, | 2460 | if (!(ifa_flags & IFA_F_NOPREFIXROUTE)) { |
2421 | expires, flags); | 2461 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, |
2462 | expires, flags); | ||
2463 | } | ||
2464 | |||
2422 | /* | 2465 | /* |
2423 | * Note that section 3.1 of RFC 4429 indicates | 2466 | * Note that section 3.1 of RFC 4429 indicates |
2424 | * that the Optimistic flag should not be set for | 2467 | * that the Optimistic flag should not be set for |
2425 | * manually configured addresses | 2468 | * manually configured addresses |
2426 | */ | 2469 | */ |
2427 | addrconf_dad_start(ifp); | 2470 | addrconf_dad_start(ifp); |
2471 | if (ifa_flags & IFA_F_MANAGETEMPADDR) | ||
2472 | manage_tempaddrs(idev, ifp, valid_lft, prefered_lft, | ||
2473 | true, jiffies); | ||
2428 | in6_ifa_put(ifp); | 2474 | in6_ifa_put(ifp); |
2429 | addrconf_verify(0); | 2475 | addrconf_verify(0); |
2430 | return 0; | 2476 | return 0; |
@@ -2611,8 +2657,18 @@ static void init_loopback(struct net_device *dev) | |||
2611 | if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) | 2657 | if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) |
2612 | continue; | 2658 | continue; |
2613 | 2659 | ||
2614 | if (sp_ifa->rt) | 2660 | if (sp_ifa->rt) { |
2615 | continue; | 2661 | /* This dst has been added to garbage list when |
2662 | * lo device down, release this obsolete dst and | ||
2663 | * reallocate a new router for ifa. | ||
2664 | */ | ||
2665 | if (sp_ifa->rt->dst.obsolete > 0) { | ||
2666 | ip6_rt_put(sp_ifa->rt); | ||
2667 | sp_ifa->rt = NULL; | ||
2668 | } else { | ||
2669 | continue; | ||
2670 | } | ||
2671 | } | ||
2616 | 2672 | ||
2617 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, false); | 2673 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, false); |
2618 | 2674 | ||
@@ -2660,7 +2716,8 @@ static void addrconf_dev_config(struct net_device *dev) | |||
2660 | (dev->type != ARPHRD_INFINIBAND) && | 2716 | (dev->type != ARPHRD_INFINIBAND) && |
2661 | (dev->type != ARPHRD_IEEE802154) && | 2717 | (dev->type != ARPHRD_IEEE802154) && |
2662 | (dev->type != ARPHRD_IEEE1394) && | 2718 | (dev->type != ARPHRD_IEEE1394) && |
2663 | (dev->type != ARPHRD_TUNNEL6)) { | 2719 | (dev->type != ARPHRD_TUNNEL6) && |
2720 | (dev->type != ARPHRD_6LOWPAN)) { | ||
2664 | /* Alas, we support only Ethernet autoconfiguration. */ | 2721 | /* Alas, we support only Ethernet autoconfiguration. */ |
2665 | return; | 2722 | return; |
2666 | } | 2723 | } |
@@ -2857,7 +2914,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2857 | } | 2914 | } |
2858 | 2915 | ||
2859 | /* | 2916 | /* |
2860 | * MTU falled under IPV6_MIN_MTU. | 2917 | * if MTU under IPV6_MIN_MTU. |
2861 | * Stop IPv6 on this interface. | 2918 | * Stop IPv6 on this interface. |
2862 | */ | 2919 | */ |
2863 | 2920 | ||
@@ -3083,7 +3140,7 @@ static void addrconf_dad_kick(struct inet6_ifaddr *ifp) | |||
3083 | if (ifp->flags & IFA_F_OPTIMISTIC) | 3140 | if (ifp->flags & IFA_F_OPTIMISTIC) |
3084 | rand_num = 0; | 3141 | rand_num = 0; |
3085 | else | 3142 | else |
3086 | rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1); | 3143 | rand_num = prandom_u32() % (idev->cnf.rtr_solicit_delay ? : 1); |
3087 | 3144 | ||
3088 | ifp->dad_probes = idev->cnf.dad_transmits; | 3145 | ifp->dad_probes = idev->cnf.dad_transmits; |
3089 | addrconf_mod_dad_timer(ifp, rand_num); | 3146 | addrconf_mod_dad_timer(ifp, rand_num); |
@@ -3096,7 +3153,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp) | |||
3096 | 3153 | ||
3097 | addrconf_join_solict(dev, &ifp->addr); | 3154 | addrconf_join_solict(dev, &ifp->addr); |
3098 | 3155 | ||
3099 | net_srandom(ifp->addr.s6_addr32[3]); | 3156 | prandom_seed((__force u32) ifp->addr.s6_addr32[3]); |
3100 | 3157 | ||
3101 | read_lock_bh(&idev->lock); | 3158 | read_lock_bh(&idev->lock); |
3102 | spin_lock(&ifp->lock); | 3159 | spin_lock(&ifp->lock); |
@@ -3178,7 +3235,8 @@ static void addrconf_dad_timer(unsigned long data) | |||
3178 | } | 3235 | } |
3179 | 3236 | ||
3180 | ifp->dad_probes--; | 3237 | ifp->dad_probes--; |
3181 | addrconf_mod_dad_timer(ifp, ifp->idev->nd_parms->retrans_time); | 3238 | addrconf_mod_dad_timer(ifp, |
3239 | NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME)); | ||
3182 | spin_unlock(&ifp->lock); | 3240 | spin_unlock(&ifp->lock); |
3183 | write_unlock(&idev->lock); | 3241 | write_unlock(&idev->lock); |
3184 | 3242 | ||
@@ -3195,7 +3253,9 @@ static bool ipv6_lonely_lladdr(struct inet6_ifaddr *ifp) | |||
3195 | struct inet6_ifaddr *ifpiter; | 3253 | struct inet6_ifaddr *ifpiter; |
3196 | struct inet6_dev *idev = ifp->idev; | 3254 | struct inet6_dev *idev = ifp->idev; |
3197 | 3255 | ||
3198 | list_for_each_entry(ifpiter, &idev->addr_list, if_list) { | 3256 | list_for_each_entry_reverse(ifpiter, &idev->addr_list, if_list) { |
3257 | if (ifpiter->scope > IFA_LINK) | ||
3258 | break; | ||
3199 | if (ifp != ifpiter && ifpiter->scope == IFA_LINK && | 3259 | if (ifp != ifpiter && ifpiter->scope == IFA_LINK && |
3200 | (ifpiter->flags & (IFA_F_PERMANENT|IFA_F_TENTATIVE| | 3260 | (ifpiter->flags & (IFA_F_PERMANENT|IFA_F_TENTATIVE| |
3201 | IFA_F_OPTIMISTIC|IFA_F_DADFAILED)) == | 3261 | IFA_F_OPTIMISTIC|IFA_F_DADFAILED)) == |
@@ -3371,7 +3431,7 @@ static int if6_seq_show(struct seq_file *seq, void *v) | |||
3371 | ifp->idev->dev->ifindex, | 3431 | ifp->idev->dev->ifindex, |
3372 | ifp->prefix_len, | 3432 | ifp->prefix_len, |
3373 | ifp->scope, | 3433 | ifp->scope, |
3374 | ifp->flags, | 3434 | (u8) ifp->flags, |
3375 | ifp->idev->dev->name); | 3435 | ifp->idev->dev->name); |
3376 | return 0; | 3436 | return 0; |
3377 | } | 3437 | } |
@@ -3518,7 +3578,7 @@ restart: | |||
3518 | !(ifp->flags&IFA_F_TENTATIVE)) { | 3578 | !(ifp->flags&IFA_F_TENTATIVE)) { |
3519 | unsigned long regen_advance = ifp->idev->cnf.regen_max_retry * | 3579 | unsigned long regen_advance = ifp->idev->cnf.regen_max_retry * |
3520 | ifp->idev->cnf.dad_transmits * | 3580 | ifp->idev->cnf.dad_transmits * |
3521 | ifp->idev->nd_parms->retrans_time / HZ; | 3581 | NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME) / HZ; |
3522 | 3582 | ||
3523 | if (age >= ifp->prefered_lft - regen_advance) { | 3583 | if (age >= ifp->prefered_lft - regen_advance) { |
3524 | struct inet6_ifaddr *ifpub = ifp->ifpub; | 3584 | struct inet6_ifaddr *ifpub = ifp->ifpub; |
@@ -3593,6 +3653,7 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { | |||
3593 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, | 3653 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, |
3594 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, | 3654 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, |
3595 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, | 3655 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, |
3656 | [IFA_FLAGS] = { .len = sizeof(u32) }, | ||
3596 | }; | 3657 | }; |
3597 | 3658 | ||
3598 | static int | 3659 | static int |
@@ -3616,16 +3677,22 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
3616 | return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); | 3677 | return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); |
3617 | } | 3678 | } |
3618 | 3679 | ||
3619 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | 3680 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, |
3620 | u32 prefered_lft, u32 valid_lft) | 3681 | u32 prefered_lft, u32 valid_lft) |
3621 | { | 3682 | { |
3622 | u32 flags; | 3683 | u32 flags; |
3623 | clock_t expires; | 3684 | clock_t expires; |
3624 | unsigned long timeout; | 3685 | unsigned long timeout; |
3686 | bool was_managetempaddr; | ||
3687 | bool had_prefixroute; | ||
3625 | 3688 | ||
3626 | if (!valid_lft || (prefered_lft > valid_lft)) | 3689 | if (!valid_lft || (prefered_lft > valid_lft)) |
3627 | return -EINVAL; | 3690 | return -EINVAL; |
3628 | 3691 | ||
3692 | if (ifa_flags & IFA_F_MANAGETEMPADDR && | ||
3693 | (ifp->flags & IFA_F_TEMPORARY || ifp->prefix_len != 64)) | ||
3694 | return -EINVAL; | ||
3695 | |||
3629 | timeout = addrconf_timeout_fixup(valid_lft, HZ); | 3696 | timeout = addrconf_timeout_fixup(valid_lft, HZ); |
3630 | if (addrconf_finite_timeout(timeout)) { | 3697 | if (addrconf_finite_timeout(timeout)) { |
3631 | expires = jiffies_to_clock_t(timeout * HZ); | 3698 | expires = jiffies_to_clock_t(timeout * HZ); |
@@ -3645,7 +3712,13 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | |||
3645 | } | 3712 | } |
3646 | 3713 | ||
3647 | spin_lock_bh(&ifp->lock); | 3714 | spin_lock_bh(&ifp->lock); |
3648 | ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS)) | ifa_flags; | 3715 | was_managetempaddr = ifp->flags & IFA_F_MANAGETEMPADDR; |
3716 | had_prefixroute = ifp->flags & IFA_F_PERMANENT && | ||
3717 | !(ifp->flags & IFA_F_NOPREFIXROUTE); | ||
3718 | ifp->flags &= ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | | ||
3719 | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR | | ||
3720 | IFA_F_NOPREFIXROUTE); | ||
3721 | ifp->flags |= ifa_flags; | ||
3649 | ifp->tstamp = jiffies; | 3722 | ifp->tstamp = jiffies; |
3650 | ifp->valid_lft = valid_lft; | 3723 | ifp->valid_lft = valid_lft; |
3651 | ifp->prefered_lft = prefered_lft; | 3724 | ifp->prefered_lft = prefered_lft; |
@@ -3654,8 +3727,30 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | |||
3654 | if (!(ifp->flags&IFA_F_TENTATIVE)) | 3727 | if (!(ifp->flags&IFA_F_TENTATIVE)) |
3655 | ipv6_ifa_notify(0, ifp); | 3728 | ipv6_ifa_notify(0, ifp); |
3656 | 3729 | ||
3657 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, ifp->idev->dev, | 3730 | if (!(ifa_flags & IFA_F_NOPREFIXROUTE)) { |
3658 | expires, flags); | 3731 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, ifp->idev->dev, |
3732 | expires, flags); | ||
3733 | } else if (had_prefixroute) { | ||
3734 | enum cleanup_prefix_rt_t action; | ||
3735 | unsigned long rt_expires; | ||
3736 | |||
3737 | write_lock_bh(&ifp->idev->lock); | ||
3738 | action = check_cleanup_prefix_route(ifp, &rt_expires); | ||
3739 | write_unlock_bh(&ifp->idev->lock); | ||
3740 | |||
3741 | if (action != CLEANUP_PREFIX_RT_NOP) { | ||
3742 | cleanup_prefix_route(ifp, rt_expires, | ||
3743 | action == CLEANUP_PREFIX_RT_DEL); | ||
3744 | } | ||
3745 | } | ||
3746 | |||
3747 | if (was_managetempaddr || ifp->flags & IFA_F_MANAGETEMPADDR) { | ||
3748 | if (was_managetempaddr && !(ifp->flags & IFA_F_MANAGETEMPADDR)) | ||
3749 | valid_lft = prefered_lft = 0; | ||
3750 | manage_tempaddrs(ifp->idev, ifp, valid_lft, prefered_lft, | ||
3751 | !was_managetempaddr, jiffies); | ||
3752 | } | ||
3753 | |||
3659 | addrconf_verify(0); | 3754 | addrconf_verify(0); |
3660 | 3755 | ||
3661 | return 0; | 3756 | return 0; |
@@ -3671,7 +3766,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
3671 | struct inet6_ifaddr *ifa; | 3766 | struct inet6_ifaddr *ifa; |
3672 | struct net_device *dev; | 3767 | struct net_device *dev; |
3673 | u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME; | 3768 | u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME; |
3674 | u8 ifa_flags; | 3769 | u32 ifa_flags; |
3675 | int err; | 3770 | int err; |
3676 | 3771 | ||
3677 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3772 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
@@ -3698,14 +3793,17 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
3698 | if (dev == NULL) | 3793 | if (dev == NULL) |
3699 | return -ENODEV; | 3794 | return -ENODEV; |
3700 | 3795 | ||
3796 | ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags; | ||
3797 | |||
3701 | /* We ignore other flags so far. */ | 3798 | /* We ignore other flags so far. */ |
3702 | ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS); | 3799 | ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR | |
3800 | IFA_F_NOPREFIXROUTE; | ||
3703 | 3801 | ||
3704 | ifa = ipv6_get_ifaddr(net, pfx, dev, 1); | 3802 | ifa = ipv6_get_ifaddr(net, pfx, dev, 1); |
3705 | if (ifa == NULL) { | 3803 | if (ifa == NULL) { |
3706 | /* | 3804 | /* |
3707 | * It would be best to check for !NLM_F_CREATE here but | 3805 | * It would be best to check for !NLM_F_CREATE here but |
3708 | * userspace alreay relies on not having to provide this. | 3806 | * userspace already relies on not having to provide this. |
3709 | */ | 3807 | */ |
3710 | return inet6_addr_add(net, ifm->ifa_index, pfx, peer_pfx, | 3808 | return inet6_addr_add(net, ifm->ifa_index, pfx, peer_pfx, |
3711 | ifm->ifa_prefixlen, ifa_flags, | 3809 | ifm->ifa_prefixlen, ifa_flags, |
@@ -3723,7 +3821,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
3723 | return err; | 3821 | return err; |
3724 | } | 3822 | } |
3725 | 3823 | ||
3726 | static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u8 flags, | 3824 | static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u32 flags, |
3727 | u8 scope, int ifindex) | 3825 | u8 scope, int ifindex) |
3728 | { | 3826 | { |
3729 | struct ifaddrmsg *ifm; | 3827 | struct ifaddrmsg *ifm; |
@@ -3766,7 +3864,8 @@ static inline int inet6_ifaddr_msgsize(void) | |||
3766 | return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) | 3864 | return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) |
3767 | + nla_total_size(16) /* IFA_LOCAL */ | 3865 | + nla_total_size(16) /* IFA_LOCAL */ |
3768 | + nla_total_size(16) /* IFA_ADDRESS */ | 3866 | + nla_total_size(16) /* IFA_ADDRESS */ |
3769 | + nla_total_size(sizeof(struct ifa_cacheinfo)); | 3867 | + nla_total_size(sizeof(struct ifa_cacheinfo)) |
3868 | + nla_total_size(4) /* IFA_FLAGS */; | ||
3770 | } | 3869 | } |
3771 | 3870 | ||
3772 | static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | 3871 | static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, |
@@ -3815,6 +3914,9 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | |||
3815 | if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) | 3914 | if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) |
3816 | goto error; | 3915 | goto error; |
3817 | 3916 | ||
3917 | if (nla_put_u32(skb, IFA_FLAGS, ifa->flags) < 0) | ||
3918 | goto error; | ||
3919 | |||
3818 | return nlmsg_end(skb, nlh); | 3920 | return nlmsg_end(skb, nlh); |
3819 | 3921 | ||
3820 | error: | 3922 | error: |
@@ -4218,7 +4320,7 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev) | |||
4218 | ci.max_reasm_len = IPV6_MAXPLEN; | 4320 | ci.max_reasm_len = IPV6_MAXPLEN; |
4219 | ci.tstamp = cstamp_delta(idev->tstamp); | 4321 | ci.tstamp = cstamp_delta(idev->tstamp); |
4220 | ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time); | 4322 | ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time); |
4221 | ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time); | 4323 | ci.retrans_time = jiffies_to_msecs(NEIGH_VAR(idev->nd_parms, RETRANS_TIME)); |
4222 | if (nla_put(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci)) | 4324 | if (nla_put(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci)) |
4223 | goto nla_put_failure; | 4325 | goto nla_put_failure; |
4224 | nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); | 4326 | nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); |
@@ -4694,6 +4796,46 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write, | |||
4694 | return ret; | 4796 | return ret; |
4695 | } | 4797 | } |
4696 | 4798 | ||
4799 | static | ||
4800 | int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write, | ||
4801 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
4802 | { | ||
4803 | int *valp = ctl->data; | ||
4804 | int ret; | ||
4805 | int old, new; | ||
4806 | |||
4807 | old = *valp; | ||
4808 | ret = proc_dointvec(ctl, write, buffer, lenp, ppos); | ||
4809 | new = *valp; | ||
4810 | |||
4811 | if (write && old != new) { | ||
4812 | struct net *net = ctl->extra2; | ||
4813 | |||
4814 | if (!rtnl_trylock()) | ||
4815 | return restart_syscall(); | ||
4816 | |||
4817 | if (valp == &net->ipv6.devconf_dflt->proxy_ndp) | ||
4818 | inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH, | ||
4819 | NETCONFA_IFINDEX_DEFAULT, | ||
4820 | net->ipv6.devconf_dflt); | ||
4821 | else if (valp == &net->ipv6.devconf_all->proxy_ndp) | ||
4822 | inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH, | ||
4823 | NETCONFA_IFINDEX_ALL, | ||
4824 | net->ipv6.devconf_all); | ||
4825 | else { | ||
4826 | struct inet6_dev *idev = ctl->extra1; | ||
4827 | |||
4828 | inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH, | ||
4829 | idev->dev->ifindex, | ||
4830 | &idev->cnf); | ||
4831 | } | ||
4832 | rtnl_unlock(); | ||
4833 | } | ||
4834 | |||
4835 | return ret; | ||
4836 | } | ||
4837 | |||
4838 | |||
4697 | static struct addrconf_sysctl_table | 4839 | static struct addrconf_sysctl_table |
4698 | { | 4840 | { |
4699 | struct ctl_table_header *sysctl_header; | 4841 | struct ctl_table_header *sysctl_header; |
@@ -4880,7 +5022,7 @@ static struct addrconf_sysctl_table | |||
4880 | .data = &ipv6_devconf.proxy_ndp, | 5022 | .data = &ipv6_devconf.proxy_ndp, |
4881 | .maxlen = sizeof(int), | 5023 | .maxlen = sizeof(int), |
4882 | .mode = 0644, | 5024 | .mode = 0644, |
4883 | .proc_handler = proc_dointvec, | 5025 | .proc_handler = addrconf_sysctl_proxy_ndp, |
4884 | }, | 5026 | }, |
4885 | { | 5027 | { |
4886 | .procname = "accept_source_route", | 5028 | .procname = "accept_source_route", |
@@ -4996,7 +5138,7 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p) | |||
4996 | 5138 | ||
4997 | static void addrconf_sysctl_register(struct inet6_dev *idev) | 5139 | static void addrconf_sysctl_register(struct inet6_dev *idev) |
4998 | { | 5140 | { |
4999 | neigh_sysctl_register(idev->dev, idev->nd_parms, "ipv6", | 5141 | neigh_sysctl_register(idev->dev, idev->nd_parms, |
5000 | &ndisc_ifinfo_sysctl_change); | 5142 | &ndisc_ifinfo_sysctl_change); |
5001 | __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, | 5143 | __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name, |
5002 | idev, &idev->cnf); | 5144 | idev, &idev->cnf); |
@@ -5129,9 +5271,7 @@ int __init addrconf_init(void) | |||
5129 | 5271 | ||
5130 | addrconf_verify(0); | 5272 | addrconf_verify(0); |
5131 | 5273 | ||
5132 | err = rtnl_af_register(&inet6_ops); | 5274 | rtnl_af_register(&inet6_ops); |
5133 | if (err < 0) | ||
5134 | goto errout_af; | ||
5135 | 5275 | ||
5136 | err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo, | 5276 | err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo, |
5137 | NULL); | 5277 | NULL); |
@@ -5155,7 +5295,6 @@ int __init addrconf_init(void) | |||
5155 | return 0; | 5295 | return 0; |
5156 | errout: | 5296 | errout: |
5157 | rtnl_af_unregister(&inet6_ops); | 5297 | rtnl_af_unregister(&inet6_ops); |
5158 | errout_af: | ||
5159 | unregister_netdevice_notifier(&ipv6_dev_notf); | 5298 | unregister_netdevice_notifier(&ipv6_dev_notf); |
5160 | errlo: | 5299 | errlo: |
5161 | unregister_pernet_subsys(&addrconf_ops); | 5300 | unregister_pernet_subsys(&addrconf_ops); |