--- /dev/null
+--- linux/drivers/net/ppp_generic.c.orig Mon Feb 25 11:37:59 2002
++++ linux/drivers/net/ppp_generic.c Mon Mar 25 10:19:53 2002
+@@ -1006,8 +1006,15 @@
+ /* try to do packet compression */
+ if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
+ && proto != PPP_LCP && proto != PPP_CCP) {
+- new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
+- GFP_ATOMIC);
++ int new_skb_size = ppp->dev->mtu + ppp->dev->hard_header_len;
++ int compressor_skb_size = ppp->dev->mtu + PPP_HDRLEN;
++
++ if (ppp->xcomp->compress_proto == CI_MPPE) {
++ /* CCP [must have] reduced MTU by MPPE_PAD. */
++ new_skb_size += MPPE_PAD;
++ compressor_skb_size += MPPE_PAD;
++ }
++ new_skb = alloc_skb(new_skb_size, GFP_ATOMIC);
+ if (new_skb == 0) {
+ printk(KERN_ERR "PPP: no memory (comp pkt)\n");
+ goto drop;
+@@ -1019,15 +1026,27 @@
+ /* compressor still expects A/C bytes in hdr */
+ len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
+ new_skb->data, skb->len + 2,
+- ppp->dev->mtu + PPP_HDRLEN);
++ compressor_skb_size);
+ if (len > 0 && (ppp->flags & SC_CCP_UP)) {
+ kfree_skb(skb);
+ skb = new_skb;
+ skb_put(skb, len);
+ skb_pull(skb, 2); /* pull off A/C bytes */
+- } else {
++ } else if (len == 0) {
+ /* didn't compress, or CCP not up yet */
+ kfree_skb(new_skb);
++ } else {
++ /*
++ * (len < 0)
++ * MPPE requires that we do not send unencrypted
++ * frames. The compressor will return -1 if we
++ * should drop the frame. We cannot simply test
++ * the compress_proto because MPPE and MPPC share
++ * the same number.
++ */
++ printk(KERN_ERR "ppp: compressor dropped pkt\n");
++ kfree_skb(new_skb);
++ goto drop;
+ }
+ }
+
+@@ -1515,7 +1534,7 @@
+ int len;
+
+ if (proto == PPP_COMP) {
+- ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN);
++ ns = dev_alloc_skb(ppp->mru + 128 + PPP_HDRLEN);
+ if (ns == 0) {
+ printk(KERN_ERR "ppp_decompress_frame: no memory\n");
+ goto err;