diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 106 |
1 files changed, 91 insertions, 15 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e035896657bc..38274c20eaa2 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -530,6 +530,16 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
530 | 530 | ||
531 | ifa->rt = rt; | 531 | ifa->rt = rt; |
532 | 532 | ||
533 | /* | ||
534 | * part one of RFC 4429, section 3.3 | ||
535 | * We should not configure an address as | ||
536 | * optimistic if we do not yet know the link | ||
537 | * layer address of our nexhop router | ||
538 | */ | ||
539 | |||
540 | if (rt->rt6i_nexthop == NULL) | ||
541 | ifa->flags &= ~IFA_F_OPTIMISTIC; | ||
542 | |||
533 | ifa->idev = idev; | 543 | ifa->idev = idev; |
534 | in6_dev_hold(idev); | 544 | in6_dev_hold(idev); |
535 | /* For caller */ | 545 | /* For caller */ |
@@ -706,6 +716,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i | |||
706 | int tmp_plen; | 716 | int tmp_plen; |
707 | int ret = 0; | 717 | int ret = 0; |
708 | int max_addresses; | 718 | int max_addresses; |
719 | u32 addr_flags; | ||
709 | 720 | ||
710 | write_lock(&idev->lock); | 721 | write_lock(&idev->lock); |
711 | if (ift) { | 722 | if (ift) { |
@@ -763,10 +774,17 @@ retry: | |||
763 | spin_unlock_bh(&ifp->lock); | 774 | spin_unlock_bh(&ifp->lock); |
764 | 775 | ||
765 | write_unlock(&idev->lock); | 776 | write_unlock(&idev->lock); |
777 | |||
778 | addr_flags = IFA_F_TEMPORARY; | ||
779 | /* set in addrconf_prefix_rcv() */ | ||
780 | if (ifp->flags & IFA_F_OPTIMISTIC) | ||
781 | addr_flags |= IFA_F_OPTIMISTIC; | ||
782 | |||
766 | ift = !max_addresses || | 783 | ift = !max_addresses || |
767 | ipv6_count_addresses(idev) < max_addresses ? | 784 | ipv6_count_addresses(idev) < max_addresses ? |
768 | ipv6_add_addr(idev, &addr, tmp_plen, | 785 | ipv6_add_addr(idev, &addr, tmp_plen, |
769 | ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : NULL; | 786 | ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, |
787 | addr_flags) : NULL; | ||
770 | if (!ift || IS_ERR(ift)) { | 788 | if (!ift || IS_ERR(ift)) { |
771 | in6_ifa_put(ifp); | 789 | in6_ifa_put(ifp); |
772 | in6_dev_put(idev); | 790 | in6_dev_put(idev); |
@@ -898,13 +916,14 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
898 | * - Tentative Address (RFC2462 section 5.4) | 916 | * - Tentative Address (RFC2462 section 5.4) |
899 | * - A tentative address is not considered | 917 | * - A tentative address is not considered |
900 | * "assigned to an interface" in the traditional | 918 | * "assigned to an interface" in the traditional |
901 | * sense. | 919 | * sense, unless it is also flagged as optimistic. |
902 | * - Candidate Source Address (section 4) | 920 | * - Candidate Source Address (section 4) |
903 | * - In any case, anycast addresses, multicast | 921 | * - In any case, anycast addresses, multicast |
904 | * addresses, and the unspecified address MUST | 922 | * addresses, and the unspecified address MUST |
905 | * NOT be included in a candidate set. | 923 | * NOT be included in a candidate set. |
906 | */ | 924 | */ |
907 | if (ifa->flags & IFA_F_TENTATIVE) | 925 | if ((ifa->flags & IFA_F_TENTATIVE) && |
926 | (!(ifa->flags & IFA_F_OPTIMISTIC))) | ||
908 | continue; | 927 | continue; |
909 | if (unlikely(score.addr_type == IPV6_ADDR_ANY || | 928 | if (unlikely(score.addr_type == IPV6_ADDR_ANY || |
910 | score.addr_type & IPV6_ADDR_MULTICAST)) { | 929 | score.addr_type & IPV6_ADDR_MULTICAST)) { |
@@ -963,15 +982,17 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
963 | } | 982 | } |
964 | } | 983 | } |
965 | 984 | ||
966 | /* Rule 3: Avoid deprecated address */ | 985 | /* Rule 3: Avoid deprecated and optimistic addresses */ |
967 | if (hiscore.rule < 3) { | 986 | if (hiscore.rule < 3) { |
968 | if (ipv6_saddr_preferred(hiscore.addr_type) || | 987 | if (ipv6_saddr_preferred(hiscore.addr_type) || |
969 | !(ifa_result->flags & IFA_F_DEPRECATED)) | 988 | (((ifa_result->flags & |
989 | (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0))) | ||
970 | hiscore.attrs |= IPV6_SADDR_SCORE_PREFERRED; | 990 | hiscore.attrs |= IPV6_SADDR_SCORE_PREFERRED; |
971 | hiscore.rule++; | 991 | hiscore.rule++; |
972 | } | 992 | } |
973 | if (ipv6_saddr_preferred(score.addr_type) || | 993 | if (ipv6_saddr_preferred(score.addr_type) || |
974 | !(ifa->flags & IFA_F_DEPRECATED)) { | 994 | (((ifa_result->flags & |
995 | (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0))) { | ||
975 | score.attrs |= IPV6_SADDR_SCORE_PREFERRED; | 996 | score.attrs |= IPV6_SADDR_SCORE_PREFERRED; |
976 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) { | 997 | if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) { |
977 | score.rule = 3; | 998 | score.rule = 3; |
@@ -1111,7 +1132,8 @@ int ipv6_get_saddr(struct dst_entry *dst, | |||
1111 | 1132 | ||
1112 | EXPORT_SYMBOL(ipv6_get_saddr); | 1133 | EXPORT_SYMBOL(ipv6_get_saddr); |
1113 | 1134 | ||
1114 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) | 1135 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, |
1136 | unsigned char banned_flags) | ||
1115 | { | 1137 | { |
1116 | struct inet6_dev *idev; | 1138 | struct inet6_dev *idev; |
1117 | int err = -EADDRNOTAVAIL; | 1139 | int err = -EADDRNOTAVAIL; |
@@ -1122,7 +1144,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) | |||
1122 | 1144 | ||
1123 | read_lock_bh(&idev->lock); | 1145 | read_lock_bh(&idev->lock); |
1124 | for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { | 1146 | for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { |
1125 | if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { | 1147 | if (ifp->scope == IFA_LINK && !(ifp->flags & banned_flags)) { |
1126 | ipv6_addr_copy(addr, &ifp->addr); | 1148 | ipv6_addr_copy(addr, &ifp->addr); |
1127 | err = 0; | 1149 | err = 0; |
1128 | break; | 1150 | break; |
@@ -1674,6 +1696,13 @@ ok: | |||
1674 | 1696 | ||
1675 | if (ifp == NULL && valid_lft) { | 1697 | if (ifp == NULL && valid_lft) { |
1676 | int max_addresses = in6_dev->cnf.max_addresses; | 1698 | int max_addresses = in6_dev->cnf.max_addresses; |
1699 | u32 addr_flags = 0; | ||
1700 | |||
1701 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | ||
1702 | if (in6_dev->cnf.optimistic_dad && | ||
1703 | !ipv6_devconf.forwarding) | ||
1704 | addr_flags = IFA_F_OPTIMISTIC; | ||
1705 | #endif | ||
1677 | 1706 | ||
1678 | /* Do not allow to create too much of autoconfigured | 1707 | /* Do not allow to create too much of autoconfigured |
1679 | * addresses; this would be too easy way to crash kernel. | 1708 | * addresses; this would be too easy way to crash kernel. |
@@ -1681,7 +1710,8 @@ ok: | |||
1681 | if (!max_addresses || | 1710 | if (!max_addresses || |
1682 | ipv6_count_addresses(in6_dev) < max_addresses) | 1711 | ipv6_count_addresses(in6_dev) < max_addresses) |
1683 | ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len, | 1712 | ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len, |
1684 | addr_type&IPV6_ADDR_SCOPE_MASK, 0); | 1713 | addr_type&IPV6_ADDR_SCOPE_MASK, |
1714 | addr_flags); | ||
1685 | 1715 | ||
1686 | if (!ifp || IS_ERR(ifp)) { | 1716 | if (!ifp || IS_ERR(ifp)) { |
1687 | in6_dev_put(in6_dev); | 1717 | in6_dev_put(in6_dev); |
@@ -1889,6 +1919,11 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | |||
1889 | 1919 | ||
1890 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, | 1920 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, |
1891 | jiffies_to_clock_t(valid_lft * HZ), flags); | 1921 | jiffies_to_clock_t(valid_lft * HZ), flags); |
1922 | /* | ||
1923 | * Note that section 3.1 of RFC 4429 indicates | ||
1924 | * that the Optimistic flag should not be set for | ||
1925 | * manually configured addresses | ||
1926 | */ | ||
1892 | addrconf_dad_start(ifp, 0); | 1927 | addrconf_dad_start(ifp, 0); |
1893 | in6_ifa_put(ifp); | 1928 | in6_ifa_put(ifp); |
1894 | addrconf_verify(0); | 1929 | addrconf_verify(0); |
@@ -2065,8 +2100,16 @@ static void init_loopback(struct net_device *dev) | |||
2065 | static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr) | 2100 | static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr) |
2066 | { | 2101 | { |
2067 | struct inet6_ifaddr * ifp; | 2102 | struct inet6_ifaddr * ifp; |
2103 | u32 addr_flags = IFA_F_PERMANENT; | ||
2104 | |||
2105 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | ||
2106 | if (idev->cnf.optimistic_dad && | ||
2107 | !ipv6_devconf.forwarding) | ||
2108 | addr_flags |= IFA_F_OPTIMISTIC; | ||
2109 | #endif | ||
2068 | 2110 | ||
2069 | ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, IFA_F_PERMANENT); | 2111 | |
2112 | ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, addr_flags); | ||
2070 | if (!IS_ERR(ifp)) { | 2113 | if (!IS_ERR(ifp)) { |
2071 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, idev->dev, 0, 0); | 2114 | addrconf_prefix_route(&ifp->addr, ifp->prefix_len, idev->dev, 0, 0); |
2072 | addrconf_dad_start(ifp, 0); | 2115 | addrconf_dad_start(ifp, 0); |
@@ -2134,7 +2177,7 @@ ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) | |||
2134 | { | 2177 | { |
2135 | struct in6_addr lladdr; | 2178 | struct in6_addr lladdr; |
2136 | 2179 | ||
2137 | if (!ipv6_get_lladdr(link_dev, &lladdr)) { | 2180 | if (!ipv6_get_lladdr(link_dev, &lladdr, IFA_F_TENTATIVE)) { |
2138 | addrconf_add_linklocal(idev, &lladdr); | 2181 | addrconf_add_linklocal(idev, &lladdr); |
2139 | return 0; | 2182 | return 0; |
2140 | } | 2183 | } |
@@ -2479,7 +2522,11 @@ static void addrconf_dad_kick(struct inet6_ifaddr *ifp) | |||
2479 | unsigned long rand_num; | 2522 | unsigned long rand_num; |
2480 | struct inet6_dev *idev = ifp->idev; | 2523 | struct inet6_dev *idev = ifp->idev; |
2481 | 2524 | ||
2482 | rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1); | 2525 | if (ifp->flags & IFA_F_OPTIMISTIC) |
2526 | rand_num = 0; | ||
2527 | else | ||
2528 | rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1); | ||
2529 | |||
2483 | ifp->probes = idev->cnf.dad_transmits; | 2530 | ifp->probes = idev->cnf.dad_transmits; |
2484 | addrconf_mod_timer(ifp, AC_DAD, rand_num); | 2531 | addrconf_mod_timer(ifp, AC_DAD, rand_num); |
2485 | } | 2532 | } |
@@ -2501,7 +2548,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) | |||
2501 | if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || | 2548 | if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || |
2502 | !(ifp->flags&IFA_F_TENTATIVE) || | 2549 | !(ifp->flags&IFA_F_TENTATIVE) || |
2503 | ifp->flags & IFA_F_NODAD) { | 2550 | ifp->flags & IFA_F_NODAD) { |
2504 | ifp->flags &= ~IFA_F_TENTATIVE; | 2551 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC); |
2505 | spin_unlock_bh(&ifp->lock); | 2552 | spin_unlock_bh(&ifp->lock); |
2506 | read_unlock_bh(&idev->lock); | 2553 | read_unlock_bh(&idev->lock); |
2507 | 2554 | ||
@@ -2521,6 +2568,14 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) | |||
2521 | addrconf_dad_stop(ifp); | 2568 | addrconf_dad_stop(ifp); |
2522 | return; | 2569 | return; |
2523 | } | 2570 | } |
2571 | |||
2572 | /* | ||
2573 | * Optimistic nodes can start receiving | ||
2574 | * Frames right away | ||
2575 | */ | ||
2576 | if(ifp->flags & IFA_F_OPTIMISTIC) | ||
2577 | ip6_ins_rt(ifp->rt); | ||
2578 | |||
2524 | addrconf_dad_kick(ifp); | 2579 | addrconf_dad_kick(ifp); |
2525 | spin_unlock_bh(&ifp->lock); | 2580 | spin_unlock_bh(&ifp->lock); |
2526 | out: | 2581 | out: |
@@ -2545,7 +2600,7 @@ static void addrconf_dad_timer(unsigned long data) | |||
2545 | * DAD was successful | 2600 | * DAD was successful |
2546 | */ | 2601 | */ |
2547 | 2602 | ||
2548 | ifp->flags &= ~IFA_F_TENTATIVE; | 2603 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC); |
2549 | spin_unlock_bh(&ifp->lock); | 2604 | spin_unlock_bh(&ifp->lock); |
2550 | read_unlock_bh(&idev->lock); | 2605 | read_unlock_bh(&idev->lock); |
2551 | 2606 | ||
@@ -3364,6 +3419,9 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | |||
3364 | #endif | 3419 | #endif |
3365 | array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; | 3420 | array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; |
3366 | array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route; | 3421 | array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route; |
3422 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | ||
3423 | array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad; | ||
3424 | #endif | ||
3367 | } | 3425 | } |
3368 | 3426 | ||
3369 | static inline size_t inet6_if_nlmsg_size(void) | 3427 | static inline size_t inet6_if_nlmsg_size(void) |
@@ -3578,7 +3636,14 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
3578 | 3636 | ||
3579 | switch (event) { | 3637 | switch (event) { |
3580 | case RTM_NEWADDR: | 3638 | case RTM_NEWADDR: |
3581 | ip6_ins_rt(ifp->rt); | 3639 | /* |
3640 | * If the address was optimistic | ||
3641 | * we inserted the route at the start of | ||
3642 | * our DAD process, so we don't need | ||
3643 | * to do it again | ||
3644 | */ | ||
3645 | if (!(ifp->rt->rt6i_node)) | ||
3646 | ip6_ins_rt(ifp->rt); | ||
3582 | if (ifp->idev->cnf.forwarding) | 3647 | if (ifp->idev->cnf.forwarding) |
3583 | addrconf_join_anycast(ifp); | 3648 | addrconf_join_anycast(ifp); |
3584 | break; | 3649 | break; |
@@ -3899,6 +3964,17 @@ static struct addrconf_sysctl_table | |||
3899 | .mode = 0644, | 3964 | .mode = 0644, |
3900 | .proc_handler = &proc_dointvec, | 3965 | .proc_handler = &proc_dointvec, |
3901 | }, | 3966 | }, |
3967 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | ||
3968 | { | ||
3969 | .ctl_name = CTL_UNNUMBERED, | ||
3970 | .procname = "optimistic_dad", | ||
3971 | .data = &ipv6_devconf.optimistic_dad, | ||
3972 | .maxlen = sizeof(int), | ||
3973 | .mode = 0644, | ||
3974 | .proc_handler = &proc_dointvec, | ||
3975 | |||
3976 | }, | ||
3977 | #endif | ||
3902 | { | 3978 | { |
3903 | .ctl_name = 0, /* sentinel */ | 3979 | .ctl_name = 0, /* sentinel */ |
3904 | } | 3980 | } |