svn commit: r233199 - in stable/8/sys: i386/conf netinet6
John Baldwin
jhb at FreeBSD.org
Mon Mar 19 20:15:19 UTC 2012
Author: jhb
Date: Mon Mar 19 20:15:18 2012
New Revision: 233199
URL: http://svn.freebsd.org/changeset/base/233199
Log:
MFC 225096:
Fix if_addr_mtx recursion in mld6.
mld_set_version() is called only from mld_v1_input_query() and
mld_v2_input_query() both holding the if_addr_mtx lock, and then calling
into mld_v2_cancel_link_timers() acquires it the second time, which results
in mtx recursion. To avoid that, delay if_addr_mtx acquisition until after
mld_set_version() is called; while here, further reduce locking scope
to protect only the needed pieces: if_multiaddrs, in6m_lookup_locked().
Modified:
stable/8/sys/netinet6/mld6.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/boot/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/e1000/ (props changed)
stable/8/sys/i386/conf/XENHVM (props changed)
Modified: stable/8/sys/netinet6/mld6.c
==============================================================================
--- stable/8/sys/netinet6/mld6.c Mon Mar 19 19:53:53 2012 (r233198)
+++ stable/8/sys/netinet6/mld6.c Mon Mar 19 20:15:18 2012 (r233199)
@@ -681,7 +681,6 @@ mld_v1_input_query(struct ifnet *ifp, co
IN6_MULTI_LOCK();
MLD_LOCK();
- IF_ADDR_LOCK(ifp);
/*
* Switch to MLDv1 host compatibility mode.
@@ -694,6 +693,7 @@ mld_v1_input_query(struct ifnet *ifp, co
if (timer == 0)
timer = 1;
+ IF_ADDR_LOCK(ifp);
if (is_general_query) {
/*
* For each reporting group joined on this
@@ -889,7 +889,6 @@ mld_v2_input_query(struct ifnet *ifp, co
IN6_MULTI_LOCK();
MLD_LOCK();
- IF_ADDR_LOCK(ifp);
mli = MLD_IFINFO(ifp);
KASSERT(mli != NULL, ("%s: no mld_ifinfo for ifp %p", __func__, ifp));
@@ -937,14 +936,18 @@ mld_v2_input_query(struct ifnet *ifp, co
* Queries for groups we are not a member of on this
* link are simply ignored.
*/
+ IF_ADDR_LOCK(ifp);
inm = in6m_lookup_locked(ifp, &mld->mld_addr);
- if (inm == NULL)
+ if (inm == NULL) {
+ IF_ADDR_UNLOCK(ifp);
goto out_locked;
+ }
if (nsrc > 0) {
if (!ratecheck(&inm->in6m_lastgsrtv,
&V_mld_gsrdelay)) {
CTR1(KTR_MLD, "%s: GS query throttled.",
__func__);
+ IF_ADDR_UNLOCK(ifp);
goto out_locked;
}
}
@@ -962,10 +965,10 @@ mld_v2_input_query(struct ifnet *ifp, co
/* XXX Clear embedded scope ID as userland won't expect it. */
in6_clearscope(&mld->mld_addr);
+ IF_ADDR_UNLOCK(ifp);
}
out_locked:
- IF_ADDR_UNLOCK(ifp);
MLD_UNLOCK();
IN6_MULTI_UNLOCK();
More information about the svn-src-all
mailing list