Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147829637
D20070.id56690.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D20070.id56690.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D20070: Fix mutual exclusion issues in multicast socket option handling.
Attached
Detach File
Event Timeline
Log In to Comment