By bringing down the routes before we bring down the addresses we leak
the dst cache entries held by the addresses.

For address on an interface there is an associated input route.  When
we bring that address down we call ipv6_ifa_notify(RTM_DELADDR, ifa).

ipv6_ifa_notify will then call ip6_del_rt and release or free the
route depending on whether the route was found in the routing table or
not.

I'm not certain about the general case but in the specific case where
we are downing an interface we should always have found the route in
the routing table and the reference count should decremented with
dst_release, this is what when we remove an address from an interface.
Unfortunately because we have already call rt6_ifdown() the route is
not found in the routing table, the dst_free does not decrement the
count and is therefore unable to free the dst entry because the count
is still elevated. 

Fix this by simply moving rt6_ifdown where we flush the routes after
we have removed all of the addresses from the interface.

Signed-off-by: Eric W. Biederman <[EMAIL PROTECTED]>


---

 net/ipv6/addrconf.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

91b01e79ff7a4cc6b901af76e81e15361e25c067
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index d328d59..7461b90 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2278,7 +2278,6 @@ static int addrconf_ifdown(struct net_de
        if (dev == &loopback_dev && how == 1)
                how = 0;
 
-       rt6_ifdown(dev);
        neigh_ifdown(&nd_tbl, dev);
 
        idev = __in6_dev_get(dev);
@@ -2370,6 +2369,12 @@ static int addrconf_ifdown(struct net_de
        idev->tstamp = jiffies;
        inet6_ifinfo_notify(RTM_DELLINK, idev);
        
+       /* Step 6: Flush any remaining routes for this device.
+        * This must be done after all of the addresses are taken
+        * down or we leak dst entries.
+        */
+       rt6_ifdown(dev);
+
        /* Shot the device (if unregistered) */
 
        if (how == 1) {
-- 
1.1.4.g7830

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to