Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 Apr 2010 19:51:22 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r207013 - in stable/8/sys: net netinet netinet6
Message-ID:  <201004211951.o3LJpMs9051421@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bz
Date: Wed Apr 21 19:51:22 2010
New Revision: 207013
URL: http://svn.freebsd.org/changeset/base/207013

Log:
  MFC r206481:
  
    Plug reference leaks in the link-layer code ("new-arp") that previously
    prevented the link-layer entry from being freed.
  
    In both in.c and in6.c (though that code path seems to be basically dead)
    plug a reference leak in case of a pending callout being drained.
  
    In if_ether.c consistently add a reference before resetting the callout
    and in case we canceled a pending one remove the reference for that.
    In the final case in arptimer, before freeing the expired entry, remove
    the reference again and explicitly call callout_stop() to clear the active
    flag.
  
    In nd6.c:nd6_free() we are only ever called from the callout function and
    thus need to remove the reference there as well before calling into
    llentry_free().
  
    In if_llatbl.c when freeing the entire tables make sure that in case we
    cancel a pending callout to remove the reference as well.
  
    Reviewed by:          qingli (earlier version)
    MFC after:            10 days
    Problem observed, patch tested by: simon on ipv6gw.f.o,
                          Christian Kratzer (ck cksoft.de),
                          Evgenii Davidov (dado korolev-net.ru)
  PR:			kern/144564
  Configurations still affected:	with options FLOWTABLE

Modified:
  stable/8/sys/net/if_llatbl.c
  stable/8/sys/netinet/if_ether.c
  stable/8/sys/netinet/in.c
  stable/8/sys/netinet6/in6.c
  stable/8/sys/netinet6/nd6.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/geom/sched/   (props changed)

Modified: stable/8/sys/net/if_llatbl.c
==============================================================================
--- stable/8/sys/net/if_llatbl.c	Wed Apr 21 19:48:40 2010	(r207012)
+++ stable/8/sys/net/if_llatbl.c	Wed Apr 21 19:51:22 2010	(r207013)
@@ -170,9 +170,12 @@ lltable_free(struct lltable *llt)
 
 	for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
 		LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
+			int canceled;
 
-			callout_drain(&lle->la_timer);
+			canceled = callout_drain(&lle->la_timer);
 			LLE_WLOCK(lle);
+			if (canceled)
+				LLE_REMREF(lle);
 			llentry_free(lle);
 		}
 	}

Modified: stable/8/sys/netinet/if_ether.c
==============================================================================
--- stable/8/sys/netinet/if_ether.c	Wed Apr 21 19:48:40 2010	(r207012)
+++ stable/8/sys/netinet/if_ether.c	Wed Apr 21 19:51:22 2010	(r207013)
@@ -180,6 +180,8 @@ arptimer(void *arg)
 	else {
 		if (!callout_pending(&lle->la_timer) &&
 		    callout_active(&lle->la_timer)) {
+			callout_stop(&lle->la_timer);
+			LLE_REMREF(lle);
 			(void) llentry_free(lle);
 			ARPSTAT_INC(timeouts);
 		} 
@@ -382,9 +384,14 @@ retry:
 		    EHOSTUNREACH : EHOSTDOWN;
 
 	if (renew) {
+		int canceled;
+
 		LLE_ADDREF(la);
 		la->la_expire = time_second + V_arpt_down;
-		callout_reset(&la->la_timer, hz * V_arpt_down, arptimer, la);
+		canceled = callout_reset(&la->la_timer, hz * V_arpt_down,
+		    arptimer, la);
+		if (canceled)
+			LLE_REMREF(la);
 		la->la_asked++;
 		LLE_WUNLOCK(la);
 		arprequest(ifp, NULL, &SIN(dst)->sin_addr,
@@ -694,9 +701,14 @@ match:
 		la->la_flags |= LLE_VALID;
 
 		if (!(la->la_flags & LLE_STATIC)) {
+			int canceled;
+
+			LLE_ADDREF(la);
 			la->la_expire = time_second + V_arpt_keep;
-			callout_reset(&la->la_timer, hz * V_arpt_keep,
-			    arptimer, la);
+			canceled = callout_reset(&la->la_timer,
+			    hz * V_arpt_keep, arptimer, la);
+			if (canceled)
+				LLE_REMREF(la);
 		}
 		la->la_asked = 0;
 		la->la_preempt = V_arp_maxtries;

Modified: stable/8/sys/netinet/in.c
==============================================================================
--- stable/8/sys/netinet/in.c	Wed Apr 21 19:48:40 2010	(r207012)
+++ stable/8/sys/netinet/in.c	Wed Apr 21 19:51:22 2010	(r207013)
@@ -1357,8 +1357,12 @@ in_lltable_prefix_free(struct lltable *l
 
 			if (IN_ARE_MASKED_ADDR_EQUAL((struct sockaddr_in *)L3_ADDR(lle), 
 						     pfx, msk)) {
-				callout_drain(&lle->la_timer);
+				int canceled;
+
+				canceled = callout_drain(&lle->la_timer);
 				LLE_WLOCK(lle);
+				if (canceled)
+					LLE_REMREF(lle);
 				llentry_free(lle);
 			}
 		}

Modified: stable/8/sys/netinet6/in6.c
==============================================================================
--- stable/8/sys/netinet6/in6.c	Wed Apr 21 19:48:40 2010	(r207012)
+++ stable/8/sys/netinet6/in6.c	Wed Apr 21 19:51:22 2010	(r207013)
@@ -2337,8 +2337,12 @@ in6_lltable_prefix_free(struct lltable *
 				    &((struct sockaddr_in6 *)L3_ADDR(lle))->sin6_addr, 
 				    &pfx->sin6_addr, 
 				    &msk->sin6_addr)) {
-				callout_drain(&lle->la_timer);
+				int canceled;
+
+				canceled = callout_drain(&lle->la_timer);
 				LLE_WLOCK(lle);
+				if (canceled)
+					LLE_REMREF(lle);
 				llentry_free(lle);
 			}
 		}

Modified: stable/8/sys/netinet6/nd6.c
==============================================================================
--- stable/8/sys/netinet6/nd6.c	Wed Apr 21 19:48:40 2010	(r207012)
+++ stable/8/sys/netinet6/nd6.c	Wed Apr 21 19:51:22 2010	(r207013)
@@ -1124,6 +1124,7 @@ nd6_free(struct llentry *ln, int gc)
 	ifp = ln->lle_tbl->llt_ifp;
 	IF_AFDATA_LOCK(ifp);
 	LLE_WLOCK(ln);
+	LLE_REMREF(ln);
 	llentry_free(ln);
 	IF_AFDATA_UNLOCK(ifp);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004211951.o3LJpMs9051421>