aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_gre.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r--net/ipv4/ip_gre.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 2a61158ea722..fd192d676955 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -637,7 +637,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
637 637
638 df = tiph->frag_off; 638 df = tiph->frag_off;
639 if (df) 639 if (df)
640 mtu = dst_mtu(&rt->u.dst) - tunnel->hlen; 640 mtu = dst_mtu(&rt->u.dst) - dev->hard_header_len - tunnel->hlen;
641 else 641 else
642 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; 642 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
643 643
@@ -785,7 +785,7 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev)
785 tunnel = netdev_priv(dev); 785 tunnel = netdev_priv(dev);
786 iph = &tunnel->parms.iph; 786 iph = &tunnel->parms.iph;
787 787
788 /* Guess output device to choose reasonable mtu and hard_header_len */ 788 /* Guess output device to choose reasonable mtu and needed_headroom */
789 789
790 if (iph->daddr) { 790 if (iph->daddr) {
791 struct flowi fl = { .oif = tunnel->parms.link, 791 struct flowi fl = { .oif = tunnel->parms.link,
@@ -806,7 +806,7 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev)
806 tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link); 806 tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link);
807 807
808 if (tdev) { 808 if (tdev) {
809 hlen = tdev->hard_header_len; 809 hlen = tdev->hard_header_len + tdev->needed_headroom;
810 mtu = tdev->mtu; 810 mtu = tdev->mtu;
811 } 811 }
812 dev->iflink = tunnel->parms.link; 812 dev->iflink = tunnel->parms.link;
@@ -820,8 +820,8 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev)
820 if (tunnel->parms.o_flags&GRE_SEQ) 820 if (tunnel->parms.o_flags&GRE_SEQ)
821 addend += 4; 821 addend += 4;
822 } 822 }
823 dev->hard_header_len = hlen + addend; 823 dev->needed_headroom = addend + hlen;
824 dev->mtu = mtu - addend; 824 dev->mtu = mtu - dev->hard_header_len - addend;
825 tunnel->hlen = addend; 825 tunnel->hlen = addend;
826 826
827} 827}
@@ -959,7 +959,8 @@ done:
959static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) 959static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
960{ 960{
961 struct ip_tunnel *tunnel = netdev_priv(dev); 961 struct ip_tunnel *tunnel = netdev_priv(dev);
962 if (new_mtu < 68 || new_mtu > 0xFFF8 - tunnel->hlen) 962 if (new_mtu < 68 ||
963 new_mtu > 0xFFF8 - dev->hard_header_len - tunnel->hlen)
963 return -EINVAL; 964 return -EINVAL;
964 dev->mtu = new_mtu; 965 dev->mtu = new_mtu;
965 return 0; 966 return 0;
@@ -1085,7 +1086,7 @@ static void ipgre_tunnel_setup(struct net_device *dev)
1085 dev->change_mtu = ipgre_tunnel_change_mtu; 1086 dev->change_mtu = ipgre_tunnel_change_mtu;
1086 1087
1087 dev->type = ARPHRD_IPGRE; 1088 dev->type = ARPHRD_IPGRE;
1088 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr) + 4; 1089 dev->needed_headroom = LL_MAX_HEADER + sizeof(struct iphdr) + 4;
1089 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 4; 1090 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 4;
1090 dev->flags = IFF_NOARP; 1091 dev->flags = IFF_NOARP;
1091 dev->iflink = 0; 1092 dev->iflink = 0;