ChangeSet 1.1982.148.17, 2005/03/03 14:39:10+09:00, [EMAIL PROTECTED]

        [IPV6] ADDRCONF: Update prefix route on address deletion.
        
        We did not delete prefix route on deletion of corresponding
        permanent address while we add prefix route on addition of
        permanent address. This was confusing.
        With this changeset, we purge prefix route or convert it to
        dynamic one, if appropriate.
        
        Signed-off-by: Hideaki YOSHIFUJI <[EMAIL PROTECTED]>



 addrconf.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 61 insertions(+), 1 deletion(-)


diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
--- a/net/ipv6/addrconf.c       2005-03-12 20:46:54 -08:00
+++ b/net/ipv6/addrconf.c       2005-03-12 20:46:54 -08:00
@@ -591,6 +591,8 @@
        struct inet6_ifaddr *ifa, **ifap;
        struct inet6_dev *idev = ifp->idev;
        int hash;
+       int deleted = 0, onlink = 0;
+       unsigned long expires = jiffies;
 
        hash = ipv6_addr_hash(&ifp->addr);
 
@@ -633,7 +635,31 @@
                        *ifap = ifa->if_next;
                        __in6_ifa_put(ifp);
                        ifa->if_next = NULL;
-                       break;
+                       if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0)
+                               break;
+                       deleted = 1;
+               } else if (ifp->flags & IFA_F_PERMANENT) {
+                       if (ipv6_prefix_equal(&ifa->addr, &ifp->addr,
+                                             ifp->prefix_len)) {
+                               if (ifa->flags & IFA_F_PERMANENT) {
+                                       onlink = 1;
+                                       if (deleted)
+                                               break;
+                               } else {
+                                       unsigned long lifetime;
+
+                                       if (!onlink)
+                                               onlink = -1;
+
+                                       spin_lock(&ifa->lock);
+                                       lifetime = min_t(unsigned long,
+                                                        ifa->valid_lft, 
0x7fffffffUL/HZ);
+                                       if (time_before(expires,
+                                                       ifa->tstamp + lifetime 
* HZ))
+                                               expires = ifa->tstamp + 
lifetime * HZ;
+                                       spin_unlock(&ifa->lock);
+                               }
+                       }
                }
        }
        write_unlock_bh(&idev->lock);
@@ -643,6 +669,40 @@
        notifier_call_chain(&inet6addr_chain,NETDEV_DOWN,ifp);
 
        addrconf_del_timer(ifp);
+
+       /*
+        * Purge or update corresponding prefix
+        *
+        * 1) we don't purge prefix here if address was not permanent.
+        *    prefix is managed by its own lifetime.
+        * 2) if there're no addresses, delete prefix.
+        * 3) if there're still other permanent address(es),
+        *    corresponding prefix is still permanent.
+        * 4) otherwise, update prefix lifetime to the
+        *    longest valid lifetime among the corresponding
+        *    addresses on the device.
+        *    Note: subsequent RA will update lifetime.
+        *
+        * --yoshfuji
+        */
+       if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) {
+               struct in6_addr prefix;
+               struct rt6_info *rt;
+
+               ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
+               rt = rt6_lookup(&prefix, NULL, ifp->idev->dev->ifindex, 1);
+
+               if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 
0)) {
+                       if (onlink == 0) {
+                               ip6_del_rt(rt, NULL, NULL);
+                               rt = NULL;
+                       } else if (!(rt->rt6i_flags & RTF_EXPIRES)) {
+                               rt->rt6i_expires = expires;
+                               rt->rt6i_flags |= RTF_EXPIRES;
+                       }
+               }
+               dst_release(&rt->u.dst);
+       }
 
        in6_ifa_put(ifp);
 }
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to