From owner-svn-src-all@FreeBSD.ORG Thu Feb 23 18:21:38 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4BA061065670; Thu, 23 Feb 2012 18:21:38 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2CD908FC13; Thu, 23 Feb 2012 18:21:38 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q1NILci1016959; Thu, 23 Feb 2012 18:21:38 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q1NILcnS016955; Thu, 23 Feb 2012 18:21:38 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201202231821.q1NILcnS016955@svn.freebsd.org> From: Kip Macy Date: Thu, 23 Feb 2012 18:21:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r232054 - in head/sys: net netinet netinet6 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Feb 2012 18:21:38 -0000 Author: kmacy Date: Thu Feb 23 18:21:37 2012 New Revision: 232054 URL: http://svn.freebsd.org/changeset/base/232054 Log: 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. MFC after: 2 weeks Modified: head/sys/net/if_llatbl.h head/sys/netinet/in.c head/sys/netinet6/in6.c Modified: head/sys/net/if_llatbl.h ============================================================================== --- head/sys/net/if_llatbl.h Thu Feb 23 17:57:08 2012 (r232053) +++ head/sys/net/if_llatbl.h Thu Feb 23 18:21:37 2012 (r232054) @@ -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: head/sys/netinet/in.c ============================================================================== --- head/sys/netinet/in.c Thu Feb 23 17:57:08 2012 (r232053) +++ head/sys/netinet/in.c Thu Feb 23 18:21:37 2012 (r232054) @@ -1260,6 +1260,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) { @@ -1277,25 +1291,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 ) @@ -1577,7 +1577,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: head/sys/netinet6/in6.c ============================================================================== --- head/sys/netinet6/in6.c Thu Feb 23 17:57:08 2012 (r232053) +++ head/sys/netinet6/in6.c Thu Feb 23 18:21:37 2012 (r232054) @@ -2439,6 +2439,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) { @@ -2451,6 +2465,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); @@ -2458,20 +2473,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, @@ -2713,7 +2714,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;