From nobody@FreeBSD.ORG  Tue Oct 17 14:39:00 2000
Return-Path: <nobody@FreeBSD.ORG>
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id 265D137B4CF; Tue, 17 Oct 2000 14:39:00 -0700 (PDT)
Message-Id: <20001017213900.265D137B4CF@hub.freebsd.org>
Date: Tue, 17 Oct 2000 14:39:00 -0700 (PDT)
From: vanepp@sfu.ca
Sender: nobody@FreeBSD.ORG
To: freebsd-gnats-submit@FreeBSD.org
Subject: bpf when used with the select system call with timeout doesn't forward packets on timeout
X-Send-Pr-Version: www-1.0

>Number:         22063
>Category:       kern
>Synopsis:       bpf when used with the select system call with timeout doesn't forward packets on timeout
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    jdp
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 17 14:40:00 PDT 2000
>Closed-Date:    Mon Dec 17 11:33:10 PST 2001
>Last-Modified:  Mon Dec 17 11:34:04 PST 2001
>Originator:     Peter Van Epp
>Release:        4.1-RELEASE
>Organization:
Simon Fraser University
>Environment:
FreeBSD demob.ucs.sfu.ca 4.1-RELEASE FreeBSD 4.1-RELEASE #19: Tue Oct 17 12:37:56 PDT 2000     vanepp@demob.ucs.sfu.ca:/usr/src/sys/compile/GENERIC  i386
>Description:
     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. 
>How-To-Repeat:
To reproduce:

1) Install argus-1.8.1.tar.gz and argus-1.8.1.patches from 

ftp.andrew.cmu.edu/pub/argus	

2) Install the test.dif patch below to report Total packets received from 
   libpcap to show the problem.

3) start argus_bpf as below and supply it a less than buffer full of packets
   (I used tcpreplay from www.anzen.com/research/nidsbench on another machine
    playing back a tcpdump file:  tcpreplay -ixl0 -r1 ip.small.tcpdump).

4) Examine output as below (unpatched then patched).

Unpatched bpf.c (all 9 packets still in bpf.c buffer, none get to libpcap):

demob# bin/argus_bpf -i xl0 -P0 -w argus.log
^C
9 packets recv'd by filter
0 packets dropped by kernel
demob# bin/ra -r argus.log -n
Tue 10/17 12:34:19      man     1.168.192.0             255.255.255.0       INT
Tue 10/17 12:34:33      man  pkts        9  drops     0   flows        0       CLO


bpf.c and bpfdesc.h patched as below and kernel recompiled and installed:

demob# bin/argus_bpf -ixl0 -P0 -w argus.log
Total packets: 1
Total packets: 2
Total packets: 3
Total packets: 4
Total packets: 5
Total packets: 6
Total packets: 7
Total packets: 8
Total packets: 9
^C
9 packets recv'd by filter
0 packets dropped by kernel
demob# bin/ra -r argus.log -n
Tue 10/17 09:50:50      man     1.168.192.0             255.255.255.0       INT
Tue 10/17 09:51:16  M   tcp  130.71.240.184.2197   |>    142.58.12.12.80    RST
Tue 10/17 09:51:23      man  pkts        9  drops     0   flows        1       CLO
demob# 


Apply in argus-1.8.1/ directory.

