[260] in linux-net channel archive

home help back first fref pref prev next nref lref last post

Patch to PPP for problems reported on kernel list

daemon@ATHENA.MIT.EDU (Al Longyear)
Mon May 1 09:42:14 1995

From: longyear@netcom.com (Al Longyear)
To: linux-ppp@vger.rutgers.edu, linux-net@vger.rutgers.edu,
        linux-kernel@vger.rutgers.edu
Date: Mon, 1 May 1995 04:58:15 -0700 (PDT)
Cc: callahan@maths.ox.ac.uk (Michael Callahan),
        helge@lintos.barkhof.uni-bremen.de

I am sorry that this message is being cross posted to the kernel list. It
really doesn't belong there. However, since the discussion about the problem
was posted there, I felt that this should be posted there as well. Please
take all follow-up to the 'net' list as that is where it should have been in
the first place.

This is a copy of the message which I sent to Linus detailing the patch
which corrects the problems with the PPP driver.

I have added the following changes:

1. Called slhc_toss where it is appropriate. It should help with problems
   of vj header compression.

2. Corrected the module support to include the 16 devices where appropriate.

3. Corrected a race condition dealing with the failure of the communications
   device and the release of the buffers.

4. Set the "CHECK_CHARACTERS" by default since several people have had
   problems with the communications setup on the peer.

5. Compressed the connection ID if so indicated by the peer.

6. The define "PPP_PPP_LOTS" is included in the previous patch which I sent
   to Linus for more than 4 ppp devices. That patch is on ftp.netcom.com
   in /pub/lo/longyear/linux. I will put a copy of this one on my ftp site
   as well.

Linus and Alan, this is the same file. In looking at the transmission
log, it seems that PGP had corrupted the patch file by changing the patch
'-' to '- -' in the first column. Sorry. This one is not 'signed' and does
not have the PGP corruption.

--- linux-1.2.5/drivers/net/ppp.c.orig	Tue Apr 18 16:45:07 1995
+++ linux-1.2.5/drivers/net/ppp.c	Sun Apr 30 13:43:51 1995
@@ -29,10 +29,11 @@
 */
 
 /* #define NET02D				-* */
 #define NEW_TTY_DRIVERS				/* */
 #define OPTIMIZE_FLAG_TIME  ((HZ * 3)/2)	/* */
+#define CHECK_CHARACTERS
 
 #ifdef MODULE
 #include <linux/module.h>
 #include <linux/version.h>
 #endif
@@ -467,12 +468,12 @@
   if (ppp->tty != NULL && ppp->tty->disc_data == ppp)
     ppp->tty->disc_data = NULL; /* Break the tty->ppp link */
 #endif
 
   if (ppp->dev) {
-    ppp->dev->flags &= ~IFF_UP; /* down the device */
-    ppp->dev->flags |= IFF_POINTOPOINT;
+    dev_close (ppp->dev);
+    ppp->dev->flags = 0;
   }
 
   kfree (ppp->xbuff);
   kfree (ppp->cbuff);
   kfree (ppp->rbuff);
@@ -951,18 +952,18 @@
       fp++;
     }
 
 #ifdef CHECK_CHARACTERS
     if (c & 0x80)
-	sc->sc_flags |= SC_RCV_B7_1;
+	ppp->flags |= SC_RCV_B7_1;
     else
-	sc->sc_flags |= SC_RCV_B7_0;
+	ppp->flags |= SC_RCV_B7_0;
 
     if (paritytab[c >> 5] & (1 << (c & 0x1F)))
-	sc->sc_flags |= SC_RCV_ODDP;
+	ppp->flags |= SC_RCV_ODDP;
     else
-	sc->sc_flags |= SC_RCV_EVNP;
+	ppp->flags |= SC_RCV_EVNP;
 #endif
 
     switch (c) {
     case PPP_ESC:		/* PPP_ESC: invert 0x20 in next character */
       ppp->escape = PPP_TRANS;
@@ -1003,10 +1004,11 @@
 
   /* forget it if we've already noticed an error */
   if (ppp->toss) {
     PRINTKN (1, (KERN_WARNING "ppp_toss: tossing frame, reason = %d\n",
 		 ppp->toss));
+    slhc_toss (ppp->slcomp);
     ppp->stats.rerrors++;
     return;
   }
 
   /* do this before printing buffer to avoid generating copious output */
@@ -1016,17 +1018,19 @@
   if (ppp_debug >= 3)
     ppp_print_buffer ("receive frame", c, count, KERNEL_DS);
 
   if (count < 4) {
     PRINTKN (1,(KERN_WARNING "ppp: got runt ppp frame, %d chars\n", count));
+    slhc_toss (ppp->slcomp);
     ppp->stats.runts++;
     return;
   }
 
   /* check PPP error detection field */
   if (!ppp_check_fcs(ppp)) {
     PRINTKN (1,(KERN_WARNING "ppp: frame with bad fcs\n"));
+    slhc_toss (ppp->slcomp);
     ppp->stats.rerrors++;
     return;
   }
 
   count -= 2;			/* ignore last two characters */
@@ -1065,10 +1069,11 @@
   }
 
   /* couldn't cope. */
   PRINTKN (1,(KERN_WARNING
 	      "ppp: dropping packet on the floor: nobody could take it.\n"));
