[260] in linux-net channel archive
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