Skip to content

Commit

Permalink
vti6: Properly adjust vti6 MTU from MTU of lower device
Browse files Browse the repository at this point in the history
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 a324523 ("vti4: Don't count header length twice."),
which was accidentally reverted by merge commit f895f0c
("Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec").

While commit 53c81e9 ("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: 53c81e9 ("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>
  • Loading branch information
Stefano Brivio authored and Steffen Klassert committed Mar 19, 2018
1 parent 03080e5 commit c6741fb
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions net/ipv6/ip6_vti.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@ static void vti6_link_config(struct ip6_tnl *t)
struct net_device *dev = t->dev;
struct __ip6_tnl_parm *p = &t->parms;
struct net_device *tdev = NULL;
int mtu;

memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
Expand Down Expand Up @@ -656,8 +657,11 @@ static void vti6_link_config(struct ip6_tnl *t)
tdev = __dev_get_by_index(t->net, p->link);

if (tdev)
dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len,
IPV6_MIN_MTU);
mtu = tdev->mtu - sizeof(struct ipv6hdr);
else
mtu = ETH_DATA_LEN - LL_MAX_HEADER - sizeof(struct ipv6hdr);

dev->mtu = max_t(int, mtu, IPV6_MIN_MTU);
}

/**
Expand Down Expand Up @@ -866,8 +870,6 @@ static void vti6_dev_setup(struct net_device *dev)
dev->priv_destructor = vti6_dev_free;

dev->type = ARPHRD_TUNNEL6;
dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
dev->mtu = ETH_DATA_LEN;
dev->min_mtu = IPV6_MIN_MTU;
dev->max_mtu = IP_MAX_MTU;
dev->flags |= IFF_NOARP;
Expand Down

0 comments on commit c6741fb

Please sign in to comment.