svn commit: r240309 - in stable/9/sys: net netinet netinet6

Gleb Smirnoff glebius at FreeBSD.org
Mon Sep 10 12:02:59 UTC 2012


Author: glebius
Date: Mon Sep 10 12:02:58 2012
New Revision: 240309
URL: http://svn.freebsd.org/changeset/base/240309

Log:
  Merge r232054 by kmacy:
    When using flowtable llentrys can outlive the interface with
    which they're associated at which the lle_tbl pointer points
    to freed memory and the llt_free pointer is no longer valid.
  
    Move the free pointer in to the llentry itself and update the
    initalization sites.

Modified:
  stable/9/sys/net/if_llatbl.h
  stable/9/sys/netinet/in.c
  stable/9/sys/netinet6/in6.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/net/if_llatbl.h
==============================================================================
--- stable/9/sys/net/if_llatbl.h	Mon Sep 10 11:50:42 2012	(r240308)
+++ stable/9/sys/net/if_llatbl.h	Mon Sep 10 12:02:58 2012	(r240309)
@@ -106,7 +106,6 @@ struct llentry {
 		("negative refcnt %d", (lle)->lle_refcnt));	\
 	(lle)->lle_refcnt++;					\
 } while (0)
-
 #define	LLE_REMREF(lle)	do {					\
 	LLE_WLOCK_ASSERT(lle);					\
 	KASSERT((lle)->lle_refcnt > 1,				\
@@ -116,7 +115,7 @@ struct llentry {
 
 #define	LLE_FREE_LOCKED(lle) do {				\
 	if ((lle)->lle_refcnt <= 1)				\
-		(lle)->lle_tbl->llt_free((lle)->lle_tbl, (lle));\
+		(lle)->lle_free((lle)->lle_tbl, (lle));\
 	else {							\
 		(lle)->lle_refcnt--;				\
 		LLE_WUNLOCK(lle);				\
@@ -152,7 +151,6 @@ struct lltable {
 	int			llt_af;
 	struct ifnet		*llt_ifp;
 
-	void			(*llt_free)(struct lltable *, struct llentry *);
 	void			(*llt_prefix_free)(struct lltable *,
 				    const struct sockaddr *prefix,
 				    const struct sockaddr *mask,

Modified: stable/9/sys/netinet/in.c
==============================================================================
--- stable/9/sys/netinet/in.c	Mon Sep 10 11:50:42 2012	(r240308)
+++ stable/9/sys/netinet/in.c	Mon Sep 10 12:02:58 2012	(r240309)
@@ -1323,6 +1323,20 @@ struct in_llentry {
 	struct sockaddr_in	l3_addr4;
 };
 
+/*
+ * Deletes an address from the address table.
+ * This function is called by the timer functions
+ * such as arptimer() and nd6_llinfo_timer(), and
+ * the caller does the locking.
+ */
+static void
+in_lltable_free(struct lltable *llt, struct llentry *lle)
+{
+	LLE_WUNLOCK(lle);
+	LLE_LOCK_DESTROY(lle);
+	free(lle, M_LLTABLE);
+}
+
 static struct llentry *
 in_lltable_new(const struct sockaddr *l3addr, u_int flags)
 {
@@ -1340,25 +1354,11 @@ in_lltable_new(const struct sockaddr *l3
 	lle->base.la_expire = time_uptime; /* mark expired */
 	lle->l3_addr4 = *(const struct sockaddr_in *)l3addr;
 	lle->base.lle_refcnt = 1;
+	lle->base.lle_free = in_lltable_free;
 	LLE_LOCK_INIT(&lle->base);
 	return &lle->base;
 }
 
-/*
- * Deletes an address from the address table.
- * This function is called by the timer functions
- * such as arptimer() and nd6_llinfo_timer(), and
- * the caller does the locking.
- */
-static void
-in_lltable_free(struct lltable *llt, struct llentry *lle)
-{
-	LLE_WUNLOCK(lle);
-	LLE_LOCK_DESTROY(lle);
-	free(lle, M_LLTABLE);
-}
-
-
 #define IN_ARE_MASKED_ADDR_EQUAL(d, a, m)	(			\
 	    (((ntohl((d)->sin_addr.s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 )
 
@@ -1640,7 +1640,6 @@ in_domifattach(struct ifnet *ifp)
 
 	llt = lltable_init(ifp, AF_INET);
 	if (llt != NULL) {
-		llt->llt_free = in_lltable_free;
 		llt->llt_prefix_free = in_lltable_prefix_free;
 		llt->llt_lookup = in_lltable_lookup;
 		llt->llt_dump = in_lltable_dump;

Modified: stable/9/sys/netinet6/in6.c
==============================================================================
--- stable/9/sys/netinet6/in6.c	Mon Sep 10 11:50:42 2012	(r240308)
+++ stable/9/sys/netinet6/in6.c	Mon Sep 10 12:02:58 2012	(r240309)
@@ -2421,6 +2421,20 @@ struct in6_llentry {
 	struct sockaddr_in6	l3_addr6;
 };
 
+/*
+ * Deletes an address from the address table.
+ * This function is called by the timer functions
+ * such as arptimer() and nd6_llinfo_timer(), and
+ * the caller does the locking.
+ */
+static void
+in6_lltable_free(struct lltable *llt, struct llentry *lle)
+{
+	LLE_WUNLOCK(lle);
+	LLE_LOCK_DESTROY(lle);
+	free(lle, M_LLTABLE);
+}
+
 static struct llentry *
 in6_lltable_new(const struct sockaddr *l3addr, u_int flags)
 {
@@ -2433,6 +2447,7 @@ in6_lltable_new(const struct sockaddr *l
 
 	lle->l3_addr6 = *(const struct sockaddr_in6 *)l3addr;
 	lle->base.lle_refcnt = 1;
+	lle->base.lle_free = in6_lltable_free;
 	LLE_LOCK_INIT(&lle->base);
 	callout_init_rw(&lle->base.ln_timer_ch, &lle->base.lle_lock,
 	    CALLOUT_RETURNUNLOCKED);
@@ -2440,20 +2455,6 @@ in6_lltable_new(const struct sockaddr *l
 	return &lle->base;
 }
 
-/*
- * Deletes an address from the address table.
- * This function is called by the timer functions
- * such as arptimer() and nd6_llinfo_timer(), and
- * the caller does the locking.
- */
-static void
-in6_lltable_free(struct lltable *llt, struct llentry *lle)
-{
-	LLE_WUNLOCK(lle);
-	LLE_LOCK_DESTROY(lle);
-	free(lle, M_LLTABLE);
-}
-
 static void
 in6_lltable_prefix_free(struct lltable *llt, 
 			const struct sockaddr *prefix,
@@ -2695,7 +2696,6 @@ in6_domifattach(struct ifnet *ifp)
 	ext->scope6_id = scope6_ifattach(ifp);
 	ext->lltable = lltable_init(ifp, AF_INET6);
 	if (ext->lltable != NULL) {
-		ext->lltable->llt_free = in6_lltable_free;
 		ext->lltable->llt_prefix_free = in6_lltable_prefix_free;
 		ext->lltable->llt_lookup = in6_lltable_lookup;
 		ext->lltable->llt_dump = in6_lltable_dump;


More information about the svn-src-stable-9 mailing list