Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet6/in6_pcb.c
Show First 20 Lines • Show All 796 Lines • ▼ Show 20 Lines | if ((lookupflags & INPLOOKUP_WILDCARD) == 0) { | ||||
return (match); | return (match); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
in6_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) | in6_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) | ||||
{ | { | ||||
struct inpcb *in6p; | struct inpcb *in6p; | ||||
struct in6_multi *inm; | |||||
struct in6_mfilter *imf; | |||||
struct ip6_moptions *im6o; | struct ip6_moptions *im6o; | ||||
int i, gap; | |||||
INP_INFO_WLOCK(pcbinfo); | INP_INFO_WLOCK(pcbinfo); | ||||
CK_LIST_FOREACH(in6p, pcbinfo->ipi_listhead, inp_list) { | CK_LIST_FOREACH(in6p, pcbinfo->ipi_listhead, inp_list) { | ||||
INP_WLOCK(in6p); | INP_WLOCK(in6p); | ||||
if (__predict_false(in6p->inp_flags2 & INP_FREED)) { | if (__predict_false(in6p->inp_flags2 & INP_FREED)) { | ||||
INP_WUNLOCK(in6p); | INP_WUNLOCK(in6p); | ||||
continue; | continue; | ||||
} | } | ||||
im6o = in6p->in6p_moptions; | im6o = in6p->in6p_moptions; | ||||
if ((in6p->inp_vflag & INP_IPV6) && im6o != NULL) { | if ((in6p->inp_vflag & INP_IPV6) && im6o != NULL) { | ||||
/* | /* | ||||
* Unselect the outgoing ifp for multicast if it | * Unselect the outgoing ifp for multicast if it | ||||
* is being detached. | * is being detached. | ||||
*/ | */ | ||||
if (im6o->im6o_multicast_ifp == ifp) | if (im6o->im6o_multicast_ifp == ifp) | ||||
im6o->im6o_multicast_ifp = NULL; | im6o->im6o_multicast_ifp = NULL; | ||||
/* | /* | ||||
* Drop multicast group membership if we joined | * Drop multicast group membership if we joined | ||||
* through the interface being detached. | * through the interface being detached. | ||||
*/ | */ | ||||
gap = 0; | restart: | ||||
for (i = 0; i < im6o->im6o_num_memberships; i++) { | IP6_MFILTER_FOREACH(imf, &im6o->im6o_head) { | ||||
if (im6o->im6o_membership[i]->in6m_ifp == | if ((inm = imf->im6f_in6m) == NULL) | ||||
ifp) { | continue; | ||||
in6_leavegroup(im6o->im6o_membership[i], NULL); | if (inm->in6m_ifp != ifp) | ||||
gap++; | continue; | ||||
} else if (gap != 0) { | ip6_mfilter_remove(&im6o->im6o_head, imf); | ||||
im6o->im6o_membership[i - gap] = | IN6_MULTI_LOCK_ASSERT(); | ||||
im6o->im6o_membership[i]; | in6_leavegroup_locked(inm, NULL); | ||||
ip6_mfilter_free(imf); | |||||
goto restart; | |||||
} | } | ||||
} | |||||
im6o->im6o_num_memberships -= gap; | |||||
} | } | ||||
INP_WUNLOCK(in6p); | INP_WUNLOCK(in6p); | ||||
} | } | ||||
INP_INFO_WUNLOCK(pcbinfo); | INP_INFO_WUNLOCK(pcbinfo); | ||||
} | } | ||||
/* | /* | ||||
* Check for alternatives when higher level complains | * Check for alternatives when higher level complains | ||||
▲ Show 20 Lines • Show All 529 Lines • Show Last 20 Lines |