diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 65439188c582..e992c6a05f86 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2367,27 +2367,41 @@ static void vxlan_set_multicast_list(struct net_device *dev) { } +static int __vxlan_change_mtu(struct net_device *dev, + struct net_device *lowerdev, + struct vxlan_rdst *dst, int new_mtu, bool strict) +{ + int max_mtu = IP_MAX_MTU; + + if (lowerdev) + max_mtu = lowerdev->mtu; + + if (dst->remote_ip.sa.sa_family == AF_INET6) + max_mtu -= VXLAN6_HEADROOM; + else + max_mtu -= VXLAN_HEADROOM; + + if (new_mtu < 68) + return -EINVAL; + + if (new_mtu > max_mtu) { + if (strict) + return -EINVAL; + + new_mtu = max_mtu; + } + + dev->mtu = new_mtu; + return 0; +} + static int vxlan_change_mtu(struct net_device *dev, int new_mtu) { struct vxlan_dev *vxlan = netdev_priv(dev); struct vxlan_rdst *dst = &vxlan->default_dst; - struct net_device *lowerdev; - int max_mtu; - - lowerdev = __dev_get_by_index(vxlan->net, dst->remote_ifindex); - if (lowerdev == NULL) - return eth_change_mtu(dev, new_mtu); - - if (dst->remote_ip.sa.sa_family == AF_INET6) - max_mtu = lowerdev->mtu - VXLAN6_HEADROOM; - else - max_mtu = lowerdev->mtu - VXLAN_HEADROOM; - - if (new_mtu < 68 || new_mtu > max_mtu) - return -EINVAL; - - dev->mtu = new_mtu; - return 0; + struct net_device *lowerdev = __dev_get_by_index(vxlan->net, + dst->remote_ifindex); + return __vxlan_change_mtu(dev, lowerdev, dst, new_mtu, true); } static int egress_ipv4_tun_info(struct net_device *dev, struct sk_buff *skb,