aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6c1634507ec2..31f75ea9cb60 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1677,7 +1677,7 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
1677static void addrconf_join_anycast(struct inet6_ifaddr *ifp) 1677static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
1678{ 1678{
1679 struct in6_addr addr; 1679 struct in6_addr addr;
1680 if (ifp->prefix_len == 127) /* RFC 6164 */ 1680 if (ifp->prefix_len >= 127) /* RFC 6164 */
1681 return; 1681 return;
1682 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); 1682 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
1683 if (ipv6_addr_any(&addr)) 1683 if (ipv6_addr_any(&addr))
@@ -1688,7 +1688,7 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
1688static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) 1688static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
1689{ 1689{
1690 struct in6_addr addr; 1690 struct in6_addr addr;
1691 if (ifp->prefix_len == 127) /* RFC 6164 */ 1691 if (ifp->prefix_len >= 127) /* RFC 6164 */
1692 return; 1692 return;
1693 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); 1693 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
1694 if (ipv6_addr_any(&addr)) 1694 if (ipv6_addr_any(&addr))
@@ -3476,7 +3476,12 @@ restart:
3476 &inet6_addr_lst[i], addr_lst) { 3476 &inet6_addr_lst[i], addr_lst) {
3477 unsigned long age; 3477 unsigned long age;
3478 3478
3479 if (ifp->flags & IFA_F_PERMANENT) 3479 /* When setting preferred_lft to a value not zero or
3480 * infinity, while valid_lft is infinity
3481 * IFA_F_PERMANENT has a non-infinity life time.
3482 */
3483 if ((ifp->flags & IFA_F_PERMANENT) &&
3484 (ifp->prefered_lft == INFINITY_LIFE_TIME))
3480 continue; 3485 continue;
3481 3486
3482 spin_lock(&ifp->lock); 3487 spin_lock(&ifp->lock);
@@ -3501,7 +3506,8 @@ restart:
3501 ifp->flags |= IFA_F_DEPRECATED; 3506 ifp->flags |= IFA_F_DEPRECATED;
3502 } 3507 }
3503 3508
3504 if (time_before(ifp->tstamp + ifp->valid_lft * HZ, next)) 3509 if ((ifp->valid_lft != INFINITY_LIFE_TIME) &&
3510 (time_before(ifp->tstamp + ifp->valid_lft * HZ, next)))
3505 next = ifp->tstamp + ifp->valid_lft * HZ; 3511 next = ifp->tstamp + ifp->valid_lft * HZ;
3506 3512
3507 spin_unlock(&ifp->lock); 3513 spin_unlock(&ifp->lock);
@@ -3801,7 +3807,8 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3801 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope), 3807 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
3802 ifa->idev->dev->ifindex); 3808 ifa->idev->dev->ifindex);
3803 3809
3804 if (!(ifa->flags&IFA_F_PERMANENT)) { 3810 if (!((ifa->flags&IFA_F_PERMANENT) &&
3811 (ifa->prefered_lft == INFINITY_LIFE_TIME))) {
3805 preferred = ifa->prefered_lft; 3812 preferred = ifa->prefered_lft;
3806 valid = ifa->valid_lft; 3813 valid = ifa->valid_lft;
3807 if (preferred != INFINITY_LIFE_TIME) { 3814 if (preferred != INFINITY_LIFE_TIME) {