aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_tunnel_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_tunnel_core.c')
-rw-r--r--net/ipv4/ip_tunnel_core.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 927687e83f18..7167b08977df 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -86,3 +86,37 @@ int iptunnel_xmit(struct net *net, struct rtable *rt,
86 return pkt_len; 86 return pkt_len;
87} 87}
88EXPORT_SYMBOL_GPL(iptunnel_xmit); 88EXPORT_SYMBOL_GPL(iptunnel_xmit);
89
90int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
91{
92 if (unlikely(!pskb_may_pull(skb, hdr_len)))
93 return -ENOMEM;
94
95 skb_pull_rcsum(skb, hdr_len);
96
97 if (inner_proto == htons(ETH_P_TEB)) {
98 struct ethhdr *eh = (struct ethhdr *)skb->data;
99
100 if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
101 return -ENOMEM;
102
103 if (likely(ntohs(eh->h_proto) >= ETH_P_802_3_MIN))
104 skb->protocol = eh->h_proto;
105 else
106 skb->protocol = htons(ETH_P_802_2);
107
108 } else {
109 skb->protocol = inner_proto;
110 }
111
112 nf_reset(skb);
113 secpath_reset(skb);
114 if (!skb->l4_rxhash)
115 skb->rxhash = 0;
116 skb_dst_drop(skb);
117 skb->vlan_tci = 0;
118 skb_set_queue_mapping(skb, 0);
119 skb->pkt_type = PACKET_HOST;
120 return 0;
121}
122EXPORT_SYMBOL_GPL(iptunnel_pull_header);