*** server/cons_ether.c.orig	Tue Oct 17 01:45:10 2000
--- server/cons_ether.c	Tue Oct 17 01:45:59 2000
***************
*** 95,100 ****
--- 95,101 ----
  
     if (p && caplen) {
        totalPktsRcv++;
+       printf("Total packets: %d\n", totalPktsRcv);
  
        globaltvp.tv_sec  = h->ts.tv_sec;
        globaltvp.tv_usec = h->ts.tv_usec;

>Fix:

begin 600 patch.dif
M*BHJ("]S>7,O;F5T+V)P9BYC+F]R:6<)4V%T($]C=" Q-" Q.3HP,#HU.2 R
M,# P"BTM+2 O<WES+VYE="]B<&8N8PE-;VX@3V-T(#$V(# Y.C,P.C(T(#(P
M,# **BHJ*BHJ*BHJ*BHJ*BHJ"BHJ*B Q,#4T+#$P-C$@*BHJ*@H@( EI9B H
M979E;G1S("8@*%!/3$Q)3B!\(%!/3$Q21$Y/4DTI*2!["B @"0EI9B H9"T^
M8F1?:&QE;B A/2 P('Q\("AD+3YB9%]I;6UE9&EA=&4@)B8@9"T^8F1?<VQE
M;B A/2 P*2D*(" )"0ER979E;G1S('P](&5V96YT<R F("A03TQ,24X@?"!0
M3TQ,4D1.3U)-*3L*(2 )"65L<V4*(2 )"0ES96QR96-O<F0H<"P@)F0M/F)D
M7W-E;"D["B @"7T*(" )<W!L>"AS*3L*(" )<F5T=7)N("AR979E;G1S*3L*
M+2TM(#$P-30L,3 W-B M+2TM"B @"6EF("AE=F5N=',@)B H4$],3$E.('P@
M4$],3%)$3D]232DI('L*(" )"6EF("AD+3YB9%]H;&5N("$](# @?'P@*&0M
M/F)D7VEM;65D:6%T92 F)B!D+3YB9%]S;&5N("$](# I*0H@( D)"7)E=F5N
M=',@?#T@979E;G1S("8@*%!/3$Q)3B!\(%!/3$Q21$Y/4DTI.PHA( D)96QS
M92!["B$@(" @(" @(" )"2\J"B$@(" @(" @(" @"0D@*B!)9B!T:&5R92!I
M<R!A('1I;65O=70@86YD(&YO(&1A=&$@:6X@=&AE(&AO;&0@8G5F9F5R"B$@
M(" @(" @( D)"2 J('-E92!I9B!T:&5R92!H87,@8F5E;B!D871A(&EN('1H
M92!C87!T=7)E(&)U9F9E<@HA( D)"2 J(&9O<B!M;W)E('1H86X@82!T:6UE
M;W5T(&EN=&5R=F%L+B!)9B!S;R!R;W1A=&4@=&AE"B$@"0D)("H@8G5F9F5R
M('1O('!U<V@@=&AE('!A8VME=',@=&\@=&AE('5S97(N"B$@(" @(" @(" )
M"2 J+PHA( D)"6EF("@H9"T^8F1?<VQE;B A/2 P*2 F)B H9"T^8F1?:&QE
M;B ]/2 P*2D@>PHA( D)"0EI9B H*&0M/F)D7W)T;W5T("$]("TQ*2 F)B *
M(2 )"0D)(" @("AD+3YB9%]R9'-T87)T("L@9"T^8F1?<G1O=70I(#X@=&EC
M:W,I('L*(2 )"0D)"5)/5$%415]"549&15)3*&0I.PHA( D)"0D)<F5V96YT
M<R!\/2!E=F5N=',@)B H4$],3$E.('P@4$],3%)$3D]232D["B$@"0D)"7T*
M(2 )"0E](&5L<V4@"B$@"0D)"7-E;')E8V]R9"AP+" F9"T^8F1?<V5L*3L*
M(2 )"0D)"B$@"0E]"B @"7T*(" )<W!L>"AS*3L*(" )<F5T=7)N("AR979E
M;G1S*3L**BHJ*BHJ*BHJ*BHJ*BHJ"BHJ*B Q,C$Y+#$R,C0@*BHJ*@HM+2T@
M,3(S-"PQ,C0U("TM+2T*(" )("HO"B @"2@J8W!F;BDH<&MT+" H=5]C:&%R
M("HI:' @*R!H9')L96XL("AH<"T^8FA?8V%P;&5N(#T@=&]T;&5N("T@:&1R
M;&5N*2D["B @"60M/F)D7W-L96X@/2!C=7)L96X@*R!T;W1L96X["BL@"BL@
M"2\J"BL@"2 J($UA<FL@=&AE('1I;64@=&AE(&QA<W0@<&%C:V5T('=A<R!S
M965N(&9O<B!P;VQL('1I;65O=70@<')O8V5S<VEN9RX**R )("HO"BL@"BL@
M"60M/F)D7W)D<W1A<G0@/2!T:6-K<SL*("!]"B @"B @+RH**BHJ("]S>7,O
M;F5T+V)P9F1E<V,N:"YO<FEG"5-A="!/8W0@,30@,3DZ,38Z,#<@,C P, HM
M+2T@+W-Y<R]N970O8G!F9&5S8RYH"5-A="!/8W0@,30@,3DZ,C$Z-30@,C P
M, HJ*BHJ*BHJ*BHJ*BHJ*BH**BHJ(#8Y+#<T("HJ*BH*+2TM(#8Y+#<U("TM
M+2T*(" *(" )<W1R=6-T(&)P9E]I9B J"6)D7V)I9CL)"2\J(&EN=&5R9F%C
M92!D97-C<FEP=&]R("HO"B @"75?;&]N9PD)8F1?<G1O=70["2\J(%)E860@
M=&EM96]U="!I;B G=&EC:W,G("HO"BL@(" @(" @("!U7VQO;F<@(" @(" @
M(" @8F1?<F1S=&%R=#L@(" @("\J('=H96X@=&AE(')E860@<W1A<G1E9" J
M+PH@( ES=')U8W0@8G!F7VEN<VX@*F)D7V9I;'1E<CL@"2\J(&9I;'1E<B!C
M;V1E("HO"B @"75?;&]N9PD)8F1?<F-O=6YT.PDO*B!N=6UB97(@;V8@<&%C
M:V5T<R!R96-E:79E9" J+PH@( EU7VQO;F<)"6)D7V1C;W5N=#L)+RH@;G5M
:8F5R(&]F('!A8VME=',@9')O<'!E9" J+PH)
 
end


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->brian 
Responsible-Changed-By: johan 
Responsible-Changed-When: Sun Oct 22 11:39:36 PDT 2000 
Responsible-Changed-Why:  
Over to bpf maintainer. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=22063 
Responsible-Changed-From-To: brian->jdp 
Responsible-Changed-By: brian 
Responsible-Changed-When: Sun Jul 22 12:40:24 PDT 2001 
Responsible-Changed-Why:  
John has asked for this :) 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=22063 

From: "Guy Helmer" <ghelmer@palisadesys.com>
To: <freebsd-gnats-submit@FreeBSD.org>, <vanepp@sfu.ca>
Cc:  
Subject: Re: kern/22063: bpf when used with the select system call with timeout doesn't forward packets on timeout
Date: Thu, 23 Aug 2001 10:57:59 -0500

 I have verified that this patch installs correctly into FreeBSD 4.3's
 kernel.  This patch aids timely reporting of results from iplog version
 2.2.3.
 
 Guy Helmer, Ph.D.
 

From: Peter Van Epp <vanepp@sfu.ca>
To: ghelmer@palisadesys.com (Guy Helmer)
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: kern/22063: bpf when used with the select system call with timeout doesn't forward packets on timeout
Date: Thu, 23 Aug 2001 09:25:02 -0700 (PDT)

 	On this subject, a month or two ago I was in communication with 
 Guy Harris / John Polstra on the subject of this patch (I know Guy Harris
 knows more about Unix kernals than I do and I expect Mr Polstra does too).
 He reported a couple of issues with the patch (an off by one test and the 
 belief that the timeout won't work under some single packet conditions) that I 
 haven't yet had any time to poke at (assuming I know enough to understand what
 I'm poking at of course :-) ). Mr Polstra indicated he was thinking about how 
 the patch should work and hopefully will supply a better one.
 
 Peter Van Epp / Operations and Technical Support 
 Simon Fraser University, Burnaby, B.C. Canada
 
 > 
 > I have verified that this patch installs correctly into FreeBSD 4.3's
 > kernel.  This patch aids timely reporting of results from iplog version
 > 2.2.3.
 > 
 > Guy Helmer, Ph.D.
 > 
 > 
 

From: "Guy Helmer" <ghelmer@palisadesys.com>
To: <freebsd-gnats-submit@FreeBSD.org>, <vanepp@sfu.ca>
Cc:  
Subject: Re: kern/22063: bpf when used with the select system call with timeout doesn't forward packets on timeout
Date: Mon, 12 Nov 2001 08:36:42 -0600

 This patch also solves problems with using poll/select, but simply marks the
 fact that a select or poll has been performed on the BPF device.  If a
 packet then arrives for the BPF device, the poll/select succeeds.  It
 changes the BPF semantics to always allow a poll to succeed when any packets
 are received.
 
 This patch also solves the problem with using BPF devices in the case of
 userland threading, because the thread library's poll doesn't timeout when a
 read timeout has been set on the BPF device.
 
 --- bpf.c.ORIG	Mon Aug 27 13:25:57 2001
 +++ bpf.c	Fri Nov  9 10:47:22 2001
 @@ -444,7 +444,8 @@
  	(d)->bd_hlen = (d)->bd_slen; \
  	(d)->bd_sbuf = (d)->bd_fbuf; \
  	(d)->bd_slen = 0; \
 -	(d)->bd_fbuf = 0;
 +	(d)->bd_fbuf = 0; \
 +	(d)->bd_poll = 0;
  /*
   *  bpfread - read next chunk of packets from buffers
   */
 @@ -472,7 +473,7 @@
  	 * have arrived to fill the store buffer.
  	 */
  	while (d->bd_hbuf == 0) {
 -		if (d->bd_immediate && d->bd_slen != 0) {
 +		if ((d->bd_immediate || d->bd_poll) && d->bd_slen != 0) {
  			/*
  			 * A packet(s) either arrived since the previous
  			 * read or arrived while we were asleep.
 @@ -559,6 +560,7 @@
  		pgsigio(d->bd_sigio, d->bd_sig, 0);
 
  #if BSD >= 199103
 +	/* revents |= events & (POLLIN | POLLRDNORM); ??? */
  	selwakeup(&d->bd_sel);
  	/* XXX */
  	d->bd_sel.si_pid = 0;
 @@ -1057,10 +1059,12 @@
 
  	s = splimp();
  	if (events & (POLLIN | POLLRDNORM)) {
 -		if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0))
 +		if (d->bd_hlen != 0 || d->bd_poll || (d->bd_immediate && d->bd_slen !=
 0))
  			revents |= events & (POLLIN | POLLRDNORM);
 -		else
 +		else {
 +			d->bd_poll = 1;
  			selrecord(p, &d->bd_sel);
 +		}
  	}
  	splx(s);
  	return (revents);
 @@ -1199,7 +1203,7 @@
  		bpf_wakeup(d);
  		curlen = 0;
  	}
 -	else if (d->bd_immediate)
 +	else if (d->bd_immediate || d->bd_poll)
  		/*
  		 * Immediate mode is set.  A packet arrived so any
  		 * reads should be woken up.
 --- bpfdesc.h.ORIG	Mon Aug 27 13:26:06 2001
 +++ bpfdesc.h	Fri Nov  9 10:47:25 2001
 @@ -76,6 +76,7 @@
  	u_char		bd_promisc;	/* true if listening promiscuously */
  	u_char		bd_state;	/* idle, waiting, or timed out */
  	u_char		bd_immediate;	/* true to return on packet arrival */
 +	u_char		bd_poll;	/* poll waiting for data */
  	int		bd_hdrcmplt;	/* false to fill in src lladdr automatically */
  	int		bd_seesent;	/* true if bpf should see sent packets */
  	int		bd_async;	/* non-zero if packet reception should generate signal */
 

From: Edwin Groothuis <edwin@mavetju.org>
To: freebsd-gnats-submit@FreeBSD.org, vanepp@sfu.ca
Cc: freebsd-bugs@freebsd.org
Subject: Re: kern/22063: bpf when used with the select system call with timeout doesn't forward packets on timeout
Date: Wed, 28 Nov 2001 22:24:16 +1100

 This patch also solves a problem with using the BPF in a threaded
 environment. The problem is described in bin/31649.
 
 Can this patch please be commited? The current behaviour of the
 system is very strange now...
 
 Edwin
 
 -- 
 Edwin Groothuis   |              Personal website: http://www.MavEtJu.org
 edwin@mavetju.org |           Interested in MUDs? Visit Fatal Dimensions:
 ------------------+                       http://www.FatalDimensions.org/
State-Changed-From-To: open->closed 
State-Changed-By: jdp 
State-Changed-When: Mon Dec 17 11:33:10 PST 2001 
State-Changed-Why:  
Fixed in sys/net/bpf.c revision 1.59.2.8 and sys/net/bpfdesc.h 
revision 1.14.2.2. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=22063 
>Unformatted:
