diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 7c7f6e84d9e..e8c9aa7ce4f 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -2849,6 +2849,33 @@ bpf_get_bp_params(struct bpf_if *bp, u_int *bif_dlt, u_int *bif_hdrlen) 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/bpf.h b/sys/net/bpf.h index 991d50bcd68..c4132d2e633 100644 --- a/sys/net/bpf.h +++ b/sys/net/bpf.h @@ -431,6 +431,7 @@ void bpfdetach(struct ifnet *); 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/if.c b/sys/net/if.c index ad8dd9703c5..4bc626b2de7 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1266,6 +1266,13 @@ finish_vnet_shutdown: static void if_vmove(struct ifnet *ifp, struct vnet *new_vnet) { +#ifdef DEV_BPF + /* + * Detach BPF file descriptors from its interface. + */ + bpf_ifdetach(ifp); +#endif + /* * Detach from current vnet, but preserve LLADDR info, do not * mark as dead etc. so that the ifnet can be reattached later.