X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fip_gre.c;h=2c768ecc0a84cd84ab98b4bf901deccae5d65f2c;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=4a227f51b2c120983e0d8a7bef0e5fd6b7ea4833;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 4a227f51b..2c768ecc0 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -533,11 +534,9 @@ static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) { if (INET_ECN_is_ce(iph->tos)) { if (skb->protocol == htons(ETH_P_IP)) { - if (INET_ECN_is_not_ce(skb->nh.iph->tos)) - IP_ECN_set_ce(skb->nh.iph); + IP_ECN_set_ce(skb->nh.iph); } else if (skb->protocol == htons(ETH_P_IPV6)) { - if (INET_ECN_is_not_ce(ip6_get_dsfield(skb->nh.ipv6h))) - IP6_ECN_set_ce(skb->nh.ipv6h); + IP6_ECN_set_ce(skb->nh.ipv6h); } } } @@ -549,7 +548,7 @@ ipgre_ecn_encapsulate(u8 tos, struct iphdr *old_iph, struct sk_buff *skb) if (skb->protocol == htons(ETH_P_IP)) inner = old_iph->tos; else if (skb->protocol == htons(ETH_P_IPV6)) - inner = ip6_get_dsfield((struct ipv6hdr*)old_iph); + inner = ipv6_get_dsfield((struct ipv6hdr *)old_iph); return INET_ECN_encapsulate(tos, inner); } @@ -605,13 +604,24 @@ int ipgre_rcv(struct sk_buff *skb) if ((tunnel = ipgre_tunnel_lookup(iph->saddr, iph->daddr, key)) != NULL) { secpath_reset(skb); + skb->protocol = *(u16*)(h + 2); + /* WCCP version 1 and 2 protocol decoding. + * - Change protocol to IP + * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header + */ + if (flags == 0 && + skb->protocol == __constant_htons(ETH_P_WCCP)) { + skb->protocol = __constant_htons(ETH_P_IP); + if ((*(h + offset) & 0xF0) != 0x40) + offset += 4; + } + skb->mac.raw = skb->nh.raw; skb->nh.raw = __pskb_pull(skb, offset); memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); if (skb->ip_summed == CHECKSUM_HW) skb->csum = csum_sub(skb->csum, csum_partial(skb->mac.raw, skb->nh.raw-skb->mac.raw, 0)); - skb->protocol = *(u16*)(h + 2); skb->pkt_type = PACKET_HOST; #ifdef CONFIG_NET_IPGRE_BROADCAST if (MULTICAST(iph->daddr)) { @@ -643,13 +653,7 @@ int ipgre_rcv(struct sk_buff *skb) skb->dev = tunnel->dev; 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 + nf_reset(skb); ipgre_ecn_decapsulate(iph, skb); netif_rx(skb); read_unlock(&ipgre_lock); @@ -877,13 +881,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) } } -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -#endif + nf_reset(skb); IPTUNNEL_XMIT(); tunnel->recursion--; @@ -1240,7 +1238,7 @@ int __init ipgre_fb_tunnel_init(struct net_device *dev) } -static struct inet_protocol ipgre_protocol = { +static struct net_protocol ipgre_protocol = { .handler = ipgre_rcv, .err_handler = ipgre_err, }; @@ -1252,7 +1250,7 @@ static struct inet_protocol ipgre_protocol = { static int __init ipgre_init(void) { - int err = -EINVAL; + int err; printk(KERN_INFO "GRE over IPv4 tunneling driver\n"); @@ -1265,18 +1263,19 @@ static int __init ipgre_init(void) ipgre_tunnel_setup); if (!ipgre_fb_tunnel_dev) { err = -ENOMEM; - goto fail; + goto err1; } ipgre_fb_tunnel_dev->init = ipgre_fb_tunnel_init; if ((err = register_netdev(ipgre_fb_tunnel_dev))) - goto fail; + goto err2; out: return err; -fail: - inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); +err2: free_netdev(ipgre_fb_tunnel_dev); +err1: + inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); goto out; }