Page MenuHomeFreeBSD

D20070.id56690.diff
No OneTemporary

D20070.id56690.diff

Index: sys/netinet/in_mcast.c
===================================================================
--- sys/netinet/in_mcast.c
+++ sys/netinet/in_mcast.c
@@ -1534,6 +1534,7 @@
/*
* Check if we are actually a member of this group.
*/
+ IN_MULTI_LOCK();
imo = inp_findmoptions(inp);
idx = imo_match_group(imo, ifp, &gsa->sa);
if (idx == -1 || imo->imo_mfilters == NULL) {
@@ -1593,14 +1594,13 @@
/*
* Begin state merge transaction at IGMP layer.
*/
- IN_MULTI_LOCK();
CTR1(KTR_IGMPV3, "%s: merge inm state", __func__);
IN_MULTI_LIST_LOCK();
error = inm_merge(inm, imf);
if (error) {
CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__);
IN_MULTI_LIST_UNLOCK();
- goto out_in_multi_locked;
+ goto out_imf_rollback;
}
CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__);
@@ -1609,9 +1609,6 @@
if (error)
CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__);
-out_in_multi_locked:
-
- IN_MULTI_UNLOCK();
out_imf_rollback:
if (error)
imf_rollback(imf);
@@ -1622,6 +1619,7 @@
out_inp_locked:
INP_WUNLOCK(inp);
+ IN_MULTI_UNLOCK();
return (error);
}
@@ -1680,10 +1678,10 @@
static void
inp_gcmoptions(struct ip_moptions *imo)
{
- struct in_mfilter *imf;
+ struct in_mfilter *imf;
struct in_multi *inm;
struct ifnet *ifp;
- size_t idx, nmships;
+ size_t idx, nmships;
nmships = imo->imo_num_memberships;
for (idx = 0; idx < nmships; ++idx) {
@@ -2142,12 +2140,12 @@
CTR2(KTR_IGMPV3, "%s: unknown sopt_name %d",
__func__, sopt->sopt_name);
return (EOPNOTSUPP);
- break;
}
if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0)
return (EADDRNOTAVAIL);
+ IN_MULTI_LOCK();
imo = inp_findmoptions(inp);
idx = imo_match_group(imo, ifp, &gsa->sa);
if (idx == -1) {
@@ -2272,10 +2270,6 @@
/*
* Begin state merge transaction at IGMP layer.
*/
- in_pcbref(inp);
- INP_WUNLOCK(inp);
- IN_MULTI_LOCK();
-
if (is_new) {
error = in_joingroup_locked(ifp, &gsa->sin.sin_addr, imf,
&inm);
@@ -2286,6 +2280,8 @@
goto out_imo_free;
}
inm_acquire(inm);
+ KASSERT(imo->imo_membership[idx] == NULL,
+ ("%s: imo_membership already allocated", __func__));
imo->imo_membership[idx] = inm;
} else {
CTR1(KTR_IGMPV3, "%s: merge inm state", __func__);
@@ -2295,7 +2291,7 @@
CTR1(KTR_IGMPV3, "%s: failed to merge inm state",
__func__);
IN_MULTI_LIST_UNLOCK();
- goto out_in_multi_locked;
+ goto out_imf_rollback;
}
CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__);
error = igmp_change_state(inm);
@@ -2303,16 +2299,11 @@
if (error) {
CTR1(KTR_IGMPV3, "%s: failed igmp downcall",
__func__);
- goto out_in_multi_locked;
+ goto out_imf_rollback;
}
}
-out_in_multi_locked:
-
- IN_MULTI_UNLOCK();
- INP_WLOCK(inp);
- if (in_pcbrele_wlocked(inp))
- return (ENXIO);
+out_imf_rollback:
if (error) {
imf_rollback(imf);
if (is_new)
@@ -2337,6 +2328,7 @@
out_inp_locked:
INP_WUNLOCK(inp);
+ IN_MULTI_UNLOCK();
return (error);
}
@@ -2463,6 +2455,7 @@
/*
* Find the membership in the membership array.
*/
+ IN_MULTI_LOCK();
imo = inp_findmoptions(inp);
idx = imo_match_group(imo, ifp, &gsa->sa);
if (idx == -1) {
@@ -2510,9 +2503,6 @@
/*
* Begin state merge transaction at IGMP layer.
*/
- in_pcbref(inp);
- INP_WUNLOCK(inp);
- IN_MULTI_LOCK();
if (is_final) {
/*
@@ -2528,7 +2518,7 @@
CTR1(KTR_IGMPV3, "%s: failed to merge inm state",
__func__);
IN_MULTI_LIST_UNLOCK();
- goto out_in_multi_locked;
+ goto out_imf_rollback;
}
CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__);
@@ -2540,13 +2530,7 @@
}
}
-out_in_multi_locked:
-
- IN_MULTI_UNLOCK();
- INP_WLOCK(inp);
- if (in_pcbrele_wlocked(inp))
- return (ENXIO);
-
+out_imf_rollback:
if (error)
imf_rollback(imf);
else
@@ -2557,11 +2541,12 @@
if (is_final) {
/* Remove the gap in the membership and filter array. */
KASSERT(RB_EMPTY(&imf->imf_sources),
- ("%s: imf_sources not empty", __func__));
+ ("%s: imf_sources (%p %p %zu) not empty", __func__, imf, imo, idx));
for (++idx; idx < imo->imo_num_memberships; ++idx) {
imo->imo_membership[idx - 1] = imo->imo_membership[idx];
imo->imo_mfilters[idx - 1] = imo->imo_mfilters[idx];
}
+ imo->imo_membership[idx - 1] = NULL;
imf_init(&imo->imo_mfilters[idx - 1], MCAST_UNDEFINED,
MCAST_EXCLUDE);
imo->imo_num_memberships--;
@@ -2569,6 +2554,7 @@
out_inp_locked:
INP_WUNLOCK(inp);
+ IN_MULTI_UNLOCK();
return (error);
}
@@ -2646,8 +2632,6 @@
/*
* Atomically set source filters on a socket for an IPv4 multicast group.
- *
- * SMPng: NOTE: Potentially calls malloc(M_WAITOK) with Giant held.
*/
static int
inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt)
@@ -2671,7 +2655,6 @@
if ((msfr.msfr_fmode != MCAST_EXCLUDE &&
msfr.msfr_fmode != MCAST_INCLUDE))
- return (EINVAL);
if (msfr.msfr_group.ss_family != AF_INET ||
msfr.msfr_group.ss_len != sizeof(struct sockaddr_in))
@@ -2694,6 +2677,7 @@
* Take the INP write lock.
* Check if this socket is a member of this group.
*/
+ IN_MULTI_LOCK();
imo = inp_findmoptions(inp);
idx = imo_match_group(imo, ifp, &gsa->sa);
if (idx == -1 || imo->imo_mfilters == NULL) {
@@ -2778,7 +2762,6 @@
goto out_imf_rollback;
INP_WLOCK_ASSERT(inp);
- IN_MULTI_LOCK();
/*
* Begin state merge transaction at IGMP layer.
@@ -2789,7 +2772,7 @@
if (error) {
CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__);
IN_MULTI_LIST_UNLOCK();
- goto out_in_multi_locked;
+ goto out_imf_rollback;
}
CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__);
@@ -2798,10 +2781,6 @@
if (error)
CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__);
-out_in_multi_locked:
-
- IN_MULTI_UNLOCK();
-
out_imf_rollback:
if (error)
imf_rollback(imf);
@@ -2812,6 +2791,7 @@
out_inp_locked:
INP_WUNLOCK(inp);
+ IN_MULTI_UNLOCK();
return (error);
}
@@ -2939,14 +2919,18 @@
case IP_ADD_SOURCE_MEMBERSHIP:
case MCAST_JOIN_GROUP:
case MCAST_JOIN_SOURCE_GROUP:
+ CTR1(KTR_IGMPV3, "%s: inp_join_group start", __func__);
error = inp_join_group(inp, sopt);
+ CTR2(KTR_IGMPV3, "%s: inp_join_group end (%d)", __func__, error);
break;
case IP_DROP_MEMBERSHIP:
case IP_DROP_SOURCE_MEMBERSHIP:
case MCAST_LEAVE_GROUP:
case MCAST_LEAVE_SOURCE_GROUP:
+ CTR1(KTR_IGMPV3, "%s: inp_leave_group start", __func__);
error = inp_leave_group(inp, sopt);
+ CTR2(KTR_IGMPV3, "%s: inp_leave_group end (%d)", __func__, error);
break;
case IP_BLOCK_SOURCE:
Index: sys/netinet6/in6_mcast.c
===================================================================
--- sys/netinet6/in6_mcast.c
+++ sys/netinet6/in6_mcast.c
@@ -2052,6 +2052,7 @@
*/
(void)in6_setscope(&gsa->sin6.sin6_addr, ifp, NULL);
+ IN6_MULTI_LOCK();
imo = in6p_findmoptions(inp);
idx = im6o_match_group(imo, ifp, &gsa->sa);
if (idx == -1) {
@@ -2171,10 +2172,6 @@
/*
* Begin state merge transaction at MLD layer.
*/
- in_pcbref(inp);
- INP_WUNLOCK(inp);
- IN6_MULTI_LOCK();
-
if (is_new) {
error = in6_joingroup_locked(ifp, &gsa->sin6.sin6_addr, imf,
&inm, 0);
@@ -2204,10 +2201,6 @@
IN6_MULTI_LIST_UNLOCK();
}
- IN6_MULTI_UNLOCK();
- INP_WLOCK(inp);
- if (in_pcbrele_wlocked(inp))
- return (ENXIO);
if (error) {
im6f_rollback(imf);
if (is_new)
@@ -2232,6 +2225,7 @@
out_in6p_locked:
INP_WUNLOCK(inp);
+ IN6_MULTI_UNLOCK();
in6m_release_list_deferred(&inmh);
return (error);
}
@@ -2381,6 +2375,7 @@
/*
* Find the membership in the membership array.
*/
+ IN6_MULTI_LOCK();
imo = in6p_findmoptions(inp);
idx = im6o_match_group(imo, ifp, &gsa->sa);
if (idx == -1) {
@@ -2429,10 +2424,6 @@
/*
* Begin state merge transaction at MLD layer.
*/
- in_pcbref(inp);
- INP_WUNLOCK(inp);
- IN6_MULTI_LOCK();
-
if (is_final) {
/*
* Give up the multicast address record to which
@@ -2456,11 +2447,6 @@
IN6_MULTI_LIST_UNLOCK();
}
- IN6_MULTI_UNLOCK();
- INP_WLOCK(inp);
- if (in_pcbrele_wlocked(inp))
- return (ENXIO);
-
if (error)
im6f_rollback(imf);
else
@@ -2476,6 +2462,7 @@
imo->im6o_membership[idx - 1] = imo->im6o_membership[idx];
imo->im6o_mfilters[idx - 1] = imo->im6o_mfilters[idx];
}
+ imo->im6o_membership[idx - 1] = NULL;
im6f_init(&imo->im6o_mfilters[idx - 1], MCAST_UNDEFINED,
MCAST_EXCLUDE);
imo->im6o_num_memberships--;
@@ -2483,6 +2470,7 @@
out_in6p_locked:
INP_WUNLOCK(inp);
+ IN6_MULTI_UNLOCK();
return (error);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 15, 12:09 AM (2 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29693617
Default Alt Text
D20070.id56690.diff (8 KB)

Event Timeline