diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 17 |
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) | |||
1677 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | 1677 | static 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) | |||
1688 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) | 1688 | static 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) { |