From: Matt Domsch <Matt_Domsch@dell.com>

This patch implements the Microsoft Point-to-Point Tunnelling Protocol
kernel module, with minor changes to ppp_generic to have it drop
packets if they are not compressed/decompressed properly.  This adds a
new ppp flag SC_MUST_COMPRESS which will be set by pppd upon CCP UP
with MPPE enabled.

Signed-off-by: Matt Domsch <Matt_Domsch@dell.com>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 drivers/net/ppp_generic.c |   19 +++++++++++++------
 drivers/net/ppp_mppe.c    |   10 +++++-----
 drivers/net/ppp_mppe.h    |    3 +--
 include/linux/if_ppp.h    |    9 +++++++--
 include/linux/ppp-comp.h  |   11 +++--------
 5 files changed, 29 insertions(+), 23 deletions(-)

diff -puN drivers/net/ppp_generic.c~ppp_mppe-add-ppp-mppe-encryption-module-update drivers/net/ppp_generic.c
--- 25/drivers/net/ppp_generic.c~ppp_mppe-add-ppp-mppe-encryption-module-update	Wed Aug 17 16:04:37 2005
+++ 25-akpm/drivers/net/ppp_generic.c	Wed Aug 17 16:04:37 2005
@@ -137,13 +137,14 @@ struct ppp {
 
 /*
  * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC,
- * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP.
+ * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP,
+ * SC_MUST_COMP
  * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR.
  * Bits in xstate: SC_COMP_RUN
  */
 #define SC_FLAG_BITS	(SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \
 			 |SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \
-			 |SC_COMP_TCP|SC_REJ_COMP_TCP)
+			 |SC_COMP_TCP|SC_REJ_COMP_TCP|SC_MUST_COMP)
 
 /*
  * Private data structure for each channel.
@@ -1032,8 +1033,10 @@ pad_compress_skb(struct ppp *ppp, struct
 {
 	struct sk_buff *new_skb;
 	int len;
-	int new_skb_size = ppp->dev->mtu + ppp->xcomp->comp_skb_extra_space + ppp->dev->hard_header_len;
-	int compressor_skb_size = ppp->dev->mtu + ppp->xcomp->comp_skb_extra_space + PPP_HDRLEN;
+	int new_skb_size = ppp->dev->mtu +
+		ppp->xcomp->comp_extra + ppp->dev->hard_header_len;
+	int compressor_skb_size = ppp->dev->mtu +
+		ppp->xcomp->comp_extra + PPP_HDRLEN;
 	new_skb = alloc_skb(new_skb_size, GFP_ATOMIC);
 	if (!new_skb) {
 		if (net_ratelimit())
@@ -1068,6 +1071,7 @@ pad_compress_skb(struct ppp *ppp, struct
 		 */
 		if (net_ratelimit())
 			printk(KERN_ERR "ppp: compressor dropped pkt\n");
+		kfree_skb(skb);
 		kfree_skb(new_skb);
 		new_skb = NULL;
 	}
