aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2018-03-15 12:17:11 -0400
committerSteffen Klassert <steffen.klassert@secunet.com>2018-03-19 03:45:50 -0400
commitc6741fbed6dc0f183d26c4b6bca4517672f92e6c (patch)
tree4040c201e7a52e8a7bcde131cf58952d96fcc404
parent03080e5ec72740c1a62e6730f2a5f3f114f11b19 (diff)
vti6: Properly adjust vti6 MTU from MTU of lower device
If a lower device is found, we don't need to subtract LL_MAX_HEADER to calculate our MTU: just use its MTU, the link layer headers are already taken into account by it. If the lower device is not found, start from ETH_DATA_LEN instead, and only in this case subtract a worst-case LL_MAX_HEADER. We then need to subtract our additional IPv6 header from the calculation. While at it, note that vti6 doesn't have a hardware header, so it doesn't need to set dev->hard_header_len. And as vti6_link_config() now always sets the MTU, there's no need to set a default value in vti6_dev_setup(). This makes the behaviour consistent with IPv4 vti, after commit a32452366b72 ("vti4: Don't count header length twice."), which was accidentally reverted by merge commit f895f0cfbb77 ("Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec"). While commit 53c81e95df17 ("ip6_vti: adjust vti mtu according to mtu of lower device") improved on the original situation, this was still not ideal. As reported in that commit message itself, if we start from an underlying veth MTU of 9000, we end up with an MTU of 8832, that is, 9000 - LL_MAX_HEADER - sizeof(ipv6hdr). This should simply be 8880, or 9000 - sizeof(ipv6hdr) instead: we found the lower device (veth) and we know we don't have any additional link layer header, so there's no need to subtract an hypothetical worst-case number. Fixes: 53c81e95df17 ("ip6_vti: adjust vti mtu according to mtu of lower device") Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Acked-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r--net/ipv6/ip6_vti.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index fa3ae1cb50d3..2ceef41cc097 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -627,6 +627,7 @@ static void vti6_link_config(struct ip6_tnl *t)
627 struct net_device *dev = t->dev; 627 struct net_device *dev = t->dev;
628 struct __ip6_tnl_parm *p = &t->parms; 628 struct __ip6_tnl_parm *p = &t->parms;
629 struct net_device *tdev = NULL; 629 struct net_device *tdev = NULL;
630 int mtu;
630 631
631 memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr)); 632 memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
632 memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr)); 633 memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
@@ -656,8 +657,11 @@ static void vti6_link_config(struct ip6_tnl *t)
656 tdev = __dev_get_by_index(t->net, p->link); 657 tdev = __dev_get_by_index(t->net, p->link);
657 658
658 if (tdev) 659 if (tdev)
659 dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len, 660 mtu = tdev->mtu - sizeof(struct ipv6hdr);
660 IPV6_MIN_MTU); 661 else
662 mtu = ETH_DATA_LEN - LL_MAX_HEADER - sizeof(struct ipv6hdr);
663
664 dev->mtu = max_t(int, mtu, IPV6_MIN_MTU);
661} 665}
662 666
663/** 667/**
@@ -866,8 +870,6 @@ static void vti6_dev_setup(struct net_device *dev)
866 dev->priv_destructor = vti6_dev_free; 870 dev->priv_destructor = vti6_dev_free;
867 871
868 dev->type = ARPHRD_TUNNEL6; 872 dev->type = ARPHRD_TUNNEL6;
869 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
870 dev->mtu = ETH_DATA_LEN;
871 dev->min_mtu = IPV6_MIN_MTU; 873 dev->min_mtu = IPV6_MIN_MTU;
872 dev->max_mtu = IP_MAX_MTU; 874 dev->max_mtu = IP_MAX_MTU;
873 dev->flags |= IFF_NOARP; 875 dev->flags |= IFF_NOARP;