/* * $Id$ * * Glenn Chisholm */ #include #include #include #include #include #include #include #include #include #include #include #include #define WCCP_PROTOCOL_TYPE 0x883E #define WCCP_GRE_LEN sizeof(long) int ip_wccp_rcv(struct sk_buff *skb, unsigned short len) { long *gre_hdr; 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 = __constant_htons(ETH_P_IP); skb->pkt_type = PACKET_HOST; skb->ip_summed = 0; dst_release(skb->dst); skb->dst = NULL; return ip_rcv(skb, skb->dev, NULL); drop: 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\n"); inet_add_protocol(&ipgre_protocol); return 0; } void cleanup_module(void) { if ( inet_del_protocol(&ipgre_protocol) < 0 ) printk(KERN_INFO "ipgre close: can't remove protocol\n"); else printk(KERN_INFO "WCCP IPv4/GRE driver unloaded\n"); }