@@ -1160,7 +1164,7 @@ ppp_send_frame(struct ppp *ppp, struct s
 	/* try to do packet compression */
 	if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
 	    && proto != PPP_LCP && proto != PPP_CCP) {
-		if (!(ppp->flags & SC_CCP_UP) && ppp->xcomp->must_compress) {
+		if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) {
 			if (net_ratelimit())
 				printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n");
 			goto drop;
@@ -1586,6 +1590,9 @@ ppp_receive_nonmp_frame(struct ppp *ppp,
 	    && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
 		skb = ppp_decompress_frame(ppp, skb);
 
+	if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR)
+		goto err;
+
 	proto = PPP_PROTO(skb);
 	switch (proto) {
 	case PPP_VJC_COMP:
@@ -1715,7 +1722,7 @@ ppp_decompress_frame(struct ppp *ppp, st
 		goto err;
 
 	if (proto == PPP_COMP) {
-		ns = dev_alloc_skb(ppp->mru + ppp->rcomp->decomp_skb_extra_space + PPP_HDRLEN);
+		ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN);
 		if (ns == 0) {
 			printk(KERN_ERR "ppp_decompress_frame: no memory\n");
 			goto err;
diff -puN drivers/net/ppp_mppe.c~ppp_mppe-add-ppp-mppe-encryption-module-update drivers/net/ppp_mppe.c
--- 25/drivers/net/ppp_mppe.c~ppp_mppe-add-ppp-mppe-encryption-module-update	Wed Aug 17 16:04:37 2005
+++ 25-akpm/drivers/net/ppp_mppe.c	Wed Aug 17 16:04:37 2005
@@ -1,6 +1,6 @@
 /*
- * ppp_mppe_compress.c - interface MPPE to the PPP code.
- * This version is for use with Linux kernel 2.2.19+, 2.4.18+ and 2.6.2+.
+ * ppp_mppe.c - interface MPPE to the PPP code.
+ * This version is for use with Linux kernel 2.6.14+
  *
  * By Frank Cusack <frank@google.com>.
  * Copyright (c) 2002,2003,2004 Google, Inc.
@@ -32,6 +32,8 @@
  *
  *
  * Changelog:
+ *      08/12/05 - Matt Domsch <Matt_Domsch@dell.com>
+ *                 Only need extra skb padding on transmit, not receive.
  *      06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru>
  *                 Use Linux kernel 2.6 arc4 and sha1 routines rather than
  *                 providing our own.
@@ -679,9 +681,7 @@ static struct compressor ppp_mppe = {
 	.incomp         = mppe_incomp,
 	.decomp_stat    = mppe_comp_stats,
 	.owner          = THIS_MODULE,
-	.comp_skb_extra_space = MPPE_COMPRESS_PAD,
-	.decomp_skb_extra_space = MPPE_DECOMPRESS_PAD,
-	.must_compress  = 1,
+	.comp_extra     = MPPE_PAD,
 };
 
 /*
diff -puN drivers/net/ppp_mppe.h~ppp_mppe-add-ppp-mppe-encryption-module-update drivers/net/ppp_mppe.h
--- 25/drivers/net/ppp_mppe.h~ppp_mppe-add-ppp-mppe-encryption-module-update	Wed Aug 17 16:04:37 2005
+++ 25-akpm/drivers/net/ppp_mppe.h	Wed Aug 17 16:04:37 2005
@@ -1,5 +1,4 @@
-#define MPPE_COMPRESS_PAD       8       /* MPPE growth per frame */
-#define MPPE_DECOMPRESS_PAD   128
+#define MPPE_PAD                4      /* MPPE growth per frame */
 #define MPPE_MAX_KEY_LEN       16      /* largest key length (128-bit) */
 
 /* option bits for ccp_options.mppe */
diff -puN include/linux/if_ppp.h~ppp_mppe-add-ppp-mppe-encryption-module-update include/linux/if_ppp.h
--- 25/include/linux/if_ppp.h~ppp_mppe-add-ppp-mppe-encryption-module-update	Wed Aug 17 16:04:37 2005
+++ 25-akpm/include/linux/if_ppp.h	Wed Aug 17 16:04:37 2005
@@ -21,7 +21,7 @@
  */
 
 /*
- *  ==FILEVERSION 20000724==
+ *  ==FILEVERSION 20050812==
  *
  *  NOTE TO MAINTAINERS:
  *     If you modify this file at all, please set the above date.
@@ -70,7 +70,8 @@
 #define SC_LOG_RAWIN	0x00080000	/* log all chars received */
 #define SC_LOG_FLUSH	0x00100000	/* log all chars flushed */
 #define	SC_SYNC		0x00200000	/* synchronous serial mode */
-#define	SC_MASK		0x0f200fff	/* bits that user can change */
+#define	SC_MUST_COMP    0x00400000	/* no uncompressed packets may be sent or received */
+#define	SC_MASK		0x0f600fff	/* bits that user can change */
 
 /* state bits */
 #define SC_XMIT_BUSY	0x10000000	/* (used by isdn_ppp?) */
@@ -90,6 +91,10 @@ struct npioctl {
 	enum NPmode	mode;
 };
 
+#ifndef __user
+#define __user
+#endif
+
 /* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */
 struct ppp_option_data {
 	__u8	__user *ptr;
diff -puN include/linux/ppp-comp.h~ppp_mppe-add-ppp-mppe-encryption-module-update include/linux/ppp-comp.h
--- 25/include/linux/ppp-comp.h~ppp_mppe-add-ppp-mppe-encryption-module-update	Wed Aug 17 16:04:37 2005
+++ 25-akpm/include/linux/ppp-comp.h	Wed Aug 17 16:04:37 2005
@@ -112,12 +112,7 @@ struct compressor {
 	/* Used in locking compressor modules */
 	struct module *owner;
 	/* Extra skb space needed by the compressor algorithm */
-	unsigned int comp_skb_extra_space;
-	/* Extra skb space needed by the decompressor algorithm */
-	unsigned int decomp_skb_extra_space;
-	/* if must_compress is set, but ppp->flags != SC_CCP_UP
-	 * then drop the packet */
-	unsigned int must_compress;
+	unsigned int comp_extra;
 };
 
 /*
@@ -201,8 +196,8 @@ struct compressor {
  * Definitions for MPPE.
  */
 
-#define CI_MPPE                        18      /* config option for MPPE */
-#define CILEN_MPPE             6       /* length of config option */
+#define CI_MPPE                18      /* config option for MPPE */
+#define CILEN_MPPE              6      /* length of config option */
 
 /*
  * Definitions for other, as yet unsupported, compression methods.
_