summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2012-02-23 18:21:37 +0000
committerkmacy <kmacy@FreeBSD.org>2012-02-23 18:21:37 +0000
commita99e9d281db6624cf9b88f07759a77f7b2d96a33 (patch)
tree3a2da57fb6f6af971e7fb849770dc0f9b231bca2 /sys/netinet6
parentffbbf1cb2c6c124090347c8c43c4eefb65ae1bd5 (diff)
downloadFreeBSD-src-a99e9d281db6624cf9b88f07759a77f7b2d96a33.zip
FreeBSD-src-a99e9d281db6624cf9b88f07759a77f7b2d96a33.tar.gz
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
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 0b22a1c..ca491b8 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -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 *l3addr, u_int flags)
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 *l3addr, u_int flags)
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;
OpenPOWER on IntegriCloud