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);

Reply via email to