@@ -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
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(-)