diff options
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r-- | net/ipv4/ip_gre.c | 15 |
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: | |||
959 | static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) | 959 | static 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; |