diff options
author | Xin Long <lucien.xin@gmail.com> | 2017-09-28 13:24:07 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-12 11:51:23 +0200 |
commit | 09788d46b756a71313378b56d1a927a5ee64f7ce (patch) | |
tree | f8b139ae89b03f3671a696debffdebb447f095df /net/ipv6 | |
parent | ab4da56f61bed798a833b8fd9cf64d88b1ba27a3 (diff) | |
download | linux-stable-09788d46b756a71313378b56d1a927a5ee64f7ce.tar.gz linux-stable-09788d46b756a71313378b56d1a927a5ee64f7ce.tar.bz2 linux-stable-09788d46b756a71313378b56d1a927a5ee64f7ce.zip |
ip6_tunnel: update mtu properly for ARPHRD_ETHER tunnel device in tx path
[ Upstream commit d41bb33ba33b8f8debe54ed36be6925eb496e354 ]
Now when updating mtu in tx path, it doesn't consider ARPHRD_ETHER tunnel
device, like ip6gre_tap tunnel, for which it should also subtract ether
header to get the correct mtu.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index a39f28ffbd63..12b2fd512f32 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1042,6 +1042,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, struct dst_entry *dst = NULL, *ndst = NULL; struct net_device *tdev; int mtu; + unsigned int eth_hlen = t->dev->type == ARPHRD_ETHER ? ETH_HLEN : 0; unsigned int psh_hlen = sizeof(struct ipv6hdr) + t->encap_hlen; unsigned int max_headroom = psh_hlen; bool use_cache = false; @@ -1120,7 +1121,7 @@ route_lookup: t->parms.name); goto tx_err_dst_release; } - mtu = dst_mtu(dst) - psh_hlen - t->tun_hlen; + mtu = dst_mtu(dst) - eth_hlen - psh_hlen - t->tun_hlen; if (encap_limit >= 0) { max_headroom += 8; mtu -= 8; @@ -1129,7 +1130,7 @@ route_lookup: mtu = IPV6_MIN_MTU; if (skb_dst(skb) && !t->parms.collect_md) skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); - if (skb->len - t->tun_hlen > mtu && !skb_is_gso(skb)) { + if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { *pmtu = mtu; err = -EMSGSIZE; goto tx_err_dst_release; |