diff --git a/sys/net/bpf.h b/sys/net/bpf.h --- a/sys/net/bpf.h +++ b/sys/net/bpf.h @@ -428,6 +428,7 @@ bool bpf_peers_present_if(struct ifnet *); #ifdef VIMAGE int bpf_get_bp_params(struct bpf_if *, u_int *, u_int *); +void bpf_ifdetach(struct ifnet *); #endif void bpfilterattach(int); diff --git a/sys/net/bpf.c b/sys/net/bpf.c --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -2847,6 +2847,33 @@ return (0); } + +/* + * Detach descriptors on interface's vmove event. + */ +void +bpf_ifdetach(struct ifnet *ifp) +{ + struct bpf_if *bp; + struct bpf_d *d; + + BPF_LOCK(); + CK_LIST_FOREACH(bp, &bpf_iflist, bif_next) { + if (bp->bif_ifp != ifp) + continue; + + /* Detach common descriptors */ + while ((d = CK_LIST_FIRST(&bp->bif_dlist)) != NULL) { + bpf_detachd_locked(d, true); + } + + /* Detach writer-only descriptors */ + while ((d = CK_LIST_FIRST(&bp->bif_wlist)) != NULL) { + bpf_detachd_locked(d, true); + } + } + BPF_UNLOCK(); +} #endif /* diff --git a/sys/net/if.c b/sys/net/if.c --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1262,6 +1262,11 @@ static void if_vmove(struct ifnet *ifp, struct vnet *new_vnet) { + /* + * Detach BPF file descriptors from its interface. + */ + bpf_ifdetach(ifp); + /* * Detach from current vnet, but preserve LLADDR info, do not * mark as dead etc. so that the ifnet can be reattached later.