Skip to content

Commit

Permalink
ipv6 addrconf: fix preferred lifetime state-changing behavior while v…
Browse files Browse the repository at this point in the history
…alid_lft is infinity

Fixed a problem with setting the lifetime of an IPv6
address. When setting preferred_lft to a value not zero or
infinity, while valid_lft is infinity(0xffffffff) preferred
lifetime is set to forever and does not update. Therefore
preferred lifetime never becomes deprecated. valid lifetime
and preferred lifetime should be set independently, even if
valid lifetime is infinity, preferred lifetime must expire
correctly (meaning it must eventually become deprecated)

Signed-off-by: Yasushi Asano <yasushi.asano@jp.fujitsu.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Yasushi Asano authored and David S. Miller committed Jan 3, 2014
1 parent 4d231b7 commit fad8da3
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3456,7 +3456,12 @@ static void addrconf_verify(unsigned long foo)
&inet6_addr_lst[i], addr_lst) {
unsigned long age;

if (ifp->flags & IFA_F_PERMANENT)
/* When setting preferred_lft to a value not zero or
* infinity, while valid_lft is infinity
* IFA_F_PERMANENT has a non-infinity life time.
*/
if ((ifp->flags & IFA_F_PERMANENT) &&
(ifp->prefered_lft == INFINITY_LIFE_TIME))
continue;

spin_lock(&ifp->lock);
Expand All @@ -3481,7 +3486,8 @@ static void addrconf_verify(unsigned long foo)
ifp->flags |= IFA_F_DEPRECATED;
}

if (time_before(ifp->tstamp + ifp->valid_lft * HZ, next))
if ((ifp->valid_lft != INFINITY_LIFE_TIME) &&
(time_before(ifp->tstamp + ifp->valid_lft * HZ, next)))
next = ifp->tstamp + ifp->valid_lft * HZ;

spin_unlock(&ifp->lock);
Expand Down Expand Up @@ -3761,7 +3767,8 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
ifa->idev->dev->ifindex);

if (!(ifa->flags&IFA_F_PERMANENT)) {
if (!((ifa->flags&IFA_F_PERMANENT) &&
(ifa->prefered_lft == INFINITY_LIFE_TIME))) {
preferred = ifa->prefered_lft;
valid = ifa->valid_lft;
if (preferred != INFINITY_LIFE_TIME) {
Expand Down

0 comments on commit fad8da3

Please sign in to comment.