]> git.hungrycats.org Git - linux/commitdiff
[IPV6]: Make sure temporary addresses are regenerated properly.
authorHideaki Yoshifuji <yoshfuji@linux-ipv6.org>
Sun, 2 Mar 2003 17:12:02 +0000 (09:12 -0800)
committerDavid S. Miller <davem@nuts.ninka.net>
Sun, 2 Mar 2003 17:12:02 +0000 (09:12 -0800)
net/ipv6/addrconf.c

index 8717c05abca84b95168c2e1c30f12fb62afc8af8..b9b9f4a3f4d57d56005a4dd9c210198c400609e6 100644 (file)
@@ -2015,6 +2015,9 @@ restart:
                write_lock(&addrconf_hash_lock);
                for (ifp=inet6_addr_lst[i]; ifp; ifp=ifp->lst_next) {
                        unsigned long age;
+#ifdef CONFIG_IPV6_PRIVACY
+                       unsigned long regen_advance;
+#endif
 
                        if (ifp->flags & IFA_F_PERMANENT)
                                continue;
@@ -2022,6 +2025,12 @@ restart:
                        spin_lock(&ifp->lock);
                        age = (now - ifp->tstamp) / HZ;
 
+#ifdef CONFIG_IPV6_PRIVACY
+                       regen_advance = ifp->idev->cnf.regen_max_retry * 
+                                       ifp->idev->cnf.dad_transmits * 
+                                       ifp->idev->nd_parms->retrans_time / HZ;
+#endif
+
                        if (age >= ifp->valid_lft) {
                                spin_unlock(&ifp->lock);
                                in6_ifa_hold(ifp);
@@ -2050,6 +2059,28 @@ restart:
                                        in6_ifa_put(ifp);
                                        goto restart;
                                }
+#ifdef CONFIG_IPV6_PRIVACY
+                       } else if ((ifp->flags&IFA_F_TEMPORARY) &&
+                                  !(ifp->flags&IFA_F_TENTATIVE)) {
+                               if (age >= ifp->prefered_lft - regen_advance) {
+                                       struct inet6_ifaddr *ifpub = ifp->ifpub;
+                                       if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
+                                               next = ifp->tstamp + ifp->prefered_lft * HZ;
+                                       if (!ifp->regen_count && ifpub) {
+                                               ifp->regen_count++;
+                                               in6_ifa_hold(ifp);
+                                               in6_ifa_hold(ifpub);
+                                               spin_unlock(&ifp->lock);
+                                               write_unlock(&addrconf_hash_lock);
+                                               ipv6_create_tempaddr(ifpub, ifp);
+                                               in6_ifa_put(ifpub);
+                                               in6_ifa_put(ifp);
+                                               goto restart;
+                                       }
+                               } else if (time_before(ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ, next))
+                                       next = ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ;
+                               spin_unlock(&ifp->lock);
+#endif
                        } else {
                                /* ifp->prefered_lft <= ifp->valid_lft */
                                if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))