Author: bz
Date: Sat Jul 31 15:31:23 2010
New Revision: 210686
URL: http://svn.freebsd.org/changeset/base/210686

Log:
  MFp4 @181628:
  
  Free the rtentry after we diconnected it from the FIB and are counting
  it as rttrash.  There might still be a chance we leak it from a different
  code path but there is nothing we can do about this here.
  
  Sponsored by: ISPsystem (in February)
  Reviewed by:  julian (in February)
  MFC after:    2 weeks

Modified:
  head/sys/netinet/in_rmx.c

Modified: head/sys/netinet/in_rmx.c
==============================================================================
--- head/sys/netinet/in_rmx.c   Sat Jul 31 14:57:38 2010        (r210685)
+++ head/sys/netinet/in_rmx.c   Sat Jul 31 15:31:23 2010        (r210686)
@@ -408,14 +408,28 @@ in_ifadownkill(struct radix_node *rn, vo
        if (rt->rt_ifa == ap->ifa &&
            (ap->del || !(rt->rt_flags & RTF_STATIC))) {
                /*
-                * We need to disable the automatic prune that happens
-                * in this case in rtrequest() because it will blow
-                * away the pointers that rn_walktree() needs in order
-                * continue our descent.  We will end up deleting all
-                * the routes that rtrequest() would have in any case,
-                * so that behavior is not needed there.
+                * Aquire a reference so that it can later be freed
+                * as the refcount would be 0 here in case of at least
+                * ap->del.
+                */
+               RT_ADDREF(rt);
+               /*
+                * Disconnect it from the tree and permit protocols
+                * to cleanup.
                 */
                rtexpunge(rt);
+               /*
+                * At this point it is an rttrash node, and in case
+                * the above is the only reference we must free it.
+                * If we do not noone will have a pointer and the
+                * rtentry will be leaked forever.
+                * In case someone else holds a reference, we are
+                * fine as we only decrement the refcount. In that
+                * case if the other entity calls RT_REMREF, we
+                * will still be leaking but at least we tried.
+                */
+               RTFREE_LOCKED(rt);
+               return (0);
        }
        RT_UNLOCK(rt);
        return 0;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to