On Tue, Nov 22, 2016 at 11:54:47AM +0100, Martin Pieuchot wrote: > Next extract diff that tweaks bpf_detachd(). > > The goal here is to remove ``d'' from the list and NULLify ``d->bd_bif'' > before calling ifpromisc(). > > The reason is that ifpromisc() can sleep. Think USB ;) So we'll have to > release the mutex before calling it. So we want to make sure ``d'' is no > longer in the interface descriptor list at this point. > > ok?
OK bluhm@ > > Index: net/bpf.c > =================================================================== > RCS file: /cvs/src/sys/net/bpf.c,v > retrieving revision 1.154 > diff -u -p -r1.154 bpf.c > --- net/bpf.c 21 Nov 2016 09:15:40 -0000 1.154 > +++ net/bpf.c 22 Nov 2016 10:47:05 -0000 > @@ -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, > > 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 > 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);