summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheloha <cheloha@cvs.openbsd.org>2020-05-13 21:34:38 +0000
committercheloha <cheloha@cvs.openbsd.org>2020-05-13 21:34:38 +0000
commite4fb65e66ab77bc59b2f2fe3776db770c2e66c52 (patch)
tree57b8cb7c728b7d0b0797d17d37d4403e2669d1ef
parent74593da698c1818da03ce6340f218a99488f3036 (diff)
bpf(4): separate descriptor non-blocking status from read timeout
If you set FIONBIO on a bpf(4) descriptor you enable non-blocking mode and also clobber any read timeout set for the descriptor. The reverse is also true: do BIOCSRTIMEOUT and you'll set a timeout and simultaneously disable non-blocking status. The two are mutually exclusive. This relationship is undocumented and might cause a bug. At the very least it makes reasoning about the code difficult. This patch adds a new member to bpf_d, bd_rnonblock, to store the non-blocking status of the descriptor. The read timeout is still kept in bd_rtout. With this in place, non-blocking status and the read timeout can coexist. Setting one state does not clear the other, and vice versa. Separating the two states also clears the way for changing the bpf(4) read timeout to use the system clock instead of ticks. More on that in a later patch. With insight from dlg@ regarding the purpose of the read timeout. ok dlg@
-rw-r--r--sys/net/bpf.c18
-rw-r--r--sys/net/bpfdesc.h3
2 files changed, 11 insertions, 10 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index fd35b5e2b04..f2a4972af9f 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bpf.c,v 1.189 2020/04/07 13:27:52 visa Exp $ */
+/* $OpenBSD: bpf.c,v 1.190 2020/05/13 21:34:37 cheloha Exp $ */
/* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
/*
@@ -379,8 +379,8 @@ bpfopen(dev_t dev, int flag, int mode, struct proc *p)
smr_init(&bd->bd_smr);
sigio_init(&bd->bd_sigio);
- if (flag & FNONBLOCK)
- bd->bd_rtout = -1;
+ bd->bd_rtout = 0; /* no timeout by default */
+ bd->bd_rnonblock = ISSET(flag, FNONBLOCK);
bpf_get(bd);
LIST_INSERT_HEAD(&bpf_d_list, bd, bd_list);
@@ -453,7 +453,7 @@ bpfread(dev_t dev, struct uio *uio, int ioflag)
* If there's a timeout, bd_rdStart is tagged when we start the read.
* we can then figure out when we're done reading.
*/
- if (d->bd_rtout != -1 && d->bd_rdStart == 0)
+ if (d->bd_rnonblock == 0 && d->bd_rdStart == 0)
d->bd_rdStart = ticks;
else
d->bd_rdStart = 0;
@@ -482,7 +482,7 @@ bpfread(dev_t dev, struct uio *uio, int ioflag)
ROTATE_BUFFERS(d);
break;
}
- if (d->bd_rtout == -1) {
+ if (d->bd_rnonblock) {
/* User requested non-blocking I/O */
error = EWOULDBLOCK;
} else {
@@ -960,9 +960,9 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
case FIONBIO: /* Non-blocking I/O */
if (*(int *)addr)
- d->bd_rtout = -1;
+ d->bd_rnonblock = 1;
else
- d->bd_rtout = 0;
+ d->bd_rnonblock = 0;
break;
case FIOASYNC: /* Send signal on receive packets */
@@ -1153,7 +1153,7 @@ bpfpoll(dev_t dev, int events, struct proc *p)
* if there's a timeout, mark the time we
* started waiting.
*/
- if (d->bd_rtout != -1 && d->bd_rdStart == 0)
+ if (d->bd_rnonblock == 0 && d->bd_rdStart == 0)
d->bd_rdStart = ticks;
selrecord(p, &d->bd_sel);
}
@@ -1193,7 +1193,7 @@ bpfkqfilter(dev_t dev, struct knote *kn)
klist_insert(klist, kn);
mtx_enter(&d->bd_mtx);
- if (d->bd_rtout != -1 && d->bd_rdStart == 0)
+ if (d->bd_rnonblock == 0 && d->bd_rdStart == 0)
d->bd_rdStart = ticks;
mtx_leave(&d->bd_mtx);
diff --git a/sys/net/bpfdesc.h b/sys/net/bpfdesc.h
index 41b65116b41..330b091b9db 100644
--- a/sys/net/bpfdesc.h
+++ b/sys/net/bpfdesc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bpfdesc.h,v 1.40 2020/01/02 16:23:01 claudio Exp $ */
+/* $OpenBSD: bpfdesc.h,v 1.41 2020/05/13 21:34:37 cheloha Exp $ */
/* $NetBSD: bpfdesc.h,v 1.11 1995/09/27 18:30:42 thorpej Exp $ */
/*
@@ -74,6 +74,7 @@ struct bpf_d {
struct bpf_if *bd_bif; /* interface descriptor */
u_long bd_rtout; /* Read timeout in 'ticks' */
u_long bd_rdStart; /* when the read started */
+ int bd_rnonblock; /* true if nonblocking reads are set */
struct bpf_program_smr
*bd_rfilter; /* read filter code */
struct bpf_program_smr