Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163400999
D20070.id57400.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D20070.id57400.diff
View Options
Index: head/sys/netinet/in_mcast.c
===================================================================
--- head/sys/netinet/in_mcast.c
+++ head/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,7 +2541,7 @@
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];
@@ -2569,6 +2553,7 @@
out_inp_locked:
INP_WUNLOCK(inp);
+ IN_MULTI_UNLOCK();
return (error);
}
@@ -2646,8 +2631,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)
@@ -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);
}
Index: head/sys/netinet6/in6_mcast.c
===================================================================
--- head/sys/netinet6/in6_mcast.c
+++ head/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
@@ -2483,6 +2469,7 @@
out_in6p_locked:
INP_WUNLOCK(inp);
+ IN6_MULTI_UNLOCK();
return (error);
}
@@ -2528,8 +2515,6 @@
/*
* Atomically set source filters on a socket for an IPv6 multicast group.
- *
- * SMPng: NOTE: Potentially calls malloc(M_WAITOK) with Giant held.
*/
static int
in6p_set_source_filters(struct inpcb *inp, struct sockopt *sopt)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 23, 9:22 PM (9 h, 31 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35415982
Default Alt Text
D20070.id57400.diff (7 KB)
Attached To
Mode
D20070: Fix mutual exclusion issues in multicast socket option handling.
Attached
Detach File
Event Timeline
Log In to Comment