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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to