2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-01 06:45:17 +00:00

datapath: use core MTU range checking in core net infra

Upstream commit:
    commit 61e84623ace35ce48975e8f90bbbac7557c43d61
    Author: Jarod Wilson <jarod@redhat.com>
    Date:   Fri Oct 7 22:04:33 2016 -0400

    net: centralize net_device min/max MTU checking

    While looking into an MTU issue with sfc, I started noticing that almost
    every NIC driver with an ndo_change_mtu function implemented almost
    exactly the same range checks, and in many cases, that was the only
    practical thing their ndo_change_mtu function was doing. Quite a few
    drivers have either 68, 64, 60 or 46 as their minimum MTU value checked,
    and then various sizes from 1500 to 65535 for their maximum MTU value. We
    can remove a whole lot of redundant code here if we simple store min_mtu
    and max_mtu in net_device, and check against those in net/core/dev.c's
    dev_set_mtu().

    In theory, there should be zero functional change with this patch, it just
    puts the infrastructure in place. Subsequent patches will attempt to start
    using said infrastructure, with theoretically zero change in
    functionality.

    CC: netdev@vger.kernel.org
    Signed-off-by: Jarod Wilson <jarod@redhat.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Upstream commit:
    commit 91572088e3fdbf4fe31cf397926d8b890fdb3237
    Author: Jarod Wilson <jarod@redhat.com>
    Date:   Thu Oct 20 13:55:20 2016 -0400

    net: use core MTU range checking in core net infra

    ...

    openvswitch:
    - set min/max_mtu, remove internal_dev_change_mtu
    - note: max_mtu wasn't checked previously, it's been set to 65535, which
      is the largest possible size supported

    ...

    Signed-off-by: Jarod Wilson <jarod@redhat.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Jarno Rajahalme <jarno@ovn.org>

Upstream commit:
    commit 425df17ce3a26d98f76e2b6b0af2acf4aeb0b026
    Author: Jarno Rajahalme <jarno@ovn.org>
    Date:   Tue Feb 14 21:16:28 2017 -0800

    openvswitch: Set internal device max mtu to ETH_MAX_MTU.

    Commit 91572088e3fd ("net: use core MTU range checking in core net
    infra") changed the openvswitch internal device to use the core net
    infra for controlling the MTU range, but failed to actually set the
    max_mtu as described in the commit message, which now defaults to
    ETH_DATA_LEN.

    This patch fixes this by setting max_mtu to ETH_MAX_MTU after
    ether_setup() call.

    Fixes: 91572088e3fd ("net: use core MTU range checking in core net infra")
    Signed-off-by: Jarno Rajahalme <jarno@ovn.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>

This backport detects the new max_mtu field in the struct netdevice
and uses the upstream code if it exists, and local backport code if
not.  The latter case is amended with bounds checks with new upstream
macros ETH_MIN_MTU and ETH_MAX_MTU and the corresponding error
messages from the upstream commit.

Signed-off-by: Jarno Rajahalme <jarno@ovn.org>
Signed-off-by: Joe Stringer <joe@ovn.org>
This commit is contained in:
Jarod Wilson
2017-02-15 17:34:19 -08:00
committed by Joe Stringer
parent b43449eacb
commit 6c0bf0917f
3 changed files with 29 additions and 3 deletions

View File

@@ -510,6 +510,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
OVS_FIND_PARAM_IFELSE([$KSRC/include/linux/netdevice.h],
[netdev_master_upper_dev_link], [upper_priv],
[OVS_DEFINE([HAVE_NETDEV_MASTER_UPPER_DEV_LINK_PRIV])])
OVS_FIND_FIELD_IFELSE([$KSRC/include/linux/netdevice.h], [net_device],
[max_mtu])
OVS_GREP_IFELSE([$KSRC/include/linux/netfilter.h], [nf_hook_state])
OVS_GREP_IFELSE([$KSRC/include/linux/netfilter.h], [nf_register_net_hook])

View File

@@ -3,6 +3,14 @@
#include_next <linux/if_ether.h>
#ifndef ETH_MIN_MTU
#define ETH_MIN_MTU 68 /* Min IPv4 MTU per RFC791 */
#endif
#ifndef ETH_MAX_MTU
#define ETH_MAX_MTU 0xFFFFU /* 65535, same as IP_MAX_MTU */
#endif
#ifndef ETH_P_802_3_MIN
#define ETH_P_802_3_MIN 0x0600
#endif

View File

@@ -89,14 +89,25 @@ static const struct ethtool_ops internal_dev_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
static int internal_dev_change_mtu(struct net_device *netdev, int new_mtu)
#ifndef HAVE_NET_DEVICE_WITH_MAX_MTU
static int internal_dev_change_mtu(struct net_device *dev, int new_mtu)
{
if (new_mtu < 68)
if (new_mtu < ETH_MIN_MTU) {
net_err_ratelimited("%s: Invalid MTU %d requested, hw min %d\n",
dev->name, new_mtu, ETH_MIN_MTU);
return -EINVAL;
}
netdev->mtu = new_mtu;
if (new_mtu > ETH_MAX_MTU) {
net_err_ratelimited("%s: Invalid MTU %d requested, hw max %d\n",
dev->name, new_mtu, ETH_MAX_MTU);
return -EINVAL;
}
dev->mtu = new_mtu;
return 0;
}
#endif
static void internal_dev_destructor(struct net_device *dev)
{
@@ -150,7 +161,9 @@ static const struct net_device_ops internal_dev_netdev_ops = {
.ndo_stop = internal_dev_stop,
.ndo_start_xmit = internal_dev_xmit,
.ndo_set_mac_address = eth_mac_addr,
#ifndef HAVE_NET_DEVICE_WITH_MAX_MTU
.ndo_change_mtu = internal_dev_change_mtu,
#endif
.ndo_get_stats64 = internal_get_stats,
#ifdef HAVE_IFF_PHONY_HEADROOM
#ifndef HAVE_NET_DEVICE_OPS_WITH_EXTENDED
@@ -169,6 +182,9 @@ static void do_setup(struct net_device *netdev)
{
ether_setup(netdev);
#ifdef HAVE_NET_DEVICE_WITH_MAX_MTU
netdev->max_mtu = ETH_MAX_MTU;
#endif
netdev->netdev_ops = &internal_dev_netdev_ops;
netdev->priv_flags &= ~IFF_TX_SKB_SHARING;