In article <[EMAIL PROTECTED]> (at Sun, 6 Feb 2005 22:41:45 +1100), Herbert Xu 
<[EMAIL PROTECTED]> says:

> On Sat, Feb 05, 2005 at 09:45:59PM +1100, herbert wrote:
> > 
> > Although I still think this is a bug, I'm now starting to suspect
> > that there is another bug around as well.
> > 
> > There is probably an ifp leak which in turn leads to a split dst
> > leak that allows the first bug to make its mark.
> 
> Found it.  This is what happens:
> 
> lo goes down =>
>       rt6_ifdown =>
>               eth0's local address route gets deleted
> 
> eth0 goes down =>
>       __ipv6_ifa_notify =>
>               ip6_del_rt fails so we fall through to the
>               dst_free path.  At this point the refcount
>               taken by __ipv6_ifa_notify is leaked.

Oh, you're right! Thanks.

How about this; Ignore entries addrconf_dst_alloc'ed entries in rt6_ifdown()?

Signed-off-by: Hideaki YOSHIFUJI <[EMAIL PROTECTED]>

===== include/linux/ipv6_route.h 1.6 vs edited =====
--- 1.6/include/linux/ipv6_route.h      2004-10-26 12:54:23 +09:00
+++ edited/include/linux/ipv6_route.h   2005-02-06 21:27:02 +09:00
@@ -26,6 +26,7 @@
 #define RTF_FLOW       0x02000000      /* flow significant route       */
 #define RTF_POLICY     0x04000000      /* policy route                 */
 
+#define RTF_ANYCAST    0x40000000
 #define RTF_LOCAL      0x80000000
 
 struct in6_rtmsg {
===== net/ipv6/route.c 1.105 vs edited =====
--- 1.105/net/ipv6/route.c      2005-01-15 17:44:48 +09:00
+++ edited/net/ipv6/route.c     2005-02-06 21:26:35 +09:00
@@ -1408,7 +1408,9 @@
        rt->u.dst.obsolete = -1;
 
        rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
-       if (!anycast)
+       if (anycast)
+               rt->rt6i_flags |= RTF_ANYCAST;
+       else
                rt->rt6i_flags |= RTF_LOCAL;
        rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway);
        if (rt->rt6i_nexthop == NULL) {
@@ -1427,7 +1429,8 @@
 static int fib6_ifdown(struct rt6_info *rt, void *arg)
 {
        if (((void*)rt->rt6i_dev == arg || arg == NULL) &&
-           rt != &ip6_null_entry) {
+           rt != &ip6_null_entry &&
+           !(rt->rt6i_flags & (RTF_LOCAL|RTF_ANYCAST))) {
                RT6_TRACE("deleted by ifdown %p\n", rt);
                return -1;
        }

-- 
Hideaki YOSHIFUJI @ USAGI Project <[EMAIL PROTECTED]>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to