Subject: kern/5901: ppp fast queue too fast
To: None <gnats-bugs@gnats.netbsd.org>
From: Felix A. Croes <felix@simplex.nl>
List: netbsd-bugs
Date: 08/03/1998 15:50:06
>Number:         5901
>Category:       kern
>Synopsis:       PPP fast queue blocks traffic at normal priority
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Aug  3 07:05:00 1998
>Last-Modified:
>Originator:     Felix A. Croes
>Organization:
	Dworkin B.V.
>Release:        NetBSD 1.3.2, NetBSD-current
>Environment:
	NetBSD 1.3.2 i386 -O2 -m486 -fomit-frame-pointer
System: NetBSD tyrathect 1.3.2 NetBSD 1.3.2 (TYRATHECT) #1: Mon Aug 3 02:04:46 CEST 1998 felix@tyrathect:/usr/src/sys/arch/i386/compile/TYRATHECT i386


>Description:
in ppp_dequeue(), preference is always given to PPP packets in the fast
queue, if present.  Normal-priority packets will not get through at all.
Unfortuately this includes ping packets and LCP echo packets.  If
the lcp-echo-failure option is set, a continuous stream of fast packets
will break the connection.

>How-To-Repeat:
Machine A running NetBSD is connected to the internet (it doesn't
matter how).  Machine B, not necessarily running NetBSD, has a PPP
connection to A and uses it as a gateway onto the internet.  The
PPP connection uses the lcp-echo feature to ascertain that the
connection still exists.

>From machine B, ftp a file from a site on the internet which has an
ftp server which uses high-priority packets, for instance
download.gamespot.com.  The ftp packets will monopolize the connection,
freezing all other traffic.  After the interval of lcp-echo-interval *
lcp-echo-failure seconds has passed, the PPP connection will be broken.

>Fix:
Instead of always giving preference to fast packets, give then a 2 to 1
preference over normal-priority traffic.  In the diffs below, I have
used the two unused flag bits in sc->sc_flags for this.  Other
possible implementations could use a new field in the ppp_softc struct
instead, or assign preference based on #bytes rather than #packets.


*** /sys/net/if_ppp.c.old	Tue May  5 08:53:34 1998
--- /sys/net/if_ppp.c	Mon Aug  3 02:01:59 1998
***************
*** 883,894 ****
      int address, control, protocol;
  
      /*
!      * Grab a packet to send: first try the fast queue, then the
!      * normal queue.
       */
!     IF_DEQUEUE(&sc->sc_fastq, m);
!     if (m == NULL)
  	IF_DEQUEUE(&sc->sc_if.if_snd, m);
      if (m == NULL)
  	return NULL;
  
--- 883,908 ----
      int address, control, protocol;
  
      /*
!      * Grab a packet to send: give the fast queue twice the priority
!      * of the normal queue.
       */
!     if ((sc->sc_flags & SC_FASTQ_MASK) != SC_FASTQ_MAX) {
! 	/* try fast queue first */
! 	IF_DEQUEUE(&sc->sc_fastq, m);
! 	if (m == NULL) {
! 	    IF_DEQUEUE(&sc->sc_if.if_snd, m);
! 	} else
! 	    sc->sc_flags += SC_FASTQ_INC;
!     } else {
! 	/* try normal queue first */
! 	sc->sc_flags &= ~SC_FASTQ_MASK;
  	IF_DEQUEUE(&sc->sc_if.if_snd, m);
+ 	if (m == NULL) {
+ 	    IF_DEQUEUE(&sc->sc_fastq, m);
+ 	    if (m != NULL)
+ 		sc->sc_flags += SC_FASTQ_INC;
+ 	}
+     }
      if (m == NULL)
  	return NULL;
  
*** /sys/net/if_ppp.h.old	Mon Aug  3 01:23:09 1998
--- /sys/net/if_ppp.h	Mon Aug  3 01:52:55 1998
***************
*** 48,53 ****
--- 48,57 ----
  /*
   * State bits in sc_flags, not changeable by user.
   */
+ #define SC_FASTQ_INC	0x00000100	/* added if packed rcvd on fast queue */
+ #define SC_FASTQ_MAX	0x00000200	/* max fast packets rcvd in sequence */
+ #define SC_FASTQ_MASK	0x00000300	/* fast queue packet count mask */
+ 
  #define SC_TIMEOUT	0x00000400	/* timeout is currently pending */
  #define SC_VJ_RESET	0x00000800	/* need to reset VJ decomp */
  #define SC_COMP_RUN	0x00001000	/* compressor has been inited */
>Audit-Trail:
>Unformatted: