+/*
+ * Detach bpf from an interface. This involves detaching each descriptor
+ * associated with the interface, and leaving bd_bif NULL. Notify each
+ * descriptor as it's detached so that any sleepers wake up and get
+ * ENXIO.
+ */
+void
+bpfdetach(ifp)
+ struct ifnet *ifp;
+{
+ struct bpf_if *bp, *bp_prev;
+ struct bpf_d *d;
+ int s;
+
+ s = splimp();
+
+ /* Locate BPF interface information */
+ bp_prev = NULL;
+ for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
+ if (ifp == bp->bif_ifp)
+ break;
+ bp_prev = bp;
+ }
+
+#ifdef __APPLE__
+ /* Check for no BPF interface information */
+ if (bp == NULL) {
+ return;
+ }
+#endif
+
+ /* Interface wasn't attached */
+ if (bp->bif_ifp == NULL) {
+ splx(s);
+#ifndef __APPLE__
+ printf("bpfdetach: %s%d was not attached\n", ifp->if_name,
+ ifp->if_unit);
+#endif
+ return;
+ }
+
+ while ((d = bp->bif_dlist) != NULL) {
+ bpf_detachd(d);
+ bpf_wakeup(d);
+ }
+
+ if (bp_prev) {
+ bp_prev->bif_next = bp->bif_next;
+ } else {
+ bpf_iflist = bp->bif_next;
+ }
+
+ FREE(bp, M_DEVBUF);
+
+ splx(s);
+}
+