@@ -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])
@@ -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
@@ -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;
+ }
+
+ 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;
+ }
- netdev->mtu = new_mtu;
+ 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;