+  slhc_toss (ppp->slcomp);
   ppp->stats.tossed++;
 }
 
 /* Examine packet at C, attempt to pass up to net layer. 
    PROTO is the protocol field from the PPP frame.
@@ -1107,27 +1112,30 @@
 
     if (! done)	{
       PRINTKN (1,(KERN_NOTICE
 		  "ppp: no space to decompress VJ compressed TCP header.\n"));
       ppp->stats.roverrun++;
+      slhc_toss (ppp->slcomp);
       return 1;
     }
 
     count = slhc_uncompress(ppp->slcomp, c, count);
     if (count <= 0) {
       ppp->stats.rerrors++;
       PRINTKN (1,(KERN_NOTICE "ppp: error in VJ decompression\n"));
+      slhc_toss (ppp->slcomp);
       return 1;
     }
     ppp->stats.rcomp++;
     goto sendit;
   }
   
   if ((proto == PROTO_VJUNCOMP) && !(ppp->flags & SC_REJ_COMP_TCP)) {
     if (slhc_remember(ppp->slcomp, c, count) <= 0) {
       ppp->stats.rerrors++;
       PRINTKN (1,(KERN_NOTICE "ppp: error in VJ memorizing\n"));
+      slhc_toss (ppp->slcomp);
       return 1;
     }
     ppp->stats.runcomp++;
     goto sendit;
   }
@@ -1707,11 +1715,16 @@
   proto = PROTO_IP;
 
   PRINTKN(4,(KERN_DEBUG "ppp_xmit [%s]: skb %lX busy %d\n", dev->name, 
 	     (unsigned long int) skb, ppp->sending));
 
-  CHECK_PPP(0);
+  /* avoid race conditions when the link fails */
+  if (!ppp->inuse) {
+    dev_kfree_skb(skb, FREE_WRITE);
+    dev_close (dev);
+    return 0;
+  }
 
   if (tty == NULL) {
     PRINTKN(1,(KERN_ERR "ppp_xmit: %s not connected to a TTY!\n", dev->name));
     goto done;
   }
@@ -1724,11 +1737,11 @@
   }
 
   /* get length from IP header as per Alan Cox bugfix for slip.c */
   if (len < sizeof(struct iphdr)) {
     PRINTKN(0,(KERN_ERR "ppp_xmit: given runt packet, ignoring\n"));
-    return 1;
+    goto done;
   }
   len = ntohs( ((struct iphdr *)(skb->data)) -> tot_len );
 
   /* If doing demand dial then divert the first frame to pppd. */
   if (ppp->flags & SC_IP_DOWN) {
@@ -1748,12 +1761,12 @@
 
   ppp->xhead = ppp->xbuff;
 
   /* try to compress, if VJ compression mode is on */
   if (ppp->flags & SC_COMP_TCP) {
-    /* NOTE: last 0 argument says never to compress connection ID */
-    len = slhc_compress(ppp->slcomp, p, len, ppp->cbuff, &p, 0);
+    len = slhc_compress(ppp->slcomp, p, len, ppp->cbuff, &p, 
+			!(ppp->flags & SC_NO_TCP_CCID));
     if (p[0] & SL_TYPE_COMPRESSED_TCP)
       proto = PROTO_VJCOMP;
     else {
       if (p[0] >= SL_TYPE_UNCOMPRESSED_TCP) {
 	proto = PROTO_VJUNCOMP;
@@ -2053,14 +2066,29 @@
 	{
 		"ppp0",		/* ppp */
 		0, 0, 0, 0,	/* memory */
 		0, 0,		/* base, irq */
 		0, 0, 0, NULL, ppp_init,
-	},
-	{ "ppp1" , 0, 0, 0, 0,  1, 0, 0, 0, 0, NULL, ppp_init },
-	{ "ppp2" , 0, 0, 0, 0,  2, 0, 0, 0, 0, NULL, ppp_init },
-	{ "ppp3" , 0, 0, 0, 0,  3, 0, 0, 0, 0, NULL, ppp_init },
+	}
+	, { "ppp1" , 0, 0, 0, 0,  1, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp2" , 0, 0, 0, 0,  2, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp3" , 0, 0, 0, 0,  3, 0, 0, 0, 0, NULL, ppp_init }
+
+#ifdef PPP_PPP_LOTS
+	, { "ppp4" , 0, 0, 0, 0,  4, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp5" , 0, 0, 0, 0,  5, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp6" , 0, 0, 0, 0,  6, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp7" , 0, 0, 0, 0,  7, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp8" , 0, 0, 0, 0,  8, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp9" , 0, 0, 0, 0,  9, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp10" , 0, 0, 0, 0, 10, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp11" , 0, 0, 0, 0, 11, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp12" , 0, 0, 0, 0, 12, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp13" , 0, 0, 0, 0, 13, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp14" , 0, 0, 0, 0, 14, 0, 0, 0, 0, NULL, ppp_init }
+	, { "ppp15" , 0, 0, 0, 0, 15, 0, 0, 0, 0, NULL, ppp_init }
+#endif
 };
 
 int
 init_module(void)
 {


-- 
Al Longyear           longyear@netcom.com

home help back first fref pref prev next nref lref last post