diff mbox series

[RFC,net-next,05/11] net: vxlan: constrain upper VLAN MTU using IFF_NO_VLAN_ROOM

Message ID 20200527212512.17901-6-edwin.peer@broadcom.com
State New
Headers show
Series [RFC,net-next,01/11] net: geneve: enable vlan offloads | expand

Commit Message

Edwin Peer May 27, 2020, 9:25 p.m. UTC
Constrain the MTU of upper VLAN devices if the MTU of the VXLAN 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.

Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
---
 drivers/net/vxlan.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index a0015cdedfaf..3e9c65eb4737 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -3098,18 +3098,20 @@  static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
 	struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
 							 dst->remote_ifindex);
 	bool use_ipv6 = !!(vxlan->cfg.flags & VXLAN_F_IPV6);
+	unsigned int max_mtu = 0;
 
 	/* This check is different than dev->max_mtu, because it looks at
 	 * the lowerdev->mtu, rather than the static dev->max_mtu
 	 */
 	if (lowerdev) {
-		int max_mtu = lowerdev->mtu -
-			      (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
+		max_mtu = lowerdev->mtu -
+			  (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
 		if (new_mtu > max_mtu)
 			return -EINVAL;
 	}
 
 	dev->mtu = new_mtu;
+	__vlan_constrain_mtu(dev, max_mtu);
 	return 0;
 }
 
@@ -3241,7 +3243,7 @@  static void vxlan_setup(struct net_device *dev)
 	dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
 	dev->hw_features |= NETIF_F_GSO_SOFTWARE;
 	netif_keep_dst(dev);
-	dev->priv_flags |= IFF_NO_QUEUE;
+	dev->priv_flags |= IFF_NO_QUEUE | IFF_NO_VLAN_ROOM;
 
 	/* MTU range: 68 - 65535 */
 	dev->min_mtu = ETH_MIN_MTU;
@@ -3762,6 +3764,8 @@  static void vxlan_config_apply(struct net_device *dev,
 	if (dev->mtu > max_mtu)
 		dev->mtu = max_mtu;
 
+	__vlan_constrain_mtu(dev, max_mtu);
+
 	if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)
 		needed_headroom += VXLAN6_HEADROOM;
 	else