Re: [PATCH 4.4 92/97] ip6_vti: adjust vti mtu according to mtu of lower device
On Thu, Apr 05, 2018 at 05:36:36PM +0200, Stefano Brivio wrote: > On Wed, 04 Apr 2018 01:09:16 +0100 > Ben Hutchingswrote: > > > On Fri, 2018-03-23 at 10:55 +0100, Greg Kroah-Hartman wrote: > > > 4.4-stable review patch. If anyone has any objections, please let me > > > know. > > > > > > -- > > > > > > From: Alexey Kodanev > > > > > > > > > [ Upstream commit 53c81e95df1793933f87748d36070a721f6cb287 ] > > [...] > > > > There are a couple of follow-ups to this: > > > > c6741fbed6dc vti6: Properly adjust vti6 MTU from MTU of lower device > > 7a67e69a339a vti6: Keep set MTU on link creation or change, validate it > > > > The second of those will fail to build on branches older than 4.10 > > though. It might be better to revert this one instead. > > Thanks Ben for spotting this. > > Actually, > 53c81e95df17 ("ip6_vti: adjust vti mtu according to mtu of lower device") > alone improves things already, despite being "fixed" by > c6741fbed6dc ("vti6: Properly adjust vti6 MTU from MTU of lower device") > > With just 53c81e95df17 the MTU of a vti6 interface will be somewhat > linked to the MTU of the lower layer, but will be underestimated. > > With c6741fbed6dc the calculation of MTU from lower layer will be > accurate instead. > > However, without > 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") > but with > 53c81e95df17 ("ip6_vti: adjust vti mtu according to mtu of lower device") > assignment of MTU on link change is discarded, so this would actually > introduce a bug. > > Fixing > 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") > for 4.4 up to 4.9 is trivial, we simply need to adjust for the lack of > b96f9afee4eb ("ipv4/6: use core net MTU range checking") > and reflect the change introduced by > f8a554b4aa96 ("vti6: Fix dev->max_mtu setting"). > > So, Greg, here comes the backport of > 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") > based on latest linux-4.4.y branch, in case you want to keep the existing > change and add the follow-ups on top. Please let me know if I should submit > it formally. Ick, that's a mess. How about I just revert this patch from the stable trees, and then someone sends me either a list of git commits to apply, or patches, for the different trees if it's really needed? thanks, greg k-h
Re: [PATCH 4.4 92/97] ip6_vti: adjust vti mtu according to mtu of lower device
On Thu, Apr 05, 2018 at 05:36:36PM +0200, Stefano Brivio wrote: > On Wed, 04 Apr 2018 01:09:16 +0100 > Ben Hutchings wrote: > > > On Fri, 2018-03-23 at 10:55 +0100, Greg Kroah-Hartman wrote: > > > 4.4-stable review patch. If anyone has any objections, please let me > > > know. > > > > > > -- > > > > > > From: Alexey Kodanev > > > > > > > > > [ Upstream commit 53c81e95df1793933f87748d36070a721f6cb287 ] > > [...] > > > > There are a couple of follow-ups to this: > > > > c6741fbed6dc vti6: Properly adjust vti6 MTU from MTU of lower device > > 7a67e69a339a vti6: Keep set MTU on link creation or change, validate it > > > > The second of those will fail to build on branches older than 4.10 > > though. It might be better to revert this one instead. > > Thanks Ben for spotting this. > > Actually, > 53c81e95df17 ("ip6_vti: adjust vti mtu according to mtu of lower device") > alone improves things already, despite being "fixed" by > c6741fbed6dc ("vti6: Properly adjust vti6 MTU from MTU of lower device") > > With just 53c81e95df17 the MTU of a vti6 interface will be somewhat > linked to the MTU of the lower layer, but will be underestimated. > > With c6741fbed6dc the calculation of MTU from lower layer will be > accurate instead. > > However, without > 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") > but with > 53c81e95df17 ("ip6_vti: adjust vti mtu according to mtu of lower device") > assignment of MTU on link change is discarded, so this would actually > introduce a bug. > > Fixing > 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") > for 4.4 up to 4.9 is trivial, we simply need to adjust for the lack of > b96f9afee4eb ("ipv4/6: use core net MTU range checking") > and reflect the change introduced by > f8a554b4aa96 ("vti6: Fix dev->max_mtu setting"). > > So, Greg, here comes the backport of > 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") > based on latest linux-4.4.y branch, in case you want to keep the existing > change and add the follow-ups on top. Please let me know if I should submit > it formally. Ick, that's a mess. How about I just revert this patch from the stable trees, and then someone sends me either a list of git commits to apply, or patches, for the different trees if it's really needed? thanks, greg k-h
Re: [PATCH 4.4 92/97] ip6_vti: adjust vti mtu according to mtu of lower device
On Wed, 04 Apr 2018 01:09:16 +0100 Ben Hutchingswrote: > On Fri, 2018-03-23 at 10:55 +0100, Greg Kroah-Hartman wrote: > > 4.4-stable review patch. If anyone has any objections, please let me know. > > > > -- > > > > From: Alexey Kodanev > > > > > > [ Upstream commit 53c81e95df1793933f87748d36070a721f6cb287 ] > [...] > > There are a couple of follow-ups to this: > > c6741fbed6dc vti6: Properly adjust vti6 MTU from MTU of lower device > 7a67e69a339a vti6: Keep set MTU on link creation or change, validate it > > The second of those will fail to build on branches older than 4.10 > though. It might be better to revert this one instead. Thanks Ben for spotting this. Actually, 53c81e95df17 ("ip6_vti: adjust vti mtu according to mtu of lower device") alone improves things already, despite being "fixed" by c6741fbed6dc ("vti6: Properly adjust vti6 MTU from MTU of lower device") With just 53c81e95df17 the MTU of a vti6 interface will be somewhat linked to the MTU of the lower layer, but will be underestimated. With c6741fbed6dc the calculation of MTU from lower layer will be accurate instead. However, without 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") but with 53c81e95df17 ("ip6_vti: adjust vti mtu according to mtu of lower device") assignment of MTU on link change is discarded, so this would actually introduce a bug. Fixing 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") for 4.4 up to 4.9 is trivial, we simply need to adjust for the lack of b96f9afee4eb ("ipv4/6: use core net MTU range checking") and reflect the change introduced by f8a554b4aa96 ("vti6: Fix dev->max_mtu setting"). So, Greg, here comes the backport of 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") based on latest linux-4.4.y branch, in case you want to keep the existing change and add the follow-ups on top. Please let me know if I should submit it formally. diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 176e79076fb1..f388f54b4162 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -610,7 +610,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 = >parms; @@ -629,6 +629,13 @@ static void vti6_link_config(struct ip6_tnl *t) else dev->flags &= ~IFF_POINTOPOINT; + if (keep_mtu && dev->mtu) { + dev->mtu = clamp(dev->mtu, (unsigned)IPV6_MIN_MTU, +(unsigned)(IP_MAX_MTU - + sizeof(struct ipv6hdr))); + return; + } + if (p->flags & IP6_TNL_F_CAP_XMIT) { int strict = (ipv6_addr_type(>raddr) & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL)); @@ -656,12 +663,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; @@ -670,11 +679,12 @@ vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p) t->parms.o_key = p->o_key; t->parms.proto = p->proto; dst_cache_reset(>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); @@ -682,7 +692,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; @@ -795,7 +805,7 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } else t = netdev_priv(dev); - err = vti6_update(t, ); + err = vti6_update(t, , false); } if (t) { err = 0; @@ -907,7 +917,7 @@ static int vti6_dev_init(struct net_device *dev)
Re: [PATCH 4.4 92/97] ip6_vti: adjust vti mtu according to mtu of lower device
On Wed, 04 Apr 2018 01:09:16 +0100 Ben Hutchings wrote: > On Fri, 2018-03-23 at 10:55 +0100, Greg Kroah-Hartman wrote: > > 4.4-stable review patch. If anyone has any objections, please let me know. > > > > -- > > > > From: Alexey Kodanev > > > > > > [ Upstream commit 53c81e95df1793933f87748d36070a721f6cb287 ] > [...] > > There are a couple of follow-ups to this: > > c6741fbed6dc vti6: Properly adjust vti6 MTU from MTU of lower device > 7a67e69a339a vti6: Keep set MTU on link creation or change, validate it > > The second of those will fail to build on branches older than 4.10 > though. It might be better to revert this one instead. Thanks Ben for spotting this. Actually, 53c81e95df17 ("ip6_vti: adjust vti mtu according to mtu of lower device") alone improves things already, despite being "fixed" by c6741fbed6dc ("vti6: Properly adjust vti6 MTU from MTU of lower device") With just 53c81e95df17 the MTU of a vti6 interface will be somewhat linked to the MTU of the lower layer, but will be underestimated. With c6741fbed6dc the calculation of MTU from lower layer will be accurate instead. However, without 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") but with 53c81e95df17 ("ip6_vti: adjust vti mtu according to mtu of lower device") assignment of MTU on link change is discarded, so this would actually introduce a bug. Fixing 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") for 4.4 up to 4.9 is trivial, we simply need to adjust for the lack of b96f9afee4eb ("ipv4/6: use core net MTU range checking") and reflect the change introduced by f8a554b4aa96 ("vti6: Fix dev->max_mtu setting"). So, Greg, here comes the backport of 7a67e69a339a ("vti6: Keep set MTU on link creation or change, validate it") based on latest linux-4.4.y branch, in case you want to keep the existing change and add the follow-ups on top. Please let me know if I should submit it formally. diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 176e79076fb1..f388f54b4162 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -610,7 +610,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 = >parms; @@ -629,6 +629,13 @@ static void vti6_link_config(struct ip6_tnl *t) else dev->flags &= ~IFF_POINTOPOINT; + if (keep_mtu && dev->mtu) { + dev->mtu = clamp(dev->mtu, (unsigned)IPV6_MIN_MTU, +(unsigned)(IP_MAX_MTU - + sizeof(struct ipv6hdr))); + return; + } + if (p->flags & IP6_TNL_F_CAP_XMIT) { int strict = (ipv6_addr_type(>raddr) & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL)); @@ -656,12 +663,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; @@ -670,11 +679,12 @@ vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p) t->parms.o_key = p->o_key; t->parms.proto = p->proto; dst_cache_reset(>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); @@ -682,7 +692,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; @@ -795,7 +805,7 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } else t = netdev_priv(dev); - err = vti6_update(t, ); + err = vti6_update(t, , false); } if (t) { err = 0; @@ -907,7 +917,7 @@ static int vti6_dev_init(struct net_device *dev) if (err) return err; -
Re: [PATCH 4.4 92/97] ip6_vti: adjust vti mtu according to mtu of lower device
On Fri, 2018-03-23 at 10:55 +0100, Greg Kroah-Hartman wrote: > 4.4-stable review patch. If anyone has any objections, please let me know. > > -- > > From: Alexey Kodanev> > > [ Upstream commit 53c81e95df1793933f87748d36070a721f6cb287 ] [...] There are a couple of follow-ups to this: c6741fbed6dc vti6: Properly adjust vti6 MTU from MTU of lower device 7a67e69a339a vti6: Keep set MTU on link creation or change, validate it The second of those will fail to build on branches older than 4.10 though. It might be better to revert this one instead. Ben. -- Ben Hutchings Software Developer, Codethink Ltd.
Re: [PATCH 4.4 92/97] ip6_vti: adjust vti mtu according to mtu of lower device
On Fri, 2018-03-23 at 10:55 +0100, Greg Kroah-Hartman wrote: > 4.4-stable review patch. If anyone has any objections, please let me know. > > -- > > From: Alexey Kodanev > > > [ Upstream commit 53c81e95df1793933f87748d36070a721f6cb287 ] [...] There are a couple of follow-ups to this: c6741fbed6dc vti6: Properly adjust vti6 MTU from MTU of lower device 7a67e69a339a vti6: Keep set MTU on link creation or change, validate it The second of those will fail to build on branches older than 4.10 though. It might be better to revert this one instead. Ben. -- Ben Hutchings Software Developer, Codethink Ltd.
[PATCH 4.4 92/97] ip6_vti: adjust vti mtu according to mtu of lower device
4.4-stable review patch. If anyone has any objections, please let me know. -- From: Alexey Kodanev[ Upstream commit 53c81e95df1793933f87748d36070a721f6cb287 ] LTP/udp6_ipsec_vti tests fail when sending large UDP datagrams over ip6_vti that require fragmentation and the underlying device has an MTU smaller than 1500 plus some extra space for headers. This happens because ip6_vti, by default, sets MTU to ETH_DATA_LEN and not updating it depending on a destination address or link parameter. Further attempts to send UDP packets may succeed because pmtu gets updated on ICMPV6_PKT_TOOBIG in vti6_err(). In case the lower device has larger MTU size, e.g. 9000, ip6_vti works but not using the possible maximum size, output packets have 1500 limit. The above cases require manual MTU setup after ip6_vti creation. However ip_vti already updates MTU based on lower device with ip_tunnel_bind_dev(). Here is the example when the lower device MTU is set to 9000: # ip a sh ltp_ns_veth2 ltp_ns_veth2@if7: mtu 9000 ... inet 10.0.0.2/24 scope global ltp_ns_veth2 inet6 fd00::2/64 scope global # ip li add vti6 type vti6 local fd00::2 remote fd00::1 # ip li show vti6 vti6@NONE: mtu 1500 ... link/tunnel6 fd00::2 peer fd00::1 After the patch: # ip li add vti6 type vti6 local fd00::2 remote fd00::1 # ip li show vti6 vti6@NONE: mtu 8832 ... link/tunnel6 fd00::2 peer fd00::1 Reported-by: Petr Vorel Signed-off-by: Alexey Kodanev Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- net/ipv6/ip6_vti.c | 20 1 file changed, 20 insertions(+) --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -614,6 +614,7 @@ static void vti6_link_config(struct ip6_ { struct net_device *dev = t->dev; struct __ip6_tnl_parm *p = >parms; + struct net_device *tdev = NULL; memcpy(dev->dev_addr, >laddr, sizeof(struct in6_addr)); memcpy(dev->broadcast, >raddr, sizeof(struct in6_addr)); @@ -626,6 +627,25 @@ static void vti6_link_config(struct ip6_ dev->flags |= IFF_POINTOPOINT; else dev->flags &= ~IFF_POINTOPOINT; + + if (p->flags & IP6_TNL_F_CAP_XMIT) { + int strict = (ipv6_addr_type(>raddr) & + (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL)); + struct rt6_info *rt = rt6_lookup(t->net, +>raddr, >laddr, +p->link, strict); + + if (rt) + tdev = rt->dst.dev; + ip6_rt_put(rt); + } + + if (!tdev && p->link) + 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); } /**
[PATCH 4.4 92/97] ip6_vti: adjust vti mtu according to mtu of lower device
4.4-stable review patch. If anyone has any objections, please let me know. -- From: Alexey Kodanev [ Upstream commit 53c81e95df1793933f87748d36070a721f6cb287 ] LTP/udp6_ipsec_vti tests fail when sending large UDP datagrams over ip6_vti that require fragmentation and the underlying device has an MTU smaller than 1500 plus some extra space for headers. This happens because ip6_vti, by default, sets MTU to ETH_DATA_LEN and not updating it depending on a destination address or link parameter. Further attempts to send UDP packets may succeed because pmtu gets updated on ICMPV6_PKT_TOOBIG in vti6_err(). In case the lower device has larger MTU size, e.g. 9000, ip6_vti works but not using the possible maximum size, output packets have 1500 limit. The above cases require manual MTU setup after ip6_vti creation. However ip_vti already updates MTU based on lower device with ip_tunnel_bind_dev(). Here is the example when the lower device MTU is set to 9000: # ip a sh ltp_ns_veth2 ltp_ns_veth2@if7: mtu 9000 ... inet 10.0.0.2/24 scope global ltp_ns_veth2 inet6 fd00::2/64 scope global # ip li add vti6 type vti6 local fd00::2 remote fd00::1 # ip li show vti6 vti6@NONE: mtu 1500 ... link/tunnel6 fd00::2 peer fd00::1 After the patch: # ip li add vti6 type vti6 local fd00::2 remote fd00::1 # ip li show vti6 vti6@NONE: mtu 8832 ... link/tunnel6 fd00::2 peer fd00::1 Reported-by: Petr Vorel Signed-off-by: Alexey Kodanev Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- net/ipv6/ip6_vti.c | 20 1 file changed, 20 insertions(+) --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -614,6 +614,7 @@ static void vti6_link_config(struct ip6_ { struct net_device *dev = t->dev; struct __ip6_tnl_parm *p = >parms; + struct net_device *tdev = NULL; memcpy(dev->dev_addr, >laddr, sizeof(struct in6_addr)); memcpy(dev->broadcast, >raddr, sizeof(struct in6_addr)); @@ -626,6 +627,25 @@ static void vti6_link_config(struct ip6_ dev->flags |= IFF_POINTOPOINT; else dev->flags &= ~IFF_POINTOPOINT; + + if (p->flags & IP6_TNL_F_CAP_XMIT) { + int strict = (ipv6_addr_type(>raddr) & + (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL)); + struct rt6_info *rt = rt6_lookup(t->net, +>raddr, >laddr, +p->link, strict); + + if (rt) + tdev = rt->dst.dev; + ip6_rt_put(rt); + } + + if (!tdev && p->link) + 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); } /**