summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/ipv6/addrconf.c10
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;