diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index c5a557a..7d30a33 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -256,7 +256,7 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, if (dev->header_ops) { /* Need space for new headers */ - if (skb_cow_head(skb, dev->needed_headroom - + if (skb_cow_head(skb, dev->hard_header_len - (tunnel->hlen + sizeof(struct iphdr)))) goto free_skb; @@ -267,7 +267,7 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, */ skb_pull(skb, tunnel->hlen + sizeof(struct iphdr)); } else { - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->hard_header_len)) goto free_skb; tnl_params = &tunnel->parms.iph; @@ -293,7 +293,7 @@ static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, if (IS_ERR(skb)) goto out; - if (skb_cow_head(skb, dev->needed_headroom)) + if (skb_cow_head(skb, dev->hard_header_len)) goto free_skb; __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_TEB)); @@ -475,7 +475,10 @@ static void __gre_tunnel_init(struct net_device *dev) tunnel->hlen = ip_gre_calc_hlen(tunnel->parms.o_flags); tunnel->parms.iph.protocol = IPPROTO_GRE; - dev->needed_headroom = LL_MAX_HEADER + sizeof(struct iphdr) + 4; + if (!dev->hard_header_len) + dev->hard_header_len = LL_MAX_HEADER; + + dev->hard_header_len += sizeof(struct iphdr) + 4; dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 4; dev->features |= GRE_FEATURES; diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 86a00bd..e7c116e 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -351,6 +351,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev) int hlen = LL_MAX_HEADER; int mtu = ETH_DATA_LEN; int t_hlen = tunnel->hlen + sizeof(struct iphdr); + int headroom = 0; iph = &tunnel->parms.iph; @@ -377,13 +378,15 @@ static int ip_tunnel_bind_dev(struct net_device *dev) tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link); if (tdev) { - hlen = tdev->hard_header_len + tdev->needed_headroom; + headroom = tdev->needed_headroom; + hlen = tdev->hard_header_len; mtu = tdev->mtu; } dev->iflink = tunnel->parms.link; - dev->needed_headroom = t_hlen + hlen; - mtu -= (dev->hard_header_len + t_hlen); + dev->needed_headroom = headroom; + dev->hard_header_len = t_hlen + hlen; + mtu -= t_hlen; if (mtu < 68) mtu = 68; @@ -483,12 +486,11 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, struct rtable *rt, __be16 df) { struct ip_tunnel *tunnel = netdev_priv(dev); - int pkt_size = skb->len - tunnel->hlen - dev->hard_header_len; + int pkt_size = skb->len - dev->hard_header_len; int mtu; if (df) - mtu = dst_mtu(&rt->dst) - dev->hard_header_len - - sizeof(struct iphdr) - tunnel->hlen; + mtu = dst_mtu(&rt->dst) - dev->hard_header_len; else mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; @@ -663,10 +665,8 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr) + rt->dst.header_len; - if (max_headroom > dev->needed_headroom) - dev->needed_headroom = max_headroom; - if (skb_cow_head(skb, dev->needed_headroom)) { + if (skb_cow_head(skb, max_headroom)) { dev->stats.tx_dropped++; kfree_skb(skb); return;