Merge branch 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6
[pandora-kernel.git] / net / ipv6 / addrconf.c
index 324fac3..e048ec6 100644 (file)
@@ -243,7 +243,7 @@ static inline bool addrconf_qdisc_ok(const struct net_device *dev)
 /* Check if a route is valid prefix route */
 static inline int addrconf_is_prefix_route(const struct rt6_info *rt)
 {
-       return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0);
+       return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0;
 }
 
 static void addrconf_del_timer(struct inet6_ifaddr *ifp)
@@ -836,7 +836,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
 {
        struct inet6_dev *idev = ifp->idev;
        struct in6_addr addr, *tmpaddr;
-       unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp;
+       unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp, age;
        unsigned long regen_advance;
        int tmp_plen;
        int ret = 0;
@@ -886,12 +886,13 @@ retry:
                goto out;
        }
        memcpy(&addr.s6_addr[8], idev->rndid, 8);
+       age = (jiffies - ifp->tstamp) / HZ;
        tmp_valid_lft = min_t(__u32,
                              ifp->valid_lft,
-                             idev->cnf.temp_valid_lft);
+                             idev->cnf.temp_valid_lft + age);
        tmp_prefered_lft = min_t(__u32,
                                 ifp->prefered_lft,
-                                idev->cnf.temp_prefered_lft -
+                                idev->cnf.temp_prefered_lft + age -
                                 idev->cnf.max_desync_factor);
        tmp_plen = ifp->prefix_len;
        max_addresses = idev->cnf.max_addresses;
@@ -1426,8 +1427,10 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
 {
        struct inet6_dev *idev = ifp->idev;
 
-       if (addrconf_dad_end(ifp))
+       if (addrconf_dad_end(ifp)) {
+               in6_ifa_put(ifp);
                return;
+       }
 
        if (net_ratelimit())
                printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n",
@@ -1544,7 +1547,7 @@ static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev)
        return 0;
 }
 
-int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
+static int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
 {
        if (addr == 0)
                return -1;
@@ -1560,7 +1563,6 @@ int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
        memcpy(eui + 4, &addr, 4);
        return 0;
 }
-EXPORT_SYMBOL(__ipv6_isatap_ifid);
 
 static int addrconf_ifid_sit(u8 *eui, struct net_device *dev)
 {
@@ -2022,10 +2024,11 @@ ok:
                                        ipv6_ifa_notify(0, ift);
                        }
 
-                       if (create && in6_dev->cnf.use_tempaddr > 0) {
+                       if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) {
                                /*
                                 * When a new public address is created as described in [ADDRCONF],
-                                * also create a new temporary address.
+                                * also create a new temporary address. Also create a temporary
+                                * address if it's enabled but no temporary address currently exists.
                                 */
                                read_unlock_bh(&in6_dev->lock);
                                ipv6_create_tempaddr(ifp, NULL);
@@ -2964,7 +2967,8 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
           start sending router solicitations.
         */
 
-       if (ifp->idev->cnf.forwarding == 0 &&
+       if ((ifp->idev->cnf.forwarding == 0 ||
+            ifp->idev->cnf.forwarding == 2) &&
            ifp->idev->cnf.rtr_solicits > 0 &&
            (dev->flags&IFF_LOOPBACK) == 0 &&
            (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {