* [PATCH net 1/3] vti6: Properly adjust vti6 MTU from MTU of lower device
2018-03-15 16:17 [PATCH net 0/3] vti6: Fixes for MTU assignment and validation Stefano Brivio
@ 2018-03-15 16:17 ` Stefano Brivio
2018-03-15 16:17 ` [PATCH net 2/3] vti6: Keep set MTU on link creation or change, validate it Stefano Brivio
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Stefano Brivio @ 2018-03-15 16:17 UTC (permalink / raw)
To: David S . Miller
Cc: Sabrina Dubroca, Steffen Klassert, Herbert Xu, Alexey Kodanev,
Jarod Wilson, netdev
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>
---
net/ipv6/ip6_vti.c | 10 ++++++----
1 file 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)
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;
--
2.15.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH net 2/3] vti6: Keep set MTU on link creation or change, validate it
2018-03-15 16:17 [PATCH net 0/3] vti6: Fixes for MTU assignment and validation Stefano Brivio
2018-03-15 16:17 ` [PATCH net 1/3] vti6: Properly adjust vti6 MTU from MTU of lower device Stefano Brivio
@ 2018-03-15 16:17 ` Stefano Brivio
2018-03-15 16:17 ` [PATCH net 3/3] vti6: Fix dev->max_mtu setting Stefano Brivio
2018-03-19 10:20 ` [PATCH net 0/3] vti6: Fixes for MTU assignment and validation Steffen Klassert
3 siblings, 0 replies; 5+ messages in thread
From: Stefano Brivio @ 2018-03-15 16:17 UTC (permalink / raw)
To: David S . Miller
Cc: Sabrina Dubroca, Steffen Klassert, Herbert Xu, Alexey Kodanev,
Jarod Wilson, netdev
In vti6_link_config(), if MTU is already given on link creation
or change, validate and use it instead of recomputing it. To do
that, we need to propagate the knowledge that MTU was set by
userspace all the way down to vti6_link_config().
To keep this simple, vti6_dev_init() sets the new 'keep_mtu'
argument of vti6_link_config() to true: on initialization, we
don't have convenient access to netlink attributes there, but we
will anyway check whether dev->mtu is set in vti6_link_config().
If it's non-zero, it was set to the value of the IFLA_MTU
attribute during creation. Otherwise, determine a reasonable
value.
Fixes: ed1efb2aefbb ("ipv6: Add support for IPsec virtual tunnel interfaces")
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>
---
net/ipv6/ip6_vti.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 2ceef41cc097..971175142e14 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -622,7 +622,7 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return 0;
}
-static void vti6_link_config(struct ip6_tnl *t)
+static void vti6_link_config(struct ip6_tnl *t, bool keep_mtu)
{
struct net_device *dev = t->dev;
struct __ip6_tnl_parm *p = &t->parms;
@@ -641,6 +641,11 @@ static void vti6_link_config(struct ip6_tnl *t)
else
dev->flags &= ~IFF_POINTOPOINT;
+ if (keep_mtu && dev->mtu) {
+ dev->mtu = clamp(dev->mtu, dev->min_mtu, dev->max_mtu);
+ return;
+ }
+
if (p->flags & IP6_TNL_F_CAP_XMIT) {
int strict = (ipv6_addr_type(&p->raddr) &
(IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
@@ -668,12 +673,14 @@ static void vti6_link_config(struct ip6_tnl *t)
* vti6_tnl_change - update the tunnel parameters
* @t: tunnel to be changed
* @p: tunnel configuration parameters
+ * @keep_mtu: MTU was set from userspace, don't re-compute it
*
* Description:
* vti6_tnl_change() updates the tunnel parameters
**/
static int
-vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
+vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p,
+ bool keep_mtu)
{
t->parms.laddr = p->laddr;
t->parms.raddr = p->raddr;
@@ -683,11 +690,12 @@ vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
t->parms.proto = p->proto;
t->parms.fwmark = p->fwmark;
dst_cache_reset(&t->dst_cache);
- vti6_link_config(t);
+ vti6_link_config(t, keep_mtu);
return 0;
}
-static int vti6_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
+static int vti6_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p,
+ bool keep_mtu)
{
struct net *net = dev_net(t->dev);
struct vti6_net *ip6n = net_generic(net, vti6_net_id);
@@ -695,7 +703,7 @@ static int vti6_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
vti6_tnl_unlink(ip6n, t);
synchronize_net();
- err = vti6_tnl_change(t, p);
+ err = vti6_tnl_change(t, p, keep_mtu);
vti6_tnl_link(ip6n, t);
netdev_state_change(t->dev);
return err;
@@ -808,7 +816,7 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
} else
t = netdev_priv(dev);
- err = vti6_update(t, &p1);
+ err = vti6_update(t, &p1, false);
}
if (t) {
err = 0;
@@ -907,7 +915,7 @@ static int vti6_dev_init(struct net_device *dev)
if (err)
return err;
- vti6_link_config(t);
+ vti6_link_config(t, true);
return 0;
}
@@ -1012,7 +1020,7 @@ static int vti6_changelink(struct net_device *dev, struct nlattr *tb[],
} else
t = netdev_priv(dev);
- return vti6_update(t, &p);
+ return vti6_update(t, &p, tb && tb[IFLA_MTU]);
}
static size_t vti6_get_size(const struct net_device *dev)
--
2.15.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH net 3/3] vti6: Fix dev->max_mtu setting
2018-03-15 16:17 [PATCH net 0/3] vti6: Fixes for MTU assignment and validation Stefano Brivio
2018-03-15 16:17 ` [PATCH net 1/3] vti6: Properly adjust vti6 MTU from MTU of lower device Stefano Brivio
2018-03-15 16:17 ` [PATCH net 2/3] vti6: Keep set MTU on link creation or change, validate it Stefano Brivio
@ 2018-03-15 16:17 ` Stefano Brivio
2018-03-19 10:20 ` [PATCH net 0/3] vti6: Fixes for MTU assignment and validation Steffen Klassert
3 siblings, 0 replies; 5+ messages in thread
From: Stefano Brivio @ 2018-03-15 16:17 UTC (permalink / raw)
To: David S . Miller
Cc: Sabrina Dubroca, Steffen Klassert, Herbert Xu, Alexey Kodanev,
Jarod Wilson, netdev
We shouldn't allow a tunnel to have IP_MAX_MTU as MTU, because
another IPv6 header is going on top of our packets. Without this
patch, we might end up building packets bigger than IP_MAX_MTU.
Fixes: b96f9afee4eb ("ipv4/6: use core net MTU range checking")
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Acked-by: Sabrina Dubroca <sd@queasysnail.net>
---
net/ipv6/ip6_vti.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 971175142e14..ce18cd20389d 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -879,7 +879,7 @@ static void vti6_dev_setup(struct net_device *dev)
dev->type = ARPHRD_TUNNEL6;
dev->min_mtu = IPV6_MIN_MTU;
- dev->max_mtu = IP_MAX_MTU;
+ dev->max_mtu = IP_MAX_MTU - sizeof(struct ipv6hdr);
dev->flags |= IFF_NOARP;
dev->addr_len = sizeof(struct in6_addr);
netif_keep_dst(dev);
--
2.15.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH net 0/3] vti6: Fixes for MTU assignment and validation
2018-03-15 16:17 [PATCH net 0/3] vti6: Fixes for MTU assignment and validation Stefano Brivio
` (2 preceding siblings ...)
2018-03-15 16:17 ` [PATCH net 3/3] vti6: Fix dev->max_mtu setting Stefano Brivio
@ 2018-03-19 10:20 ` Steffen Klassert
3 siblings, 0 replies; 5+ messages in thread
From: Steffen Klassert @ 2018-03-19 10:20 UTC (permalink / raw)
To: Stefano Brivio
Cc: David S . Miller, Sabrina Dubroca, Herbert Xu, Alexey Kodanev,
Jarod Wilson, netdev
On Thu, Mar 15, 2018 at 05:17:10PM +0100, Stefano Brivio wrote:
> This series introduces fixes to ensure that default MTU
> assignment for vti6 is properly calculated (and to make it
> consistent with vti4), to ensure we always use the MTU from
> userspace (and validate it), if given, when a link is created or
> changed, and that the MTU upper bound is properly set.
>
> Stefano Brivio (3):
> vti6: Properly adjust vti6 MTU from MTU of lower device
> vti6: Keep set MTU on link creation or change, validate it
> vti6: Fix dev->max_mtu setting
>
> net/ipv6/ip6_vti.c | 36 +++++++++++++++++++++++-------------
> 1 file changed, 23 insertions(+), 13 deletions(-)
Also applied, thanks Stefano!
^ permalink raw reply [flat|nested] 5+ messages in thread