On Mon, Nov 14, 2016 at 10:07:30AM +0100, Martin Pieuchot wrote:
> Here's another extracted diff to move forward. Let bpf_allocbufs()
> fail when allocating memory, this way we can call it while holding
> a mutex.
>
> ok?
OK bluhm@
>
> Index: net/bpf.c
> ===================================================================
> RCS file: /cvs/src/sys/net/bpf.c,v
> retrieving revision 1.150
> diff -u -p -r1.150 bpf.c
> --- net/bpf.c 16 Oct 2016 18:05:41 -0000 1.150
> +++ net/bpf.c 14 Nov 2016 09:02:51 -0000
> @@ -92,7 +92,7 @@ int bpf_maxbufsize = BPF_MAXBUFSIZE;
> struct bpf_if *bpf_iflist;
> LIST_HEAD(, bpf_d) bpf_d_list;
>
> -void bpf_allocbufs(struct bpf_d *);
> +int bpf_allocbufs(struct bpf_d *);
> void bpf_ifname(struct ifnet *, struct ifreq *);
> int _bpf_mtap(caddr_t, const struct mbuf *, u_int,
> void (*)(const void *, void *, size_t));
> @@ -996,6 +996,7 @@ int
> bpf_setif(struct bpf_d *d, struct ifreq *ifr)
> {
> struct bpf_if *bp, *candidate = NULL;
> + int error = 0;
> int s;
>
> /*
> @@ -1012,30 +1013,33 @@ bpf_setif(struct bpf_d *d, struct ifreq
> candidate = bp;
> }
>
> - if (candidate != NULL) {
> - /*
> - * Allocate the packet buffers if we need to.
> - * If we're already attached to requested interface,
> - * just flush the buffer.
> - */
> - if (d->bd_sbuf == NULL)
> - bpf_allocbufs(d);
> - s = splnet();
> - if (candidate != d->bd_bif) {
> - if (d->bd_bif)
> - /*
> - * Detach if attached to something else.
> - */
> - bpf_detachd(d);
> + /* Not found. */
> + if (candidate == NULL)
> + return (ENXIO);
>
> - bpf_attachd(d, candidate);
> - }
> - bpf_reset_d(d);
> - splx(s);
> - return (0);
> + /*
> + * Allocate the packet buffers if we need to.
> + * If we're already attached to requested interface,
> + * just flush the buffer.
> + */
> + s = splnet();
> + if (d->bd_sbuf == NULL) {
> + if ((error = bpf_allocbufs(d)))
> + goto out;
> }
> - /* Not found. */
> - return (ENXIO);
> + if (candidate != d->bd_bif) {
> + if (d->bd_bif)
> + /*
> + * Detach if attached to something else.
> + */
> + bpf_detachd(d);
> +
> + bpf_attachd(d, candidate);
> + }
> + bpf_reset_d(d);
> +out:
> + splx(s);
> + return (error);
> }
>
> /*
> @@ -1434,13 +1438,23 @@ bpf_catchpacket(struct bpf_d *d, u_char
> /*
> * Initialize all nonzero fields of a descriptor.
> */
> -void
> +int
> bpf_allocbufs(struct bpf_d *d)
> {
> - d->bd_fbuf = malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
> - d->bd_sbuf = malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
> + d->bd_fbuf = malloc(d->bd_bufsize, M_DEVBUF, M_NOWAIT);
> + if (d->bd_fbuf == NULL)
> + return (ENOMEM);
> +
> + d->bd_sbuf = malloc(d->bd_bufsize, M_DEVBUF, M_NOWAIT);
> + if (d->bd_sbuf == NULL) {
> + free(d->bd_fbuf, M_DEVBUF, d->bd_bufsize);
> + return (ENOMEM);
> + }
> +
> d->bd_slen = 0;
> d->bd_hlen = 0;
> +
> + return (0);
> }
>
> void