mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 14:42:24 +00:00
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 commita32452366b
("vti4: Don't count header length twice."), which was accidentally reverted by merge commitf895f0cfbb
("Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec"). While commit53c81e95df
("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:53c81e95df
("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>
This commit is contained in:
parent
03080e5ec7
commit
c6741fbed6
@ -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));
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user