diff options
Diffstat (limited to 'net/ipv4/ip_tunnel_core.c')
-rw-r--r-- | net/ipv4/ip_tunnel_core.c | 34 |
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 | } |
88 | EXPORT_SYMBOL_GPL(iptunnel_xmit); | 88 | EXPORT_SYMBOL_GPL(iptunnel_xmit); |
89 | |||
90 | int 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 | } | ||
122 | EXPORT_SYMBOL_GPL(iptunnel_pull_header); | ||