* Delete a multicast group membership by group membership pointer. * Network-layer protocol domains must use this routine. * * It is safe to call this routine if the ifp disappeared. */
| 3641 | * It is safe to call this routine if the ifp disappeared. |
| 3642 | */ |
| 3643 | void |
| 3644 | if_delmulti_ifma_flags(struct ifmultiaddr *ifma, int flags) |
| 3645 | { |
| 3646 | struct ifnet *ifp; |
| 3647 | int lastref; |
| 3648 | MCDPRINTF("%s freeing ifma: %p\n", __func__, ifma); |
| 3649 | #ifdef INET |
| 3650 | IN_MULTI_LIST_UNLOCK_ASSERT(); |
| 3651 | #endif |
| 3652 | ifp = ifma->ifma_ifp; |
| 3653 | #ifdef DIAGNOSTIC |
| 3654 | if (ifp == NULL) { |
| 3655 | printf("%s: ifma_ifp seems to be detached\n", __func__); |
| 3656 | } else { |
| 3657 | struct epoch_tracker et; |
| 3658 | struct ifnet *oifp; |
| 3659 | |
| 3660 | NET_EPOCH_ENTER(et); |
| 3661 | CK_STAILQ_FOREACH(oifp, &V_ifnet, if_link) |
| 3662 | if (ifp == oifp) |
| 3663 | break; |
| 3664 | NET_EPOCH_EXIT(et); |
| 3665 | if (ifp != oifp) |
| 3666 | ifp = NULL; |
| 3667 | } |
| 3668 | #endif |
| 3669 | /* |
| 3670 | * If and only if the ifnet instance exists: Acquire the address lock. |
| 3671 | */ |
| 3672 | if (ifp != NULL) |
| 3673 | IF_ADDR_WLOCK(ifp); |
| 3674 | |
| 3675 | lastref = if_delmulti_locked(ifp, ifma, flags); |
| 3676 | |
| 3677 | if (ifp != NULL) { |
| 3678 | /* |
| 3679 | * If and only if the ifnet instance exists: |
| 3680 | * Release the address lock. |
| 3681 | * If the group was left: update the hardware hash filter. |
| 3682 | */ |
| 3683 | IF_ADDR_WUNLOCK(ifp); |
| 3684 | if (lastref && ifp->if_ioctl != NULL) { |
| 3685 | (void)(*ifp->if_ioctl)(ifp, SIOCDELMULTI, 0); |
| 3686 | } |
| 3687 | } |
| 3688 | } |
| 3689 | |
| 3690 | /* |
| 3691 | * Perform deletion of network-layer and/or link-layer multicast address. |
no test coverage detected