FreeBSD/sys/net/bpf.c
/*
 * Detach bpf from an interface. This involves detaching each descriptor
 * associated with the interface. Notify each descriptor as it's detached
 * so that any sleepers wake up and get ENXIO.
 */
Detach bpf from an interface. This involves detaching each descriptor
associated with the interface. Notify each descriptor as it's detached
so that any sleepers wake up and get ENXIO.
Detach bpf from an interface . This involves detaching each descriptor associated with the interface . Notify each descriptor as it ' s detached so that any sleepers wake up and get ENXIO .
void
bpfdetach(struct ifnet *ifp)
{
	struct bpf_if	*bp, *bp_temp;
	struct bpf_d	*d;
	int ndetached;
	ndetached = 0;
	BPF_LOCK();
	LIST_FOREACH_SAFE(bp, &bpf_iflist, bif_next, bp_temp) {
		if (ifp != bp->bif_ifp)
			continue;
		LIST_REMOVE(bp, bif_next);
		LIST_INSERT_HEAD(&bpf_freelist, bp, bif_next);
		ndetached++;
		BPFIF_WLOCK(bp);
		bp->bif_flags |= BPFIF_FLAG_DYING;
		BPFIF_WUNLOCK(bp);
		CTR4(KTR_NET, "%s: sheduling free for encap %d (%p) for if %p",
		    __func__, bp->bif_dlt, bp, ifp);
		while ((d = LIST_FIRST(&bp->bif_dlist)) != NULL) {
			bpf_detachd_locked(d);
			BPFD_LOCK(d);
			bpf_wakeup(d);
			BPFD_UNLOCK(d);
		}
		while ((d = LIST_FIRST(&bp->bif_wlist)) != NULL) {
			bpf_detachd_locked(d);
			BPFD_LOCK(d);
			bpf_wakeup(d);
			BPFD_UNLOCK(d);
		}
	}
	BPF_UNLOCK();
#ifdef INVARIANTS
	if (ndetached == 0)
		printf("bpfdetach: %s was not attached\n", ifp->if_xname);
#endif
}
void bpfdetach ( struct ifnet * ifp ) { struct bpf_if * bp , * bp_temp ; struct bpf_d * d ; int ndetached ; ndetached = 0 ; BPF_LOCK ( ) ; LIST_FOREACH_SAFE ( bp , & bpf_iflist , bif_next , bp_temp ) { if ( ifp != bp -> bif_ifp ) continue ; LIST_REMOVE ( bp , bif_next ) ; LIST_INSERT_HEAD ( & bpf_freelist , bp , bif_next ) ; ndetached ++ ; BPFIF_WLOCK ( bp ) ; bp -> bif_flags |= BPFIF_FLAG_DYING ; BPFIF_WUNLOCK ( bp ) ; CTR4 ( KTR_NET , " " , __func__ , bp -> bif_dlt , bp , ifp ) ; while ( ( d = LIST_FIRST ( & bp -> bif_dlist ) ) != NULL ) { bpf_detachd_locked ( d ) ; BPFD_LOCK ( d ) ; bpf_wakeup ( d ) ; BPFD_UNLOCK ( d ) ; } while ( ( d = LIST_FIRST ( & bp -> bif_wlist ) ) != NULL ) { bpf_detachd_locked ( d ) ; BPFD_LOCK ( d ) ; bpf_wakeup ( d ) ; BPFD_UNLOCK ( d ) ; } } BPF_UNLOCK ( ) ; #ifdef INVARIANTS if ( ndetached == 0 ) printf ( " \n " , ifp -> if_xname ) ; #endif }
Detach bpf from an interface.
Detach bpf from an interface .
/* Find all bpf_if struct's which reference ifp and detach them. */ /* Add to to-be-freed list */ /*
		 * Delay freeing bp till interface is detached
		 * and all routes through this interface are removed.
		 * Mark bp as detached to restrict new consumers.
		 */ /* Free common descriptors */ /* Free writer-only descriptors */