* Perform deletion of network-layer and/or link-layer multicast address. * * Return 0 if the reference count was decremented. * Return 1 if the final reference was released, indicating that the * hardware hash filter should be reprogrammed. */
| 3695 | * hardware hash filter should be reprogrammed. |
| 3696 | */ |
| 3697 | static int |
| 3698 | if_delmulti_locked(struct ifnet *ifp, struct ifmultiaddr *ifma, int detaching) |
| 3699 | { |
| 3700 | struct ifmultiaddr *ll_ifma; |
| 3701 | |
| 3702 | if (ifp != NULL && ifma->ifma_ifp != NULL) { |
| 3703 | KASSERT(ifma->ifma_ifp == ifp, |
| 3704 | ("%s: inconsistent ifp %p", __func__, ifp)); |
| 3705 | IF_ADDR_WLOCK_ASSERT(ifp); |
| 3706 | } |
| 3707 | |
| 3708 | ifp = ifma->ifma_ifp; |
| 3709 | MCDPRINTF("%s freeing %p from %s \n", __func__, ifma, ifp ? ifp->if_xname : ""); |
| 3710 | |
| 3711 | /* |
| 3712 | * If the ifnet is detaching, null out references to ifnet, |
| 3713 | * so that upper protocol layers will notice, and not attempt |
| 3714 | * to obtain locks for an ifnet which no longer exists. The |
| 3715 | * routing socket announcement must happen before the ifnet |
| 3716 | * instance is detached from the system. |
| 3717 | */ |
| 3718 | if (detaching) { |
| 3719 | #ifdef DIAGNOSTIC |
| 3720 | printf("%s: detaching ifnet instance %p\n", __func__, ifp); |
| 3721 | #endif |
| 3722 | /* |
| 3723 | * ifp may already be nulled out if we are being reentered |
| 3724 | * to delete the ll_ifma. |
| 3725 | */ |
| 3726 | if (ifp != NULL) { |
| 3727 | rt_newmaddrmsg(RTM_DELMADDR, ifma); |
| 3728 | ifma->ifma_ifp = NULL; |
| 3729 | } |
| 3730 | } |
| 3731 | |
| 3732 | if (--ifma->ifma_refcount > 0) |
| 3733 | return 0; |
| 3734 | |
| 3735 | if (ifp != NULL && detaching == 0 && (ifma->ifma_flags & IFMA_F_ENQUEUED)) { |
| 3736 | CK_STAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifmultiaddr, ifma_link); |
| 3737 | ifma->ifma_flags &= ~IFMA_F_ENQUEUED; |
| 3738 | } |
| 3739 | /* |
| 3740 | * If this ifma is a network-layer ifma, a link-layer ifma may |
| 3741 | * have been associated with it. Release it first if so. |
| 3742 | */ |
| 3743 | ll_ifma = ifma->ifma_llifma; |
| 3744 | if (ll_ifma != NULL) { |
| 3745 | KASSERT(ifma->ifma_lladdr != NULL, |
| 3746 | ("%s: llifma w/o lladdr", __func__)); |
| 3747 | if (detaching) |
| 3748 | ll_ifma->ifma_ifp = NULL; /* XXX */ |
| 3749 | if (--ll_ifma->ifma_refcount == 0) { |
| 3750 | if (ifp != NULL) { |
| 3751 | if (ll_ifma->ifma_flags & IFMA_F_ENQUEUED) { |
| 3752 | CK_STAILQ_REMOVE(&ifp->if_multiaddrs, ll_ifma, ifmultiaddr, |
| 3753 | ifma_link); |
| 3754 | ll_ifma->ifma_flags &= ~IFMA_F_ENQUEUED; |
no test coverage detected