diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-11-28 10:16:09 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-11-28 10:16:09 +0000 |
commit | f5290878945fe703bba59968749d2d418bc803fc (patch) | |
tree | 8ad4d44ef9418d84222867191189e5745d5ca61a /sys/net/bpf.c | |
parent | e8e80a69d97663a785bd2d25c1ef591e5d6532c1 (diff) |
Make sure the descriptor has been removed from the interface list
before we call ifpromisc() and possibly sleep.
ok bluhm@
Diffstat (limited to 'sys/net/bpf.c')
-rw-r--r-- | sys/net/bpf.c | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 10ecea17088..affd0a4b567 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bpf.c,v 1.154 2016/11/21 09:15:40 mpi Exp $ */ +/* $OpenBSD: bpf.c,v 1.155 2016/11/28 10:16:08 mpi Exp $ */ /* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */ /* @@ -288,6 +288,23 @@ bpf_detachd(struct bpf_d *d) struct bpf_if *bp; bp = d->bd_bif; + /* Not attached. */ + if (bp == NULL) + return; + + /* Remove ``d'' from the interface's descriptor list. */ + KERNEL_ASSERT_LOCKED(); + SRPL_REMOVE_LOCKED(&bpf_d_rc, &bp->bif_dlist, d, bpf_d, bd_next); + + if (SRPL_EMPTY_LOCKED(&bp->bif_dlist)) { + /* + * Let the driver know that there are no more listeners. + */ + *bp->bif_driverp = NULL; + } + + d->bd_bif = NULL; + /* * Check if this descriptor had requested promiscuous mode. * If so, turn it off. @@ -305,19 +322,6 @@ bpf_detachd(struct bpf_d *d) */ panic("bpf: ifpromisc failed"); } - - /* Remove d from the interface's descriptor list. */ - KERNEL_ASSERT_LOCKED(); - SRPL_REMOVE_LOCKED(&bpf_d_rc, &bp->bif_dlist, d, bpf_d, bd_next); - - if (SRPL_EMPTY_LOCKED(&bp->bif_dlist)) { - /* - * Let the driver know that there are no more listeners. - */ - *d->bd_bif->bif_driverp = 0; - } - - d->bd_bif = NULL; } void @@ -372,8 +376,7 @@ bpfclose(dev_t dev, int flag, int mode, struct proc *p) d = bpfilter_lookup(minor(dev)); s = splnet(); - if (d->bd_bif) - bpf_detachd(d); + bpf_detachd(d); bpf_wakeup(d); LIST_REMOVE(d, bd_list); bpf_put(d); @@ -1033,12 +1036,10 @@ bpf_setif(struct bpf_d *d, struct ifreq *ifr) goto out; } if (candidate != d->bd_bif) { - if (d->bd_bif) - /* - * Detach if attached to something else. - */ - bpf_detachd(d); - + /* + * Detach if attached to something else. + */ + bpf_detachd(d); bpf_attachd(d, candidate); } bpf_resetd(d); |