svn commit: r240309 - in stable/9/sys: net netinet netinet6
Bjoern A. Zeeb
bz at FreeBSD.org
Mon Sep 10 14:37:43 UTC 2012
On Mon, 10 Sep 2012, Gleb Smirnoff wrote:
> 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.
This breaks the KBI.
> 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;
>
--
Bjoern A. Zeeb You have to have visions!
Stop bit received. Insert coin for new address family.
More information about the svn-src-stable-9
mailing list