Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:tpatzig
squid
ip_wccp.c
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File ip_wccp.c of Package squid
/* * $Id: ip_wccp.c,v 1.6 2004/08/19 12:49:50 hno Exp $ * * Maintainer: * Henrik Nordstrom <hno@squid-cache.org> * * Change log: * 2004-08-19 SONE Naoto * Updated to support Linux 2.6.8 * * 2004-02-17 Henrik Nordstrom <hno@squid-cache.org> * Updated to linux-2.6.0 * WCCPv2 support * * 2003-10-20 Henrik Nordstrom <hno@squid-cache.org> * Dropped support for old kernels. Linux-2.4 or later required * Play well with Netfilter * * 2002-04-16 francis a. vidal <francisv@dagupan.com> * Module license tag * * 2002-04-13 Henrik Nordstrom <hno@squid-cache.org> * Updated to Linux-2.4 * - there no longer is a len argument to ip_wccp_recv * - deal with fragmented skb packets * - incremental checksumming to allow detection of corrupted * packets * * 1999-09-30 Glenn Chisholm <glenn@ircache.net> * Original release */ #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/version.h> #include <net/checksum.h> #include <net/protocol.h> #include <linux/netfilter_ipv4.h> #include <net/ip.h> #include <net/inet_ecn.h> #define WCCP_PROTOCOL_TYPE 0x883E #define WCCP_GRE_LEN sizeof(u32) #define WCCP2_GRE_EXTRA sizeof(u32) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9) /* New License scheme */ #ifdef MODULE_LICENSE MODULE_AUTHOR("Glenn Chisholm"); MODULE_DESCRIPTION("WCCP module"); MODULE_LICENSE("GPL"); #endif #endif static inline void ip_wccp_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff *skb) { struct iphdr *inner_iph = skb->nh.iph; if (INET_ECN_is_ce(outer_iph->tos) && INET_ECN_is_not_ce(inner_iph->tos)) IP_ECN_set_ce(inner_iph); } int ip_wccp_rcv(struct sk_buff *skb) { u32 *gre_hdr; struct iphdr *iph; if (!pskb_may_pull(skb, 16)) goto drop; iph = skb->nh.iph; gre_hdr = (u32 *)skb->h.raw; if(*gre_hdr != __constant_htonl(WCCP_PROTOCOL_TYPE)) goto drop; skb->mac.raw = skb->nh.raw; /* WCCP2 puts an extra 4 octets into the header, but uses the same * encapsulation type; if it looks as if the first octet of the packet * isn't the beginning of an IPv4 header, assume it's WCCP2. * This should be safe as these bits are reserved in the WCCPv2 header * and always zero in WCCPv2. */ if ((skb->h.raw[WCCP_GRE_LEN] & 0xF0) != 0x40) { skb->nh.raw = pskb_pull(skb, WCCP_GRE_LEN + WCCP2_GRE_EXTRA); } else { skb->nh.raw = pskb_pull(skb, WCCP_GRE_LEN); } 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; 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_wccp_ecn_decapsulate(iph, skb); netif_rx(skb); return(0); drop: kfree_skb(skb); return(0); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8) static struct net_protocol ipwccp_protocol = { #else static struct inet_protocol ipwccp_protocol = { #endif .handler = ip_wccp_rcv }; static inline void wccp_add_protocol(void) { inet_add_protocol(&ipwccp_protocol, IPPROTO_GRE); } static inline int wccp_del_protocol(void) { return inet_del_protocol(&ipwccp_protocol, IPPROTO_GRE); } #else static struct inet_protocol ipwccp_protocol = { ip_wccp_rcv, NULL, 0, IPPROTO_GRE, 0, NULL, "GRE" }; static inline void wccp_add_protocol(void) { inet_add_protocol(&ipwccp_protocol); } static inline int wccp_del_protocol(void) { return inet_del_protocol(&ipwccp_protocol); } #endif int __init ip_wccp_init(void) { printk(KERN_INFO "WCCP IPv4/GRE driver\n"); wccp_add_protocol(); return 0; } static void __exit ip_wccp_fini(void) { if (wccp_del_protocol() < 0) printk(KERN_INFO "ip_wccp: can't remove protocol\n"); else printk(KERN_INFO "WCCP IPv4/GRE driver unloaded\n"); } #ifdef MODULE module_init(ip_wccp_init); #endif module_exit(ip_wccp_fini);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor