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