diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8b84142fd775..915b210c4512 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -539,6 +539,12 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) }; int err; + if (skb->protocol != htons(ETH_P_IP) || !pskb_inet_may_pull(skb)) { + DEV_STATS_INC(dev, tx_errors); + kfree_skb(skb); + return NETDEV_TX_OK; + } + rcu_read_lock(); err = ipmr_fib_lookup(net, &fl4, &mrt); if (err < 0) { @@ -2511,6 +2517,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb, skb_push(skb2, sizeof(struct iphdr)); skb_reset_network_header(skb2); iph = ip_hdr(skb2); + memset(iph, 0, sizeof(*iph)); iph->ihl = sizeof(struct iphdr) >> 2; iph->saddr = saddr; iph->daddr = daddr; diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 3a551be30f15..a628acf50b0d 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -642,7 +642,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, .flowi6_mark = skb->mark, }; - if (!pskb_inet_may_pull(skb)) + if (skb->protocol != htons(ETH_P_IPV6) || !pskb_inet_may_pull(skb)) goto tx_err; rcu_read_lock();