diff options
Diffstat (limited to 'net/ipv4/ip_tunnel.c')
| -rw-r--r-- | net/ipv4/ip_tunnel.c | 9 | 
1 files changed, 9 insertions, 0 deletions
| diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index c4f5602308ed..284a22154b4e 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -627,6 +627,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,  		    const struct iphdr *tnl_params, u8 protocol)  {  	struct ip_tunnel *tunnel = netdev_priv(dev); +	unsigned int inner_nhdr_len = 0;  	const struct iphdr *inner_iph;  	struct flowi4 fl4;  	u8     tos, ttl; @@ -636,6 +637,14 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,  	__be32 dst;  	bool connected; +	/* ensure we can access the inner net header, for several users below */ +	if (skb->protocol == htons(ETH_P_IP)) +		inner_nhdr_len = sizeof(struct iphdr); +	else if (skb->protocol == htons(ETH_P_IPV6)) +		inner_nhdr_len = sizeof(struct ipv6hdr); +	if (unlikely(!pskb_may_pull(skb, inner_nhdr_len))) +		goto tx_error; +  	inner_iph = (const struct iphdr *)skb_inner_network_header(skb);  	connected = (tunnel->parms.iph.daddr != 0); |