summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2016-11-16 14:13:00 +0000
committermpi <mpi@openbsd.org>2016-11-16 14:13:00 +0000
commit97bfac85de00b5e405b40ea8fe743fad409c3f23 (patch)
tree71e641feed427847fe6be81c91293211ca68b6dc
parentBe consistent and do not use braces for single line statements. (diff)
downloadwireguard-openbsd-97bfac85de00b5e405b40ea8fe743fad409c3f23.tar.xz
wireguard-openbsd-97bfac85de00b5e405b40ea8fe743fad409c3f23.zip
Use goto in bpf{read,write}() to ease review of locked sections.
While here properly account for used reference in bpfwrite(). ok bluhm@
-rw-r--r--sys/net/bpf.c68
1 files changed, 36 insertions, 32 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 98666d4314a..eb980d26ac9 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bpf.c,v 1.151 2016/11/16 09:00:01 mpi Exp $ */
+/* $OpenBSD: bpf.c,v 1.152 2016/11/16 14:13:00 mpi Exp $ */
/* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
/*
@@ -406,16 +406,17 @@ bpfread(dev_t dev, struct uio *uio, int ioflag)
if (d->bd_bif == NULL)
return (ENXIO);
+ s = splnet();
+ bpf_get(d);
+
/*
* Restrict application to use a buffer the same size as
* as kernel buffers.
*/
- if (uio->uio_resid != d->bd_bufsize)
- return (EINVAL);
-
- s = splnet();
-
- bpf_get(d);
+ if (uio->uio_resid != d->bd_bufsize) {
+ error = EINVAL;
+ goto out;
+ }
/*
* If there's a timeout, bd_rdStart is tagged when we start the read.
@@ -431,13 +432,12 @@ bpfread(dev_t dev, struct uio *uio, int ioflag)
* ends when the timeout expires or when enough packets
* have arrived to fill the store buffer.
*/
- while (d->bd_hbuf == 0) {
+ while (d->bd_hbuf == NULL) {
if (d->bd_bif == NULL) {
/* interface is gone */
if (d->bd_slen == 0) {
- bpf_put(d);
- splx(s);
- return (EIO);
+ error = EIO;
+ goto out;
}
ROTATE_BUFFERS(d);
break;
@@ -461,18 +461,15 @@ bpfread(dev_t dev, struct uio *uio, int ioflag)
} else
error = EWOULDBLOCK;
}
- if (error == EINTR || error == ERESTART) {
- bpf_put(d);
- splx(s);
- return (error);
- }
+ if (error == EINTR || error == ERESTART)
+ goto out;
if (error == EWOULDBLOCK) {
/*
* On a timeout, return what's in the buffer,
* which may be nothing. If there is something
* in the store buffer, we can rotate the buffers.
*/
- if (d->bd_hbuf)
+ if (d->bd_hbuf != NULL)
/*
* We filled up the buffer in between
* getting the timeout and arriving
@@ -481,9 +478,8 @@ bpfread(dev_t dev, struct uio *uio, int ioflag)
break;
if (d->bd_slen == 0) {
- bpf_put(d);
- splx(s);
- return (0);
+ error = 0;
+ goto out;
}
ROTATE_BUFFERS(d);
break;
@@ -505,7 +501,7 @@ bpfread(dev_t dev, struct uio *uio, int ioflag)
d->bd_fbuf = d->bd_hbuf;
d->bd_hbuf = NULL;
d->bd_hlen = 0;
-
+out:
bpf_put(d);
splx(s);
@@ -554,32 +550,40 @@ bpfwrite(dev_t dev, struct uio *uio, int ioflag)
struct bpf_insn *fcode = NULL;
int error, s;
struct sockaddr_storage dst;
+ u_int dlt;
d = bpfilter_lookup(minor(dev));
if (d->bd_bif == NULL)
return (ENXIO);
+ bpf_get(d);
ifp = d->bd_bif->bif_ifp;
- if ((ifp->if_flags & IFF_UP) == 0)
- return (ENETDOWN);
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ error = ENETDOWN;
+ goto out;
+ }
- if (uio->uio_resid == 0)
- return (0);
+ if (uio->uio_resid == 0) {
+ error = 0;
+ goto out;
+ }
KERNEL_ASSERT_LOCKED(); /* for accessing bd_wfilter */
bf = srp_get_locked(&d->bd_wfilter);
if (bf != NULL)
fcode = bf->bf_insns;
- error = bpf_movein(uio, d->bd_bif->bif_dlt, &m,
- (struct sockaddr *)&dst, fcode);
+ dlt = d->bd_bif->bif_dlt;
+
+ error = bpf_movein(uio, dlt, &m, (struct sockaddr *)&dst, fcode);
if (error)
- return (error);
+ goto out;
if (m->m_pkthdr.len > ifp->if_mtu) {
m_freem(m);
- return (EMSGSIZE);
+ error = EMSGSIZE;
+ goto out;
}
m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
@@ -591,9 +595,9 @@ bpfwrite(dev_t dev, struct uio *uio, int ioflag)
s = splsoftnet();
error = ifp->if_output(ifp, m, (struct sockaddr *)&dst, NULL);
splx(s);
- /*
- * The driver frees the mbuf.
- */
+
+out:
+ bpf_put(d);
return (error);
}