On Mon, Dec 18, 2000 at 07:58:04AM +1100, Darren Reed wrote:
> Haven't we already fixed this one ?
> 
> Darren
> 
> ----- Forwarded message from John Polstra -----
> 
> Message-Id: <[EMAIL PROTECTED]>
> From: John Polstra <[EMAIL PROTECTED]>
> Date: Sun, 17 Dec 2000 12:50:23 -0800 (PST)
> Subject: cvs commit: src/sys/net bpf.c
> X-FreeBSD-CVS-Branch: HEAD
> 
> jdp         2000/12/17 12:50:23 PST
> 
>   Modified files:
>     sys/net              bpf.c 
>   Log:
>   Fix bug: a read() on a bpf device which was in non-blocking mode
>   and had no data available returned 0.  Now it returns -1 with errno
>   set to EWOULDBLOCK (== EAGAIN) as it should.  This fix makes the bpf
>   device usable in threaded programs.
>   
>   Reviewed by:        bde
>   
>   Revision  Changes    Path
>   1.72      +7 -6      src/sys/net/bpf.c

Who are "we"?

libpcap treats either a return of 0 or a return of -1 with "errno" set
to EWOULDBLOCK as meaning "no packets available", so libpcap works
around this to some extent.

I'm assuming from the checkin log, however, that the problem this is
intended to fix is that the userland threading library puts file
descriptors into non-blocking mode "behind the back" of a threaded
application, and if any read returns -1 and sets "errno" to EWOULDBLOCK,
treats this as an indication that the thread doing the read needs to be
blocked (the threading library supplies its own "read()" which handles
that, hiding those details from the threaded application).

If, however, the read returns 0, the threading library's "read()"
wrapper just returns 0, which may cause the threaded application - or
libpcap in the threaded application, if they're calling "pcap_loop()" -
to try again, so the application will just spin waiting for packets to
arrive, rather than handing control to another thread or blocking in the
threading library's "select()" if no packets are available.

So the workaround in libpcap doesn't work for threaded programs; it also
doesn't work if the threaded program isn't using libpcap but is directly
reading from a BPF device.

So if "we" refers to tcpdump.org, we can't fix this one; it requires a
kernel change.

(The current top-of-tree NetBSD "sys/net/bpf.c" still appears to have
this problem.  The current top-of-tree OpenBSD looks as if it fixes
this.)

The current top-of-tree *Free*BSD may still have *another* problem,
which is that a "select()" on a BPF device won't pay any attention to
the read timeout on the BPF device; instead, it'll block until the store
buffer fills.

This is OpenBSD PR 1459:

        "/sys/net/bpf.c when accessed via libpcap with the select system
        call with timeout does not flush the buffers (if they aren't
        full) when the timeout occurs.  There is code there that is
        supposed to do this (or something like it) but it doesn't work
        in this particular case.  This doesn't affect tcpdump because it
        appears to be running in immediate mode (which is probably
        performance limiting but does work)."

although the reason why it doesn't affect tcpdump isn't that tcpdump
runs in immediate mode (it doesn't) but that tcpdump doesn't use
"select()".

I think it's also OpenBSD PR 1460.

The current top-of-tree OpenBSD has what I think are some patches from
the folks at NFR which might fix this.

It's also FreeBSD PR 22063:

        "When bpf is accessed via libpcap with the select system call
        with a timeout set if a less than full buffer of packets
        received on the interface (and passed to bpf.c) they will never
        be returned to libpcap even on a timeout.  OpenBSD has a partial
        fix for this (it gets the first packet of 9 up and leaves the
        other 8) which I have corrected, reported to OpenBSD and ported
        to FreeBSD.  As a side note one of the OpenBSD people is working
        on a better bpf implementation and would be interested in help
        by someone knowledgable in the FreeBSD VM system to assist
        porting his code when finished to FreeBSD."

I didn't find any NetBSD PR for this.
-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe

Reply via email to