diff options
| -rw-r--r-- | net/ipv6/addrconf.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index da0f07e21e3f..d7b03196725f 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1174,6 +1174,7 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg, ipv6_link_dev_addr(idev, ifa); if (ifa->flags&IFA_F_TEMPORARY) { + /* manage_tempaddrs() relies on addresses being added to the head */ list_add(&ifa->tmp_list, &idev->tempaddr_list); in6_ifa_hold(ifa); } @@ -2602,8 +2603,10 @@ static void manage_tempaddrs(struct inet6_dev *idev, __u32 valid_lft, __u32 prefered_lft, bool create, unsigned long now) { - u32 flags; + u32 orig_prefered_lft = prefered_lft; struct inet6_ifaddr *ift; + bool reset_done = false; + u32 flags; read_lock_bh(&idev->lock); /* update all temporary addresses in the list */ @@ -2638,6 +2641,11 @@ static void manage_tempaddrs(struct inet6_dev *idev, prefered_lft = max_prefered; spin_lock(&ift->lock); + /* the first match is the most recent temp address */ + if (!reset_done && orig_prefered_lft > 0) { + ift->regen_count = 0; + reset_done = true; + } flags = ift->flags; ift->valid_lft = valid_lft; ift->prefered_lft = prefered_lft; |
