diff -uNr linux/Documentation/Configure.help linux-2.4.2/Documentation/Configure.help
--- linux/Documentation/Configure.help	Mon Feb 19 19:18:18 2001
+++ linux-2.4.2/Documentation/Configure.help	Thu Mar 22 19:16:57 2001
@@ -3926,6 +3926,15 @@
   Documentation/networking/multicast.txt. If you haven't heard about
   it, you don't need it.
 
+IP: WCCP tunnels over IP
+CONFIG_NET_IPWCCP
+  Tunneling means encapsulating data of one protocol type within
+  another protocol and sending it over a channel that understands the
+  encapsulating protocol. This particular tunneling driver implements
+  WCCP (Web Cache Coordination Protocol) GRE.  This driver is useful 
+  if you have a WCCP-enabled router, and would like to use WCCP to 
+  redirect packets to a web cache.
+
 IP: PIM-SM version 1 support
 CONFIG_IP_PIMSM_V1
   Kernel side support for Sparse Mode PIM (Protocol Independent
diff -uNr linux/net/ipv4/Config.in linux-2.4.2/net/ipv4/Config.in
--- linux/net/ipv4/Config.in	Tue Aug 22 17:59:00 2000
+++ linux-2.4.2/net/ipv4/Config.in	Thu Mar 22 19:17:56 2001
@@ -27,6 +27,7 @@
 fi
 tristate '  IP: tunneling' CONFIG_NET_IPIP
 tristate '  IP: GRE tunnels over IP' CONFIG_NET_IPGRE
+tristate '  IP: WCCP GRE tunnels over IP' CONFIG_NET_IPWCCP
 if [ "$CONFIG_IP_MULTICAST" = "y" ]; then
    if [ "$CONFIG_NET_IPGRE" != "n" ]; then
       bool '    IP: broadcast GRE over IP' CONFIG_NET_IPGRE_BROADCAST
diff -uNr linux/net/ipv4/Makefile linux-2.4.2/net/ipv4/Makefile
--- linux/net/ipv4/Makefile	Fri Dec 29 23:07:24 2000
+++ linux-2.4.2/net/ipv4/Makefile	Mon Mar 19 20:38:34 2001
@@ -9,7 +9,7 @@
 
 O_TARGET := ipv4.o
 
-export-objs = ipip.o ip_gre.o
+export-objs = ipip.o ip_gre.o ip_wccp.o
 
 obj-y     := utils.o route.o inetpeer.o proc.o protocol.o \
 	     ip_input.o ip_fragment.o ip_forward.o ip_options.o \
@@ -22,6 +22,7 @@
 obj-$(CONFIG_IP_ROUTE_NAT) += ip_nat_dumb.o
 obj-$(CONFIG_IP_MROUTE) += ipmr.o
 obj-$(CONFIG_NET_IPIP) += ipip.o
+obj-$(CONFIG_NET_IPWCCP) += ip_wccp.o
 obj-$(CONFIG_NET_IPGRE) += ip_gre.o
 obj-$(CONFIG_SYN_COOKIES) += syncookies.o
 obj-$(CONFIG_IP_PNP) += ipconfig.o
diff -uNr linux/net/ipv4/ip_wccp.c linux-2.4.2/net/ipv4/ip_wccp.c
--- linux/net/ipv4/ip_wccp.c	Thu Jan  1 01:00:00 1970
+++ linux-2.4.2/net/ipv4/ip_wccp.c	Thu Mar 22 19:20:05 2001
@@ -0,0 +1,99 @@
+/*
+ *      $Id: ip_wccp.c,v 1.1 1999/09/30 20:43:37 wessels Exp $
+ *
+ * Glenn Chisholm <glenn@ircache.net>
+ * Jorge Boncompte <jorge@dti2.net> (Modified for kernel 2.4)
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/in.h>
+#include <linux/if_arp.h>
+#include <linux/init.h>
+#include <linux/inetdevice.h>
+#include <linux/netfilter_ipv4.h>
+
+#include <net/ip.h>
+
+#define WCCP_PROTOCOL_TYPE 	0x883E
+#define WCCP_GRE_LEN		sizeof(long)
+
+static rwlock_t ipwccp_lock = RW_LOCK_UNLOCKED;
+
+int ip_wccp_rcv(struct sk_buff *skb, unsigned short len)
+{
+	long *gre_hdr;
+
+	read_lock(&ipwccp_lock);
+
+	gre_hdr = (unsigned long *)skb->h.raw;
+
+	if(*gre_hdr != htonl(WCCP_PROTOCOL_TYPE)) 
+		goto drop;
+
+
+	skb->mac.raw = skb->nh.raw;
+	skb->nh.raw = skb_pull(skb, skb->h.raw + WCCP_GRE_LEN - skb->data);
+
+	if (skb->len <= 0) 
+                goto drop;
+
+	memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+/*	skb->protocol = *(u16*)(h + 2);*/
+	skb->protocol = __constant_htons(ETH_P_IP);
+	skb->pkt_type = PACKET_HOST;
+	skb->ip_summed = 0;
+	dst_release(skb->dst);
+	skb->dst = NULL;
+
+#ifdef CONFIG_NETFILTER
+		nf_conntrack_put(skb->nfct);
+		skb->nfct = NULL;
+
+#ifdef CONFIG_NETFILTER_DEBUG
+		skb->nf_debug = 0;
+#endif
+#endif
+
+        ip_rcv(skb, skb->dev, NULL);
+		
+	read_unlock(&ipwccp_lock);
+
+	return(0);
+
+drop:
+	read_unlock(&ipwccp_lock);
+
+	kfree_skb(skb);
+	return(0);
+}
+
+static struct inet_protocol ipgre_protocol = {
+  ip_wccp_rcv,     
+  NULL,           
+  0,            
+  IPPROTO_GRE, 
+  0,          
+  NULL,      
+  "GRE"     
+};
+
+int init_module(void) 
+{
+	printk(KERN_INFO "WCCP IPv4/GRE driver loaded\n");
+	inet_add_protocol(&ipgre_protocol);
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	if ( inet_del_protocol(&ipgre_protocol) < 0 )
+		printk(KERN_INFO "ip_wccp close: can't remove protocol\n");
+	else
+		printk(KERN_INFO "WCCP IPv4/GRE driver unloaded\n");
+}
