[Midnightbsd-cvs] src [8040] trunk/sys: When using flowtable llentrys can outlive the interface with
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Thu Sep 15 16:49:28 EDT 2016
Revision: 8040
http://svnweb.midnightbsd.org/src/?rev=8040
Author: laffer1
Date: 2016-09-15 16:49:28 -0400 (Thu, 15 Sep 2016)
Log Message:
-----------
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 Paths:
--------------
trunk/sys/net/if_llatbl.h
trunk/sys/netinet/in.c
trunk/sys/netinet6/in6.c
Modified: trunk/sys/net/if_llatbl.h
===================================================================
--- trunk/sys/net/if_llatbl.h 2016-09-15 20:48:17 UTC (rev 8039)
+++ trunk/sys/net/if_llatbl.h 2016-09-15 20:49:28 UTC (rev 8040)
@@ -106,7 +106,6 @@
("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 @@
#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 @@
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: trunk/sys/netinet/in.c
===================================================================
--- trunk/sys/netinet/in.c 2016-09-15 20:48:17 UTC (rev 8039)
+++ trunk/sys/netinet/in.c 2016-09-15 20:49:28 UTC (rev 8040)
@@ -1323,6 +1323,20 @@
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 @@
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 @@
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: trunk/sys/netinet6/in6.c
===================================================================
--- trunk/sys/netinet6/in6.c 2016-09-15 20:48:17 UTC (rev 8039)
+++ trunk/sys/netinet6/in6.c 2016-09-15 20:49:28 UTC (rev 8040)
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__MBSDID("$MidnightBSD: src/sys/netinet6/in6.c,v 1.9 2013/01/17 23:29:40 laffer1 Exp $");
+__MBSDID("$MidnightBSD$");
#include "opt_compat.h"
#include "opt_inet.h"
@@ -2433,6 +2433,20 @@
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)
{
@@ -2445,6 +2459,7 @@
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);
@@ -2452,21 +2467,7 @@
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,
const struct sockaddr *mask,
@@ -2707,7 +2708,6 @@
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 Midnightbsd-cvs
mailing list