lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  PHC 
Open Source and information security mailing list archives
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 27 May 2020 14:25:08 -0700
From:   Edwin Peer <>
Cc:     Edwin Peer <>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Subject: [RFC PATCH net-next 07/11] net: gre: constrain upper VLAN MTU using IFF_NO_VLAN_ROOM

Constrain the MTU of upper VLAN devices if the MTU of the GRE device
is configured to its default optimal size, which does not leave space
for a nested VLAN tag without causing fragmentation. If the underlying
lower device is not known, then the worst case is assumed and any upper
VLAN devices will always be adjusted to accommodate the VLAN tag.

For IPv4 tunnels, the changes to support this are made in the generic
ip_tunnel_change_mtu() handler and so IFF_NO_VLAN_ROOM is consequently
maintained for all tunnel devices that leverage this implementation. GRE
is, however, the only one of these implementations that might use an L2
overlay. At present nothing prevents VLAN devices being layered above
raw IP tunnel devices, which does not make sense. This limitation will
be addressed by a later patch in this series.

IPv6 GRE is dependent on PMTU discovery, but the MTU of nested VLANs
still need to be constrained, because non-VLAN packets will share the
same path MTU.

Signed-off-by: Edwin Peer <>
 net/ipv4/ip_tunnel.c | 2 ++
 net/ipv6/ip6_gre.c   | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index f4f1d11eab50..21803bd35ab3 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -981,6 +981,7 @@ int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
 	int max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen;
+	int best_mtu = ip_tunnel_bind_dev(dev);
 	if (new_mtu < ETH_MIN_MTU)
 		return -EINVAL;
@@ -993,6 +994,7 @@ int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
 	dev->mtu = new_mtu;
+	__vlan_constrain_mtu(dev, best_mtu);
 	return 0;
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 781ca8c07a0d..0b86ee7f3d31 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1131,6 +1131,8 @@ static void ip6gre_tnl_link_config_route(struct ip6_tnl *t, int set_mtu,
 				if (dev->mtu < IPV6_MIN_MTU)
 					dev->mtu = IPV6_MIN_MTU;
+				dev->priv_flags |= IFF_NO_VLAN_ROOM;
@@ -1801,7 +1803,7 @@ static int ip6gre_tap_init(struct net_device *dev)
 	if (ret)
 		return ret;
-	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_VLAN_ROOM;
 	return 0;

Powered by blists - more mailing lists