| 831 | } |
| 832 | |
| 833 | void |
| 834 | in6_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) |
| 835 | { |
| 836 | struct inpcb *inp; |
| 837 | struct in6_multi *inm; |
| 838 | struct in6_mfilter *imf; |
| 839 | struct ip6_moptions *im6o; |
| 840 | |
| 841 | INP_INFO_WLOCK(pcbinfo); |
| 842 | CK_LIST_FOREACH(inp, pcbinfo->ipi_listhead, inp_list) { |
| 843 | INP_WLOCK(inp); |
| 844 | if (__predict_false(inp->inp_flags2 & INP_FREED)) { |
| 845 | INP_WUNLOCK(inp); |
| 846 | continue; |
| 847 | } |
| 848 | im6o = inp->in6p_moptions; |
| 849 | if ((inp->inp_vflag & INP_IPV6) && im6o != NULL) { |
| 850 | /* |
| 851 | * Unselect the outgoing ifp for multicast if it |
| 852 | * is being detached. |
| 853 | */ |
| 854 | if (im6o->im6o_multicast_ifp == ifp) |
| 855 | im6o->im6o_multicast_ifp = NULL; |
| 856 | /* |
| 857 | * Drop multicast group membership if we joined |
| 858 | * through the interface being detached. |
| 859 | */ |
| 860 | restart: |
| 861 | IP6_MFILTER_FOREACH(imf, &im6o->im6o_head) { |
| 862 | if ((inm = imf->im6f_in6m) == NULL) |
| 863 | continue; |
| 864 | if (inm->in6m_ifp != ifp) |
| 865 | continue; |
| 866 | ip6_mfilter_remove(&im6o->im6o_head, imf); |
| 867 | IN6_MULTI_LOCK_ASSERT(); |
| 868 | in6_leavegroup_locked(inm, NULL); |
| 869 | ip6_mfilter_free(imf); |
| 870 | goto restart; |
| 871 | } |
| 872 | } |
| 873 | INP_WUNLOCK(inp); |
| 874 | } |
| 875 | INP_INFO_WUNLOCK(pcbinfo); |
| 876 | } |
| 877 | |
| 878 | /* |
| 879 | * Check for alternatives when higher level complains |
no test coverage detected