summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet/in_mcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet/in_mcast.c')
-rw-r--r--freebsd/sys/netinet/in_mcast.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/freebsd/sys/netinet/in_mcast.c b/freebsd/sys/netinet/in_mcast.c
index ff442399..cbb6c6d3 100644
--- a/freebsd/sys/netinet/in_mcast.c
+++ b/freebsd/sys/netinet/in_mcast.c
@@ -2207,7 +2207,11 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
__func__);
goto out_inp_locked;
}
- inm_acquire(imf->imf_inm);
+ /*
+ * NOTE: Refcount from in_joingroup_locked()
+ * is protecting membership.
+ */
+ ip_mfilter_insert(&imo->imo_head, imf);
} else {
CTR1(KTR_IGMPV3, "%s: merge inm state", __func__);
IN_MULTI_LIST_LOCK();
@@ -2231,8 +2235,6 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
goto out_inp_locked;
}
}
- if (is_new)
- ip_mfilter_insert(&imo->imo_head, imf);
imf_commit(imf);
imf = NULL;
@@ -2401,6 +2403,12 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
if (is_final) {
ip_mfilter_remove(&imo->imo_head, imf);
imf_leave(imf);
+
+ /*
+ * Give up the multicast address record to which
+ * the membership points.
+ */
+ (void) in_leavegroup_locked(imf->imf_inm, imf);
} else {
if (imf->imf_st[0] == MCAST_EXCLUDE) {
error = EADDRNOTAVAIL;
@@ -2455,14 +2463,8 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
out_inp_locked:
INP_WUNLOCK(inp);
- if (is_final && imf) {
- /*
- * Give up the multicast address record to which
- * the membership points.
- */
- (void) in_leavegroup_locked(imf->imf_inm, imf);
+ if (is_final && imf)
ip_mfilter_free(imf);
- }
IN_MULTI_UNLOCK();
return (error);