Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 07 Nov 2002 01:17:46 +0900 (JST)
From:      Noritoshi Demizu <demizu@dd.iij4u.or.jp>
To:        pete@he.iki.fi
Cc:        freebsd-net@FreeBSD.ORG
Subject:   Re: bpf
Message-ID:  <20021107.011746.41626604.noritosi@demizu.org>
In-Reply-To: <05af01c2856a$f103c960$862a40c1@PHE> <03fe01c28386$186fed80$862a40c1@PHE>
References:  <03fe01c28386$186fed80$862a40c1@PHE> <20021103225402.GA28812@tp.databus.com> <05af01c2856a$f103c960$862a40c1@PHE>

next in thread | previous in thread | raw e-mail | index | archive | help
 > I believe the select operation on bpf is not functioning as supposed to.
 > I'm calling select with 100ms timeout. The bpf interface is listening to
 > an interface with constant packet rate, so it's certain that multiple
 > packets have been received during the select call. However the fd for
 > the bpf device is not set until the bpf buffer is full. (which might be
 > several seconds away since I'm using fairly large bpf buffers)

How about to call ioctl(fd, BIOCSRTIMEOUT, &timeval) ?
I think select(2) sets the fd for the bpf if the bpf buffer is full,
or if the bpf buffer is not empty after timed out.

If you also want select(2) sets the fd for the bpf in the case where
the bpf buffer is empty after timed out (I guess you do not want...:-),
you might want the following patch.


Actually, I had a different problem when I use pcap/bpf on pthread
environment; The fourth argument 'read-timeout' of pcap_open_live()
does not work when the bpf buffer is empty.  The following patch
solved my problem.  I think it could also be applied to your case.

In the read(2) system call procedure, the difference between
with/without pthread is that bpfread() is called when without pthread,
while bpfpoll() is called when with pthread.  Note: in the select(2)
system call procedure, bpfpoll() is called.  On timed out, bpfread()
returns even if d->bd_slen == 0.  On the other hand, on timed out,
bpfpoll() returns POLLIN|POLLRDNORM bits only if d->bd_slen != 0.

The following patch makes bpfpoll() returns POLLIN|POLLRDNORM bits
even if d->bd_slen == 0 on timed out and also makes bpfread() returns 0
after bpfpoll() returns those bits.

Noritoshi

=========================================================================
<<Patch for FreeBSD 4.6R>>
--- sys/net/bpf.c-ORG	Mon Apr 15 06:41:48 2002
+++ sys/net/bpf.c	Wed Oct  2 16:55:53 2002
@@ -480,7 +480,7 @@
 	 * have arrived to fill the store buffer.
 	 */
 	while (d->bd_hbuf == 0) {
-		if ((d->bd_immediate || timed_out) && d->bd_slen != 0) {
+		if (d->bd_immediate && d->bd_slen != 0) {
 			/*
 			 * A packet(s) either arrived since the previous
 			 * read or arrived while we were asleep.
@@ -488,6 +488,8 @@
 			 */
 			ROTATE_BUFFERS(d);
 			break;
+		} else if (timed_out) {
+			goto timedout;
 		}

 		/*
@@ -512,6 +514,7 @@
 			return (error);
 		}
 		if (error == EWOULDBLOCK) {
+		timedout:
 			/*
 			 * On a timeout, return what's in the buffer,
 			 * which may be nothing.  If there is something
@@ -1095,8 +1098,8 @@
 		 *	    (d->bd_hbuf != NULL && d->bd_hlen != 0)
 		 */
 		if (d->bd_hlen != 0 ||
-		    ((d->bd_immediate || d->bd_state == BPF_TIMED_OUT) &&
-		    d->bd_slen != 0))
+		    (d->bd_immediate && d->bd_slen != 0) ||
+		    d->bd_state == BPF_TIMED_OUT)
 			revents |= events & (POLLIN | POLLRDNORM);
 		else {
 			selrecord(p, &d->bd_sel);
=========================================================================

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021107.011746.41626604.noritosi>