diff options
Diffstat (limited to 'freebsd/sys/netinet/in_mcast.c')
-rw-r--r-- | freebsd/sys/netinet/in_mcast.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/freebsd/sys/netinet/in_mcast.c b/freebsd/sys/netinet/in_mcast.c index 6d748f1f..4112046c 100644 --- a/freebsd/sys/netinet/in_mcast.c +++ b/freebsd/sys/netinet/in_mcast.c @@ -140,7 +140,9 @@ static int in_getmulti(struct ifnet *, const struct in_addr *, struct in_multi **); static int inm_get_source(struct in_multi *inm, const in_addr_t haddr, const int noalloc, struct ip_msource **pims); +#ifdef KTR static int inm_is_ifp_detached(const struct in_multi *); +#endif static int inm_merge(struct in_multi *, /*const*/ struct in_mfilter *); static void inm_purge(struct in_multi *); static void inm_reap(struct in_multi *); @@ -181,6 +183,7 @@ static SYSCTL_NODE(_net_inet_ip_mcast, OID_AUTO, filters, CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_ip_mcast_filters, "Per-interface stack-wide source filters"); +#ifdef KTR /* * Inline function which wraps assertions for a valid ifp. * The ifnet layer will set the ifma's ifp pointer to NULL if the ifp @@ -203,6 +206,7 @@ inm_is_ifp_detached(const struct in_multi *inm) return (ifp == NULL); } +#endif /* * Initialize an in_mfilter structure to a known state at t0, t1 @@ -1444,7 +1448,7 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) error = inm_merge(inm, imf); if (error) { CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__); - goto out_imf_rollback; + goto out_in_multi_locked; } CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__); @@ -1452,6 +1456,8 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) if (error) CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__); +out_in_multi_locked: + IN_MULTI_UNLOCK(); out_imf_rollback: @@ -2092,8 +2098,12 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt) if (is_new) { error = in_joingroup_locked(ifp, &gsa->sin.sin_addr, imf, &inm); - if (error) + if (error) { + CTR1(KTR_IGMPV3, "%s: in_joingroup_locked failed", + __func__); + IN_MULTI_UNLOCK(); goto out_imo_free; + } imo->imo_membership[idx] = inm; } else { CTR1(KTR_IGMPV3, "%s: merge inm state", __func__); @@ -2101,20 +2111,21 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt) if (error) { CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__); - goto out_imf_rollback; + goto out_in_multi_locked; } CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__); error = igmp_change_state(inm); if (error) { CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__); - goto out_imf_rollback; + goto out_in_multi_locked; } } +out_in_multi_locked: + IN_MULTI_UNLOCK(); -out_imf_rollback: INP_WLOCK_ASSERT(inp); if (error) { imf_rollback(imf); @@ -2318,7 +2329,7 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt) if (error) { CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__); - goto out_imf_rollback; + goto out_in_multi_locked; } CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__); @@ -2329,9 +2340,10 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt) } } +out_in_multi_locked: + IN_MULTI_UNLOCK(); -out_imf_rollback: if (error) imf_rollback(imf); else @@ -2565,7 +2577,7 @@ inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt) error = inm_merge(inm, imf); if (error) { CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__); - goto out_imf_rollback; + goto out_in_multi_locked; } CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__); @@ -2573,6 +2585,8 @@ inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt) if (error) CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__); +out_in_multi_locked: + IN_MULTI_UNLOCK(); out_imf_rollback: |