Date: Mon, 10 Sep 2012 12:02:59 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r240309 - in stable/9/sys: net netinet netinet6 Message-ID: <201209101202.q8AC2xqE049573@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209101202.q8AC2xqE049573>