svn commit: r211297 - stable/7/sys/netinet

Bjoern A. Zeeb bz at FreeBSD.org
Sat Aug 14 13:47:34 UTC 2010


Author: bz
Date: Sat Aug 14 13:47:34 2010
New Revision: 211297
URL: http://svn.freebsd.org/changeset/base/211297

Log:
  MFC r210686:
  
    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.

Modified:
  stable/7/sys/netinet/in_rmx.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/netinet/in_rmx.c
==============================================================================
--- stable/7/sys/netinet/in_rmx.c	Sat Aug 14 13:44:24 2010	(r211296)
+++ stable/7/sys/netinet/in_rmx.c	Sat Aug 14 13:47:34 2010	(r211297)
@@ -402,15 +402,35 @@ in_ifadownkill(struct radix_node *rn, vo
 	if (rt->rt_ifa == ap->ifa &&
 	    (ap->del || !(rt->rt_flags & RTF_STATIC))) {
 		/*
+		 * 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);
+		/*
 		 * 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.
+		 * Disconnect it from the tree and permit protocols
+		 * to cleanup.
 		 */
 		rt->rt_flags &= ~RTF_CLONING;
 		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;


More information about the svn-src-all mailing list