ip_tunnel: push generic protocol handling to ip_tunnel module.
[linux-2.6-block.git] / net / ipv4 / ip_tunnel_core.c
index 927687e83f182788c76651d9439d4f7129a7de17..7167b08977df582bd38565cf960568a8553f29d4 100644 (file)
@@ -86,3 +86,37 @@ int iptunnel_xmit(struct net *net, struct rtable *rt,
        return pkt_len;
 }
 EXPORT_SYMBOL_GPL(iptunnel_xmit);
+
+int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
+{
+       if (unlikely(!pskb_may_pull(skb, hdr_len)))
+               return -ENOMEM;
+
+       skb_pull_rcsum(skb, hdr_len);
+
+       if (inner_proto == htons(ETH_P_TEB)) {
+               struct ethhdr *eh = (struct ethhdr *)skb->data;
+
+               if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+                       return -ENOMEM;
+
+               if (likely(ntohs(eh->h_proto) >= ETH_P_802_3_MIN))
+                       skb->protocol = eh->h_proto;
+               else
+                       skb->protocol = htons(ETH_P_802_2);
+
+       } else {
+               skb->protocol = inner_proto;
+       }
+
+       nf_reset(skb);
+       secpath_reset(skb);
+       if (!skb->l4_rxhash)
+               skb->rxhash = 0;
+       skb_dst_drop(skb);
+       skb->vlan_tci = 0;
+       skb_set_queue_mapping(skb, 0);
+       skb->pkt_type = PACKET_HOST;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(iptunnel_pull_header);