Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net Fix bpf so that select will return for a timeout (fr...
details: https://anonhg.NetBSD.org/src/rev/4862f12d9b3a
branches: trunk
changeset: 565514:4862f12d9b3a
user: darrenr <darrenr%NetBSD.org@localhost>
date: Sat Apr 10 23:31:51 2004 +0000
description:
Fix bpf so that select will return for a timeout (from FreeBSD.)
Fix the behaviour of BIOCIMMEDIATE (fix from LBL BPF code via FreeBSD.)
In bpf_mtap(), optimise the calling of bpf_filter() and catchpacket()
based on whether or not the entire packet is in one mbuf (based on
similar change FreeBSD but fixes BIOC*SEESENT issue with that.)
Copy the implementation of BIOCSSEESENT, BIOCGSEESENT by FreeBSD.
Review Assistance: Guy Harris
PRs: kern/8674, kern/12170
diffstat:
sys/net/bpf.c | 115 +++++++++++++++++++++++++++++++++++++++++------------
sys/net/bpf.h | 22 +++++----
sys/net/bpfdesc.h | 11 ++++-
3 files changed, 111 insertions(+), 37 deletions(-)
diffs (truncated from 324 to 300 lines):
diff -r 17d9f0d58682 -r 4862f12d9b3a sys/net/bpf.c
--- a/sys/net/bpf.c Sat Apr 10 23:31:41 2004 +0000
+++ b/sys/net/bpf.c Sat Apr 10 23:31:51 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bpf.c,v 1.90 2004/03/24 15:34:54 atatat Exp $ */
+/* $NetBSD: bpf.c,v 1.91 2004/04/10 23:31:51 darrenr Exp $ */
/*
* Copyright (c) 1990, 1991, 1993
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.90 2004/03/24 15:34:54 atatat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.91 2004/04/10 23:31:51 darrenr Exp $");
#include "bpfilter.h"
@@ -114,6 +114,7 @@
static void bpf_attachd __P((struct bpf_d *, struct bpf_if *));
static void bpf_detachd __P((struct bpf_d *));
static int bpf_setif __P((struct bpf_d *, struct ifreq *));
+static void bpf_timed_out __P((void *));
static __inline void
bpf_wakeup __P((struct bpf_d *));
static void catchpacket __P((struct bpf_d *, u_char *, u_int, u_int,
@@ -380,6 +381,8 @@
/* Mark "free" and do most initialization. */
memset((char *)d, 0, sizeof(*d));
d->bd_bufsize = bpf_bufsize;
+ d->bd_seesent = 1;
+ callout_init(&d->bd_callout);
return (0);
}
@@ -400,6 +403,9 @@
int s;
s = splnet();
+ if (d->bd_state == BPF_WAITING)
+ callout_stop(&d->bd_callout);
+ d->bd_state = BPF_IDLE;
if (d->bd_bif)
bpf_detachd(d);
splx(s);
@@ -429,6 +435,7 @@
int ioflag;
{
struct bpf_d *d = &bpf_dtab[minor(dev)];
+ int timed_out;
int error;
int s;
@@ -440,17 +447,17 @@
return (EINVAL);
s = splnet();
+ if (d->bd_state == BPF_WAITING)
+ callout_stop(&d->bd_callout);
+ timed_out = (d->bd_state == BPF_TIMED_OUT);
+ d->bd_state = BPF_IDLE;
/*
* If the hold buffer is empty, then do a timed sleep, which
* ends when the timeout expires or when enough packets
* have arrived to fill the store buffer.
*/
while (d->bd_hbuf == 0) {
- if (d->bd_immediate) {
- if (d->bd_slen == 0) {
- splx(s);
- return (EWOULDBLOCK);
- }
+ if ((d->bd_immediate || timed_out) && d->bd_slen != 0) {
/*
* A packet(s) either arrived since the previous
* read or arrived while we were asleep.
@@ -463,11 +470,8 @@
error = tsleep((caddr_t)d, PRINET|PCATCH, "bpf",
d->bd_rtout);
else {
- if (d->bd_rtout == -1) {
- /* User requested non-blocking I/O */
- error = EWOULDBLOCK;
- } else
- error = 0;
+ /* User requested non-blocking I/O */
+ error = EWOULDBLOCK;
}
if (error == EINTR || error == ERESTART) {
splx(s);
@@ -535,6 +539,24 @@
d->bd_sel.sel_pid = 0;
}
+
+static void
+bpf_timed_out(arg)
+ void *arg;
+{
+ struct bpf_d *d = (struct bpf_d *)arg;
+ int s;
+
+ s = splnet();
+ if (d->bd_state == BPF_WAITING) {
+ d->bd_state = BPF_TIMED_OUT;
+ if (d->bd_slen != 0)
+ bpf_wakeup(d);
+ }
+ splx(s);
+}
+
+
int
bpfwrite(dev, uio, ioflag)
dev_t dev;
@@ -631,6 +653,12 @@
struct bpf_insn **p;
#endif
+ s = splnet();
+ if (d->bd_state == BPF_WAITING)
+ callout_stop(&d->bd_callout);
+ d->bd_state = BPF_IDLE;
+ splx(s);
+
switch (cmd) {
default:
@@ -853,6 +881,20 @@
d->bd_hdrcmplt = *(u_int *)addr ? 1 : 0;
break;
+ /*
+ * Get "see sent packets" flag
+ */
+ case BIOCGSEESENT:
+ *(u_int *)addr = d->bd_seesent;
+ break;
+
+ /*
+ * Set "see sent" packets flag
+ */
+ case BIOCSSEESENT:
+ d->bd_seesent = *(u_int *)addr;
+ break;
+
case FIONBIO: /* Non-blocking I/O */
if (*(int *)addr)
d->bd_rtout = -1;
@@ -1040,10 +1082,19 @@
/*
* An imitation of the FIONREAD ioctl code.
*/
- if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0))
+ if (d->bd_hlen != 0 ||
+ ((d->bd_immediate || d->bd_state == BPF_TIMED_OUT) &&
+ d->bd_slen != 0))
revents |= events & (POLLIN | POLLRDNORM);
- else
+ else {
selrecord(p, &d->bd_sel);
+ /* Start the read timeout if necessary */
+ if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) {
+ callout_reset(&d->bd_callout, d->bd_rtout,
+ bpf_timed_out, d);
+ d->bd_state = BPF_WAITING;
+ }
+ }
}
splx(s);
@@ -1168,20 +1219,34 @@
caddr_t arg;
struct mbuf *m;
{
+ void *(*cpfn) __P((void *, const void *, size_t));
struct bpf_if *bp = (struct bpf_if *)arg;
struct bpf_d *d;
- u_int pktlen, slen;
+ u_int pktlen, slen, buflen;
struct mbuf *m0;
+ void *marg;
pktlen = 0;
for (m0 = m; m0 != 0; m0 = m0->m_next)
pktlen += m0->m_len;
+ if (pktlen == m->m_len) {
+ cpfn = memcpy;
+ marg = mtod(m, void *);
+ buflen = pktlen;
+ } else {
+ cpfn = bpf_mcpy;
+ marg = m;
+ buflen = 0;
+ }
+
for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
+ if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL))
+ continue;
++d->bd_rcount;
- slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
+ slen = bpf_filter(d->bd_filter, marg, pktlen, buflen);
if (slen != 0)
- catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcpy);
+ catchpacket(d, marg, pktlen, slen, cpfn);
}
}
@@ -1234,7 +1299,13 @@
ROTATE_BUFFERS(d);
bpf_wakeup(d);
curlen = 0;
- }
+ } else if (d->bd_immediate || d->bd_state == BPF_TIMED_OUT)
+ /*
+ * Immediate mode is set, or the read timeout has
+ * already expired during a select call. A packet
+ * arrived, so the reader should be woken up.
+ */
+ bpf_wakeup(d);
/*
* Append the bpf header.
@@ -1248,14 +1319,6 @@
*/
(*cpfn)((u_char *)hp + hdrlen, pkt, (hp->bh_caplen = totlen - hdrlen));
d->bd_slen = curlen + totlen;
-
- if (d->bd_immediate) {
- /*
- * Immediate mode is set. A packet arrived so any
- * reads should be woken up.
- */
- bpf_wakeup(d);
- }
}
/*
diff -r 17d9f0d58682 -r 4862f12d9b3a sys/net/bpf.h
--- a/sys/net/bpf.h Sat Apr 10 23:31:41 2004 +0000
+++ b/sys/net/bpf.h Sat Apr 10 23:31:51 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bpf.h,v 1.33 2004/01/22 00:32:41 jonathan Exp $ */
+/* $NetBSD: bpf.h,v 1.34 2004/04/10 23:31:52 darrenr Exp $ */
/*
* Copyright (c) 1990, 1991, 1993
@@ -102,12 +102,12 @@
* header files. If your using gcc, we assume that you
* have run fixincludes so the latter set should work.
*/
-#define BIOCGBLEN _IOR('B',102, u_int)
-#define BIOCSBLEN _IOWR('B',102, u_int)
-#define BIOCSETF _IOW('B',103, struct bpf_program)
-#define BIOCFLUSH _IO('B',104)
+#define BIOCGBLEN _IOR('B',102, u_int)
+#define BIOCSBLEN _IOWR('B',102, u_int)
+#define BIOCSETF _IOW('B',103, struct bpf_program)
+#define BIOCFLUSH _IO('B',104)
#define BIOCPROMISC _IO('B',105)
-#define BIOCGDLT _IOR('B',106, u_int)
+#define BIOCGDLT _IOR('B',106, u_int)
#define BIOCGETIF _IOR('B',107, struct ifreq)
#define BIOCSETIF _IOW('B',108, struct ifreq)
#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
@@ -117,10 +117,12 @@
#define BIOCVERSION _IOR('B',113, struct bpf_version)
#define BIOCSTCPF _IOW('B',114, struct bpf_program)
#define BIOCSUDPF _IOW('B',115, struct bpf_program)
-#define BIOCGHDRCMPLT _IOR('B',116, u_int)
-#define BIOCSHDRCMPLT _IOW('B',117, u_int)
-#define BIOCSDLT _IOW('B',118, u_int)
-#define BIOCGDLTLIST _IOWR('B',119, struct bpf_dltlist)
+#define BIOCGHDRCMPLT _IOR('B',116, u_int)
+#define BIOCSHDRCMPLT _IOW('B',117, u_int)
+#define BIOCSDLT _IOW('B',118, u_int)
+#define BIOCGDLTLIST _IOWR('B',119, struct bpf_dltlist)
+#define BIOCGSEESENT _IOR('B',120, u_int)
+#define BIOCSSEESENT _IOW('B',121, u_int)
/*
* Structure prepended to each packet.
diff -r 17d9f0d58682 -r 4862f12d9b3a sys/net/bpfdesc.h
--- a/sys/net/bpfdesc.h Sat Apr 10 23:31:41 2004 +0000
+++ b/sys/net/bpfdesc.h Sat Apr 10 23:31:51 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bpfdesc.h,v 1.16 2003/08/07 16:32:48 agc Exp $ */
+/* $NetBSD: bpfdesc.h,v 1.17 2004/04/10 23:31:52 darrenr Exp $ */
/*
* Copyright (c) 1990, 1991, 1993
@@ -41,6 +41,7 @@
#ifndef _NET_BPFDESC_H_
#define _NET_BPFDESC_H_
+#include <sys/callout.h>
#include <sys/select.h>
/*
Home |
Main Index |
Thread Index |
Old Index