2016-10-19 02:33:50

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next 0/6] net: use core MTU range checking everywhere

This stack of patches should get absolutely everything in the kernel
converted from doing their own MTU range checking to the core MTU range
checking.

Jarod Wilson (6):
net: use core MTU range checking in USB NIC drivers
net: use core MTU range checking in wireless drivers
net: use core MTU range checking in WAN drivers
net: use core MTU range checking in core net infra
net: use core MTU range checking in virt drivers
net: use core MTU range checking in misc drivers

CC: [email protected]

drivers/char/pcmcia/synclink_cs.c | 1 -
drivers/firewire/net.c | 12 +----
drivers/infiniband/hw/nes/nes.c | 1 -
drivers/infiniband/hw/nes/nes.h | 4 +-
drivers/infiniband/hw/nes/nes_nic.c | 10 ++--
drivers/misc/sgi-xp/xpnet.c | 21 ++------
drivers/net/geneve.c | 48 +++++++----------
drivers/net/hippi/rrunner.c | 1 -
drivers/net/hyperv/hyperv_net.h | 4 +-
drivers/net/hyperv/netvsc_drv.c | 14 ++---
drivers/net/macvlan.c | 6 ++-
drivers/net/rionet.c | 15 ++----
drivers/net/slip/slip.c | 11 ++--
drivers/net/tun.c | 20 +++----
drivers/net/usb/lan78xx.c | 8 ++-
drivers/net/usb/r8152.c | 15 ++++--
drivers/net/usb/usbnet.c | 2 -
drivers/net/virtio_net.c | 23 ++++----
drivers/net/vmxnet3/vmxnet3_drv.c | 7 +--
drivers/net/vxlan.c | 62 +++++++++++-----------
drivers/net/wan/c101.c | 1 -
drivers/net/wan/cosa.c | 1 -
drivers/net/wan/dscc4.c | 1 -
drivers/net/wan/farsync.c | 1 -
drivers/net/wan/fsl_ucc_hdlc.c | 1 -
drivers/net/wan/hdlc.c | 11 +---
drivers/net/wan/hdlc_fr.c | 3 +-
drivers/net/wan/hostess_sv11.c | 1 -
drivers/net/wan/ixp4xx_hss.c | 1 -
drivers/net/wan/lmc/lmc_main.c | 1 -
drivers/net/wan/n2.c | 1 -
drivers/net/wan/pc300too.c | 1 -
drivers/net/wan/pci200syn.c | 1 -
drivers/net/wan/sealevel.c | 1 -
drivers/net/wan/wanxl.c | 1 -
drivers/net/wireless/ath/wil6210/netdev.c | 17 +-----
drivers/net/wireless/atmel/atmel.c | 13 ++---
drivers/net/wireless/cisco/airo.c | 14 ++---
drivers/net/wireless/intel/ipw2x00/ipw2100.c | 3 +-
drivers/net/wireless/intel/ipw2x00/ipw2200.c | 8 ++-
drivers/net/wireless/intel/ipw2x00/libipw.h | 1 -
drivers/net/wireless/intel/ipw2x00/libipw_module.c | 9 ----
drivers/staging/wlan-ng/p80211netdev.c | 18 ++-----
drivers/tty/synclink.c | 1 -
drivers/tty/synclink_gt.c | 1 -
drivers/tty/synclinkmp.c | 1 -
include/linux/hdlc.h | 2 -
include/linux/hippidevice.h | 1 -
net/802/hippi.c | 14 +----
net/atm/lec.c | 11 +---
net/batman-adv/soft-interface.c | 13 +----
net/bridge/br_device.c | 9 ++--
net/openvswitch/vport-internal_dev.c | 10 ----
net/sched/sch_teql.c | 5 +-
54 files changed, 153 insertions(+), 310 deletions(-)

--
2.10.0


2016-10-19 02:34:14

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next 1/6] net: use core MTU range checking in USB NIC drivers

- Remove stale new_mtu <= 0 check in usbnet.c
- Set appropriate max_mtu for different r8152 driven variants
- Set max_mtu in lan78xx driver

CC: [email protected]
CC: Woojung Huh <[email protected]>
CC: Microchip Linux Driver Support <[email protected]>
CC: Hayes Wang <[email protected]>
CC: Oliver Neukum <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/net/usb/lan78xx.c | 8 +++-----
drivers/net/usb/r8152.c | 15 ++++++++++++---
drivers/net/usb/usbnet.c | 2 --
3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 13f033c..c4e748e 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -1980,11 +1980,6 @@ static int lan78xx_change_mtu(struct net_device *netdev, int new_mtu)
int old_rx_urb_size = dev->rx_urb_size;
int ret;

- if (new_mtu > MAX_SINGLE_PACKET_SIZE)
- return -EINVAL;
-
- if (new_mtu <= 0)
- return -EINVAL;
/* no second zero-length packet read wanted after mtu-sized packets */
if ((ll_mtu % dev->maxpacket) == 0)
return -EDOM;
@@ -3388,6 +3383,9 @@ static int lan78xx_probe(struct usb_interface *intf,
if (netdev->mtu > (dev->hard_mtu - netdev->hard_header_len))
netdev->mtu = dev->hard_mtu - netdev->hard_header_len;

+ /* MTU range: 68 - 9000 */
+ netdev->max_mtu = MAX_SINGLE_PACKET_SIZE;
+
dev->ep_blkin = (intf->cur_altsetting)->endpoint + 0;
dev->ep_blkout = (intf->cur_altsetting)->endpoint + 1;
dev->ep_intr = (intf->cur_altsetting)->endpoint + 2;
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 8d6e13c..4213c28 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -4119,9 +4119,6 @@ static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
break;
}

- if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU)
- return -EINVAL;
-
ret = usb_autopm_get_interface(tp->intf);
if (ret < 0)
return ret;
@@ -4311,6 +4308,18 @@ static int rtl8152_probe(struct usb_interface *intf,
netdev->ethtool_ops = &ops;
netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);

+ /* MTU range: 68 - 1500 or 9194 */
+ netdev->min_mtu = ETH_MIN_MTU;
+ switch (tp->version) {
+ case RTL_VER_01:
+ case RTL_VER_02:
+ netdev->max_mtu = ETH_DATA_LEN;
+ break;
+ default:
+ netdev->max_mtu = RTL8153_MAX_MTU;
+ break;
+ }
+
tp->mii.dev = netdev;
tp->mii.mdio_read = read_mii_word;
tp->mii.mdio_write = write_mii_word;
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index d5071e3..52ec271 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -384,8 +384,6 @@ int usbnet_change_mtu (struct net_device *net, int new_mtu)
int old_hard_mtu = dev->hard_mtu;
int old_rx_urb_size = dev->rx_urb_size;

- if (new_mtu <= 0)
- return -EINVAL;
// no second zero-length packet read wanted after mtu-sized packets
if ((ll_mtu % dev->maxpacket) == 0)
return -EDOM;
--
2.10.0

2016-10-19 02:34:25

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next 3/6] net: use core MTU range checking in WAN drivers

- set min/max_mtu in all hdlc drivers, remove hdlc_change_mtu
- sent max_mtu in lec driver, remove lec_change_mtu

CC: [email protected]
CC: Krzysztof Halasa <[email protected]>
CC: Krzysztof Halasa <[email protected]>
CC: Jan "Yenya" Kasprzak <[email protected]>
CC: Francois Romieu <[email protected]>
CC: Kevin Curtis <[email protected]>
CC: Zhao Qiang <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/char/pcmcia/synclink_cs.c | 1 -
drivers/net/wan/c101.c | 1 -
drivers/net/wan/cosa.c | 1 -
drivers/net/wan/dscc4.c | 1 -
drivers/net/wan/farsync.c | 1 -
drivers/net/wan/fsl_ucc_hdlc.c | 1 -
drivers/net/wan/hdlc.c | 11 ++---------
drivers/net/wan/hdlc_fr.c | 3 ++-
drivers/net/wan/hostess_sv11.c | 1 -
drivers/net/wan/ixp4xx_hss.c | 1 -
drivers/net/wan/lmc/lmc_main.c | 1 -
drivers/net/wan/n2.c | 1 -
drivers/net/wan/pc300too.c | 1 -
drivers/net/wan/pci200syn.c | 1 -
drivers/net/wan/sealevel.c | 1 -
drivers/net/wan/wanxl.c | 1 -
drivers/tty/synclink.c | 1 -
drivers/tty/synclink_gt.c | 1 -
drivers/tty/synclinkmp.c | 1 -
include/linux/hdlc.h | 2 --
net/atm/lec.c | 11 +----------
21 files changed, 5 insertions(+), 39 deletions(-)

diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index d28922d..a7dd5f4 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -4248,7 +4248,6 @@ static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size)
static const struct net_device_ops hdlcdev_ops = {
.ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlcdev_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout,
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index 09a5075..2371e07 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -302,7 +302,6 @@ static void c101_destroy_card(card_t *card)
static const struct net_device_ops c101_ops = {
.ndo_open = c101_open,
.ndo_stop = c101_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = c101_ioctl,
};
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index b87fe0a..087eb26 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -432,7 +432,6 @@ module_exit(cosa_exit);
static const struct net_device_ops cosa_ops = {
.ndo_open = cosa_net_open,
.ndo_stop = cosa_net_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = cosa_net_ioctl,
.ndo_tx_timeout = cosa_net_timeout,
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 6292259..7351e54 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -887,7 +887,6 @@ static inline int dscc4_set_quartz(struct dscc4_dev_priv *dpriv, int hz)
static const struct net_device_ops dscc4_ops = {
.ndo_open = dscc4_open,
.ndo_stop = dscc4_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = dscc4_ioctl,
.ndo_tx_timeout = dscc4_tx_timeout,
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 3c9cbf9..03696d3 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -2394,7 +2394,6 @@ fst_init_card(struct fst_card_info *card)
static const struct net_device_ops fst_ops = {
.ndo_open = fst_open,
.ndo_stop = fst_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = fst_ioctl,
.ndo_tx_timeout = fst_tx_timeout,
diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
index 6564753..e38ce4d 100644
--- a/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/drivers/net/wan/fsl_ucc_hdlc.c
@@ -992,7 +992,6 @@ static const struct dev_pm_ops uhdlc_pm_ops = {
static const struct net_device_ops uhdlc_ops = {
.ndo_open = uhdlc_open,
.ndo_stop = uhdlc_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = uhdlc_ioctl,
};
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index 9bd4aa8..7221a53 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -46,14 +46,6 @@ static const char* version = "HDLC support module revision 1.22";

static struct hdlc_proto *first_proto;

-int hdlc_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *p, struct net_device *orig_dev)
{
@@ -237,6 +229,8 @@ static void hdlc_setup_dev(struct net_device *dev)
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
dev->priv_flags = IFF_WAN_HDLC;
dev->mtu = HDLC_MAX_MTU;
+ dev->min_mtu = 68;
+ dev->max_mtu = HDLC_MAX_MTU;
dev->type = ARPHRD_RAWHDLC;
dev->hard_header_len = 16;
dev->addr_len = 0;
@@ -353,7 +347,6 @@ MODULE_AUTHOR("Krzysztof Halasa <[email protected]>");
MODULE_DESCRIPTION("HDLC support module");
MODULE_LICENSE("GPL v2");

-EXPORT_SYMBOL(hdlc_change_mtu);
EXPORT_SYMBOL(hdlc_start_xmit);
EXPORT_SYMBOL(hdlc_open);
EXPORT_SYMBOL(hdlc_close);
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index b6e0cfb..eb91528 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1053,7 +1053,6 @@ static void pvc_setup(struct net_device *dev)
static const struct net_device_ops pvc_ops = {
.ndo_open = pvc_open,
.ndo_stop = pvc_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = pvc_xmit,
.ndo_do_ioctl = pvc_ioctl,
};
@@ -1096,6 +1095,8 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
}
dev->netdev_ops = &pvc_ops;
dev->mtu = HDLC_MAX_MTU;
+ dev->min_mtu = 68;
+ dev->max_mtu = HDLC_MAX_MTU;
dev->priv_flags |= IFF_NO_QUEUE;
dev->ml_priv = pvc;

diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index 3d74166..dd6bb33 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -180,7 +180,6 @@ static int hostess_attach(struct net_device *dev, unsigned short encoding,
static const struct net_device_ops hostess_ops = {
.ndo_open = hostess_open,
.ndo_stop = hostess_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hostess_ioctl,
};
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index e7bbdb7..6a505c2 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -1321,7 +1321,6 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static const struct net_device_ops hss_hdlc_ops = {
.ndo_open = hss_hdlc_open,
.ndo_stop = hss_hdlc_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hss_hdlc_ioctl,
};
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 299140c..001b779 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -808,7 +808,6 @@ static int lmc_attach(struct net_device *dev, unsigned short encoding,
static const struct net_device_ops lmc_ops = {
.ndo_open = lmc_open,
.ndo_stop = lmc_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = lmc_ioctl,
.ndo_tx_timeout = lmc_driver_timeout,
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index 315bf09..c8f4517 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -330,7 +330,6 @@ static void n2_destroy_card(card_t *card)
static const struct net_device_ops n2_ops = {
.ndo_open = n2_open,
.ndo_stop = n2_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = n2_ioctl,
};
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c
index db36385..e1dd1ec 100644
--- a/drivers/net/wan/pc300too.c
+++ b/drivers/net/wan/pc300too.c
@@ -291,7 +291,6 @@ static void pc300_pci_remove_one(struct pci_dev *pdev)
static const struct net_device_ops pc300_ops = {
.ndo_open = pc300_open,
.ndo_stop = pc300_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = pc300_ioctl,
};
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index e845562..4e437c5 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -270,7 +270,6 @@ static void pci200_pci_remove_one(struct pci_dev *pdev)
static const struct net_device_ops pci200_ops = {
.ndo_open = pci200_open,
.ndo_stop = pci200_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = pci200_ioctl,
};
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 27860b4..fbb5aa2 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -174,7 +174,6 @@ static int sealevel_attach(struct net_device *dev, unsigned short encoding,
static const struct net_device_ops sealevel_ops = {
.ndo_open = sealevel_open,
.ndo_stop = sealevel_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = sealevel_ioctl,
};
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index a20d688..0c73175 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -551,7 +551,6 @@ static void wanxl_pci_remove_one(struct pci_dev *pdev)
static const struct net_device_ops wanxl_ops = {
.ndo_open = wanxl_open,
.ndo_stop = wanxl_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = wanxl_ioctl,
.ndo_get_stats = wanxl_get_stats,
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c
index c13e27e..415885c 100644
--- a/drivers/tty/synclink.c
+++ b/drivers/tty/synclink.c
@@ -7973,7 +7973,6 @@ static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size)
static const struct net_device_ops hdlcdev_ops = {
.ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlcdev_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout,
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index 7aca2d4..8267bcf 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -1768,7 +1768,6 @@ static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
static const struct net_device_ops hdlcdev_ops = {
.ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlcdev_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout,
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c
index dec1565..d66620f 100644
--- a/drivers/tty/synclinkmp.c
+++ b/drivers/tty/synclinkmp.c
@@ -1887,7 +1887,6 @@ static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
static const struct net_device_ops hdlcdev_ops = {
.ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlcdev_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout,
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h
index e31bcd4..97585d9 100644
--- a/include/linux/hdlc.h
+++ b/include/linux/hdlc.h
@@ -93,8 +93,6 @@ static __inline__ void debug_frame(const struct sk_buff *skb)
int hdlc_open(struct net_device *dev);
/* Must be called by hardware driver when HDLC device is being closed */
void hdlc_close(struct net_device *dev);
-/* May be used by hardware driver */
-int hdlc_change_mtu(struct net_device *dev, int new_mtu);
/* Must be pointed to by hw driver's dev->netdev_ops->ndo_start_xmit */
netdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev);

diff --git a/net/atm/lec.c b/net/atm/lec.c
index 5d26938..779b3fa 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -544,15 +544,6 @@ send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
return 0;
}

-/* shamelessly stolen from drivers/net/net_init.c */
-static int lec_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > 18190))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static void lec_set_multicast_list(struct net_device *dev)
{
/*
@@ -565,7 +556,6 @@ static const struct net_device_ops lec_netdev_ops = {
.ndo_open = lec_open,
.ndo_stop = lec_close,
.ndo_start_xmit = lec_start_xmit,
- .ndo_change_mtu = lec_change_mtu,
.ndo_tx_timeout = lec_tx_timeout,
.ndo_set_rx_mode = lec_set_multicast_list,
};
@@ -742,6 +732,7 @@ static int lecd_attach(struct atm_vcc *vcc, int arg)
if (!dev_lec[i])
return -ENOMEM;
dev_lec[i]->netdev_ops = &lec_netdev_ops;
+ dev_lec[i]->max_mtu = 18190;
snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
if (register_netdev(dev_lec[i])) {
free_netdev(dev_lec[i]);
--
2.10.0

2016-10-19 02:34:03

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next 2/6] net: use core MTU range checking in wireless drivers

- set max_mtu in wil6210 driver
- set max_mtu in atmel driver
- set min/max_mtu in cisco airo driver, remove airo_change_mtu
- set min/max_mtu in ipw2100/ipw2200 drivers, remove libipw_change_mtu
- set min/max_mtu in p80211netdev, remove wlan_change_mtu

CC: [email protected]
CC: [email protected]
CC: Maya Erez <[email protected]>
CC: Simon Kelley <[email protected]>
CC: Stanislav Yakovlev <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/net/wireless/ath/wil6210/netdev.c | 17 +----------------
drivers/net/wireless/atmel/atmel.c | 13 ++++---------
drivers/net/wireless/cisco/airo.c | 14 +++-----------
drivers/net/wireless/intel/ipw2x00/ipw2100.c | 3 ++-
drivers/net/wireless/intel/ipw2x00/ipw2200.c | 8 ++++++--
drivers/net/wireless/intel/ipw2x00/libipw.h | 1 -
drivers/net/wireless/intel/ipw2x00/libipw_module.c | 9 ---------
drivers/staging/wlan-ng/p80211netdev.c | 18 +++++-------------
8 files changed, 21 insertions(+), 62 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 61de5e9..d18372c 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -41,21 +41,6 @@ static int wil_stop(struct net_device *ndev)
return wil_down(wil);
}

-static int wil_change_mtu(struct net_device *ndev, int new_mtu)
-{
- struct wil6210_priv *wil = ndev_to_wil(ndev);
-
- if (new_mtu < 68 || new_mtu > mtu_max) {
- wil_err(wil, "invalid MTU %d\n", new_mtu);
- return -EINVAL;
- }
-
- wil_dbg_misc(wil, "change MTU %d -> %d\n", ndev->mtu, new_mtu);
- ndev->mtu = new_mtu;
-
- return 0;
-}
-
static int wil_do_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
{
struct wil6210_priv *wil = ndev_to_wil(ndev);
@@ -69,7 +54,6 @@ static const struct net_device_ops wil_netdev_ops = {
.ndo_start_xmit = wil_start_xmit,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
- .ndo_change_mtu = wil_change_mtu,
.ndo_do_ioctl = wil_do_ioctl,
};

@@ -126,6 +110,7 @@ static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
static void wil_dev_setup(struct net_device *dev)
{
ether_setup(dev);
+ dev->max_mtu = mtu_max;
dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT;
}

diff --git a/drivers/net/wireless/atmel/atmel.c b/drivers/net/wireless/atmel/atmel.c
index bf2e9a0..eb92d5a 100644
--- a/drivers/net/wireless/atmel/atmel.c
+++ b/drivers/net/wireless/atmel/atmel.c
@@ -1295,14 +1295,6 @@ static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
return &priv->wstats;
}

-static int atmel_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > 2312))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static int atmel_set_mac_address(struct net_device *dev, void *p)
{
struct sockaddr *addr = p;
@@ -1506,7 +1498,6 @@ static const struct file_operations atmel_proc_fops = {
static const struct net_device_ops atmel_netdev_ops = {
.ndo_open = atmel_open,
.ndo_stop = atmel_close,
- .ndo_change_mtu = atmel_change_mtu,
.ndo_set_mac_address = atmel_set_mac_address,
.ndo_start_xmit = start_tx,
.ndo_do_ioctl = atmel_ioctl,
@@ -1600,6 +1591,10 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
dev->irq = irq;
dev->base_addr = port;

+ /* MTU range: 68 - 2312 */
+ dev->min_mtu = 68;
+ dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN;
+
SET_NETDEV_DEV(dev, sys_dev);

if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c
index 69b826d..4b04045 100644
--- a/drivers/net/wireless/cisco/airo.c
+++ b/drivers/net/wireless/cisco/airo.c
@@ -2329,14 +2329,6 @@ static int airo_set_mac_address(struct net_device *dev, void *p)
return 0;
}

-static int airo_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > 2400))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static LIST_HEAD(airo_devices);

static void add_airo_dev(struct airo_info *ai)
@@ -2656,7 +2648,6 @@ static const struct net_device_ops airo11_netdev_ops = {
.ndo_get_stats = airo_get_stats,
.ndo_set_mac_address = airo_set_mac_address,
.ndo_do_ioctl = airo_ioctl,
- .ndo_change_mtu = airo_change_mtu,
};

static void wifi_setup(struct net_device *dev)
@@ -2668,6 +2659,8 @@ static void wifi_setup(struct net_device *dev)
dev->type = ARPHRD_IEEE80211;
dev->hard_header_len = ETH_HLEN;
dev->mtu = AIRO_DEF_MTU;
+ dev->min_mtu = 68;
+ dev->max_mtu = MIC_MSGLEN_MAX;
dev->addr_len = ETH_ALEN;
dev->tx_queue_len = 100;

@@ -2754,7 +2747,6 @@ static const struct net_device_ops airo_netdev_ops = {
.ndo_set_rx_mode = airo_set_multicast_list,
.ndo_set_mac_address = airo_set_mac_address,
.ndo_do_ioctl = airo_ioctl,
- .ndo_change_mtu = airo_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};

@@ -2766,7 +2758,6 @@ static const struct net_device_ops mpi_netdev_ops = {
.ndo_set_rx_mode = airo_set_multicast_list,
.ndo_set_mac_address = airo_set_mac_address,
.ndo_do_ioctl = airo_ioctl,
- .ndo_change_mtu = airo_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};

@@ -2822,6 +2813,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
dev->irq = irq;
dev->base_addr = port;
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+ dev->max_mtu = MIC_MSGLEN_MAX;

SET_NETDEV_DEV(dev, dmdev);

diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
index bfa542c..6417609 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
@@ -6035,7 +6035,6 @@ static const struct net_device_ops ipw2100_netdev_ops = {
.ndo_open = ipw2100_open,
.ndo_stop = ipw2100_close,
.ndo_start_xmit = libipw_xmit,
- .ndo_change_mtu = libipw_change_mtu,
.ndo_tx_timeout = ipw2100_tx_timeout,
.ndo_set_mac_address = ipw2100_set_address,
.ndo_validate_addr = eth_validate_addr,
@@ -6071,6 +6070,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
dev->wireless_data = &priv->wireless_data;
dev->watchdog_timeo = 3 * HZ;
dev->irq = 0;
+ dev->min_mtu = 68;
+ dev->max_mtu = LIBIPW_DATA_LEN;

/* NOTE: We don't use the wireless_handlers hook
* in dev as the system will start throwing WX requests
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index bfd6861..ef9af8a 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -11561,7 +11561,6 @@ static const struct net_device_ops ipw_prom_netdev_ops = {
.ndo_open = ipw_prom_open,
.ndo_stop = ipw_prom_stop,
.ndo_start_xmit = ipw_prom_hard_start_xmit,
- .ndo_change_mtu = libipw_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
};
@@ -11587,6 +11586,9 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;

+ priv->prom_net_dev->min_mtu = 68;
+ priv->prom_net_dev->max_mtu = LIBIPW_DATA_LEN;
+
priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);

@@ -11619,7 +11621,6 @@ static const struct net_device_ops ipw_netdev_ops = {
.ndo_set_rx_mode = ipw_net_set_multicast_list,
.ndo_set_mac_address = ipw_net_set_mac_address,
.ndo_start_xmit = libipw_xmit,
- .ndo_change_mtu = libipw_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};

@@ -11729,6 +11730,9 @@ static int ipw_pci_probe(struct pci_dev *pdev,
net_dev->wireless_handlers = &ipw_wx_handler_def;
net_dev->ethtool_ops = &ipw_ethtool_ops;

+ net_dev->min_mtu = 68;
+ net_dev->max_mtu = LIBIPW_DATA_LEN;
+
err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
if (err) {
IPW_ERROR("failed to create sysfs device attributes\n");
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw.h b/drivers/net/wireless/intel/ipw2x00/libipw.h
index b057161..b513551 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw.h
+++ b/drivers/net/wireless/intel/ipw2x00/libipw.h
@@ -948,7 +948,6 @@ static inline int libipw_is_cck_rate(u8 rate)
/* libipw.c */
void free_libipw(struct net_device *dev, int monitor);
struct net_device *alloc_libipw(int sizeof_priv, int monitor);
-int libipw_change_mtu(struct net_device *dev, int new_mtu);

void libipw_networks_age(struct libipw_device *ieee, unsigned long age_secs);

diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_module.c b/drivers/net/wireless/intel/ipw2x00/libipw_module.c
index 60f2874..2332075 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_module.c
@@ -118,15 +118,6 @@ static void libipw_networks_initialize(struct libipw_device *ieee)
&ieee->network_free_list);
}

-int libipw_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-EXPORT_SYMBOL(libipw_change_mtu);
-
struct net_device *alloc_libipw(int sizeof_priv, int monitor)
{
struct libipw_device *ieee;
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index 825a63a..4762d38 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -669,18 +669,6 @@ static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr)
return result;
}

-static int wlan_change_mtu(struct net_device *dev, int new_mtu)
-{
- /* 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
- and another 8 for wep. */
- if ((new_mtu < 68) || (new_mtu > (2312 - 20 - 8)))
- return -EINVAL;
-
- dev->mtu = new_mtu;
-
- return 0;
-}
-
static const struct net_device_ops p80211_netdev_ops = {
.ndo_init = p80211knetdev_init,
.ndo_open = p80211knetdev_open,
@@ -690,7 +678,6 @@ static const struct net_device_ops p80211_netdev_ops = {
.ndo_do_ioctl = p80211knetdev_do_ioctl,
.ndo_set_mac_address = p80211knetdev_set_mac_address,
.ndo_tx_timeout = p80211knetdev_tx_timeout,
- .ndo_change_mtu = wlan_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};

@@ -756,6 +743,11 @@ int wlan_setup(struct wlandevice *wlandev, struct device *physdev)
wdev->wiphy = wiphy;
wdev->iftype = NL80211_IFTYPE_STATION;
netdev->ieee80211_ptr = wdev;
+ netdev->min_mtu = 68;
+ /* 2312 is max 802.11 payload, 20 is overhead,
+ * (ether + llc + snap) and another 8 for wep.
+ */
+ netdev->max_mtu = (2312 - 20 - 8);

netif_stop_queue(netdev);
netif_carrier_off(netdev);
--
2.10.0

2016-10-19 02:34:52

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next 6/6] net: use core MTU range checking in misc drivers

firewire-net:
- set min/max_mtu
- remove fwnet_change_mtu

nes:
- set max_mtu
- clean up nes_netdev_change_mtu

xpnet:
- set min/max_mtu
- remove xpnet_dev_change_mtu

hippi:
- set min/max_mtu
- remove hippi_change_mtu

batman-adv:
- set max_mtu
- remove batadv_interface_change_mtu
- initialization is a little async, not 100% certain that max_mtu is set
in the optimal place, don't have hardware to test with

rionet:
- set min/max_mtu
- remove rionet_change_mtu

slip:
- set min/max_mtu
- streamline sl_change_mtu

CC: [email protected]
CC: Stefan Richter <[email protected]>
CC: Faisal Latif <[email protected]>
CC: [email protected]
CC: Cliff Whickman <[email protected]>
CC: Robin Holt <[email protected]>
CC: Jes Sorensen <[email protected]>
CC: Marek Lindner <[email protected]>
CC: Simon Wunderlich <[email protected]>
CC: Antonio Quartulli <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/firewire/net.c | 12 ++----------
drivers/infiniband/hw/nes/nes.c | 1 -
drivers/infiniband/hw/nes/nes.h | 4 ++--
drivers/infiniband/hw/nes/nes_nic.c | 10 +++-------
drivers/misc/sgi-xp/xpnet.c | 21 ++++-----------------
drivers/net/hippi/rrunner.c | 1 -
drivers/net/rionet.c | 15 +++------------
drivers/net/slip/slip.c | 11 +++++------
include/linux/hippidevice.h | 1 -
net/802/hippi.c | 14 ++------------
net/batman-adv/soft-interface.c | 13 +------------
11 files changed, 22 insertions(+), 81 deletions(-)

diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 309311b..b5f125c 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -1349,15 +1349,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
return NETDEV_TX_OK;
}

-static int fwnet_change_mtu(struct net_device *net, int new_mtu)
-{
- if (new_mtu < 68)
- return -EINVAL;
-
- net->mtu = new_mtu;
- return 0;
-}
-
static const struct ethtool_ops fwnet_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
@@ -1366,7 +1357,6 @@ static const struct net_device_ops fwnet_netdev_ops = {
.ndo_open = fwnet_open,
.ndo_stop = fwnet_stop,
.ndo_start_xmit = fwnet_tx,
- .ndo_change_mtu = fwnet_change_mtu,
};

static void fwnet_init_dev(struct net_device *net)
@@ -1481,6 +1471,8 @@ static int fwnet_probe(struct fw_unit *unit,
max_mtu = (1 << (card->max_receive + 1))
- sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
net->mtu = min(1500U, max_mtu);
+ net->min_mtu = ETH_MIN_MTU;
+ net->max_mtu = net->mtu;

/* Set our hardware address while we're at it */
ha = (union fwnet_hwaddr *)net->dev_addr;
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 35cbb17..2baa45a 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -65,7 +65,6 @@ MODULE_DESCRIPTION("NetEffect RNIC Low-level iWARP Driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_VERSION);

-int max_mtu = 9000;
int interrupt_mod_interval = 0;

/* Interoperability */
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index e7430c9..85acd08 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -83,6 +83,8 @@
#define NES_FIRST_QPN 64
#define NES_SW_CONTEXT_ALIGN 1024

+#define NES_MAX_MTU 9000
+
#define NES_NIC_MAX_NICS 16
#define NES_MAX_ARP_TABLE_SIZE 4096

@@ -169,8 +171,6 @@ do { \
#include "nes_cm.h"
#include "nes_mgt.h"

-extern int max_mtu;
-#define max_frame_len (max_mtu+ETH_HLEN)
extern int interrupt_mod_interval;
extern int nes_if_count;
extern int mpa_version;
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 2b27d13..7f8597d 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -981,20 +981,16 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
{
struct nes_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev;
- int ret = 0;
u8 jumbomode = 0;
u32 nic_active;
u32 nic_active_bit;
u32 uc_all_active;
u32 mc_all_active;

- if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu))
- return -EINVAL;
-
netdev->mtu = new_mtu;
nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN;

- if (netdev->mtu > 1500) {
+ if (netdev->mtu > ETH_DATA_LEN) {
jumbomode=1;
}
nes_nic_init_timer_defaults(nesdev, jumbomode);
@@ -1020,7 +1016,7 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
}

- return ret;
+ return 0;
}


@@ -1658,7 +1654,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,

netdev->watchdog_timeo = NES_TX_TIMEOUT;
netdev->irq = nesdev->pcidev->irq;
- netdev->mtu = ETH_DATA_LEN;
+ netdev->max_mtu = NES_MAX_MTU;
netdev->hard_header_len = ETH_HLEN;
netdev->addr_len = ETH_ALEN;
netdev->type = ARPHRD_ETHER;
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 557f978..0c26eaf 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -118,6 +118,8 @@ static DEFINE_SPINLOCK(xpnet_broadcast_lock);
* now, the default is 64KB.
*/
#define XPNET_MAX_MTU (0x800000UL - L1_CACHE_BYTES)
+/* 68 comes from min TCP+IP+MAC header */
+#define XPNET_MIN_MTU 68
/* 32KB has been determined to be the ideal */
#define XPNET_DEF_MTU (0x8000UL)

@@ -330,22 +332,6 @@ xpnet_dev_stop(struct net_device *dev)
return 0;
}

-static int
-xpnet_dev_change_mtu(struct net_device *dev, int new_mtu)
-{
- /* 68 comes from min TCP+IP+MAC header */
- if ((new_mtu < 68) || (new_mtu > XPNET_MAX_MTU)) {
- dev_err(xpnet, "ifconfig %s mtu %d failed; value must be "
- "between 68 and %ld\n", dev->name, new_mtu,
- XPNET_MAX_MTU);
- return -EINVAL;
- }
-
- dev->mtu = new_mtu;
- dev_dbg(xpnet, "ifconfig %s mtu set to %d\n", dev->name, new_mtu);
- return 0;
-}
-
/*
* Notification that the other end has received the message and
* DMA'd the skb information. At this point, they are done with
@@ -519,7 +505,6 @@ static const struct net_device_ops xpnet_netdev_ops = {
.ndo_open = xpnet_dev_open,
.ndo_stop = xpnet_dev_stop,
.ndo_start_xmit = xpnet_dev_hard_start_xmit,
- .ndo_change_mtu = xpnet_dev_change_mtu,
.ndo_tx_timeout = xpnet_dev_tx_timeout,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
@@ -555,6 +540,8 @@ xpnet_init(void)

xpnet_device->netdev_ops = &xpnet_netdev_ops;
xpnet_device->mtu = XPNET_DEF_MTU;
+ xpnet_device->min_mtu = XPNET_MIN_MTU;
+ xpnet_device->max_mtu = XPNET_MAX_MTU;

/*
* Multicast assumes the LSB of the first octet is set for multicast
diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c
index 95c0b45..f5a9728 100644
--- a/drivers/net/hippi/rrunner.c
+++ b/drivers/net/hippi/rrunner.c
@@ -68,7 +68,6 @@ static const struct net_device_ops rr_netdev_ops = {
.ndo_stop = rr_close,
.ndo_do_ioctl = rr_ioctl,
.ndo_start_xmit = rr_start_xmit,
- .ndo_change_mtu = hippi_change_mtu,
.ndo_set_mac_address = hippi_mac_addr,
};

diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index a31f461..300bb14 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -466,17 +466,6 @@ static void rionet_set_msglevel(struct net_device *ndev, u32 value)
rnet->msg_enable = value;
}

-static int rionet_change_mtu(struct net_device *ndev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > RIONET_MAX_MTU)) {
- printk(KERN_ERR "%s: Invalid MTU size %d\n",
- ndev->name, new_mtu);
- return -EINVAL;
- }
- ndev->mtu = new_mtu;
- return 0;
-}
-
static const struct ethtool_ops rionet_ethtool_ops = {
.get_drvinfo = rionet_get_drvinfo,
.get_msglevel = rionet_get_msglevel,
@@ -488,7 +477,6 @@ static const struct net_device_ops rionet_netdev_ops = {
.ndo_open = rionet_open,
.ndo_stop = rionet_close,
.ndo_start_xmit = rionet_start_xmit,
- .ndo_change_mtu = rionet_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
};
@@ -525,6 +513,9 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)

ndev->netdev_ops = &rionet_netdev_ops;
ndev->mtu = RIONET_MAX_MTU;
+ /* MTU range: 68 - 4082 */
+ ndev->min_mtu = ETH_MIN_MTU;
+ ndev->max_mtu = RIONET_MAX_MTU;
ndev->features = NETIF_F_LLTX;
SET_NETDEV_DEV(ndev, &mport->dev);
ndev->ethtool_ops = &rionet_ethtool_ops;
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index 9ed6d1c..7e933d8 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -561,12 +561,7 @@ static int sl_change_mtu(struct net_device *dev, int new_mtu)
{
struct slip *sl = netdev_priv(dev);

- if (new_mtu < 68 || new_mtu > 65534)
- return -EINVAL;
-
- if (new_mtu != dev->mtu)
- return sl_realloc_bufs(sl, new_mtu);
- return 0;
+ return sl_realloc_bufs(sl, new_mtu);
}

/* Netdevice get statistics request */
@@ -663,6 +658,10 @@ static void sl_setup(struct net_device *dev)
dev->addr_len = 0;
dev->tx_queue_len = 10;

+ /* MTU range: 68 - 65534 */
+ dev->min_mtu = 68;
+ dev->max_mtu = 65534;
+
/* New-style flags. */
dev->flags = IFF_NOARP|IFF_POINTOPOINT|IFF_MULTICAST;
}
diff --git a/include/linux/hippidevice.h b/include/linux/hippidevice.h
index 8ec23fb..402f99e 100644
--- a/include/linux/hippidevice.h
+++ b/include/linux/hippidevice.h
@@ -32,7 +32,6 @@ struct hippi_cb {
};

__be16 hippi_type_trans(struct sk_buff *skb, struct net_device *dev);
-int hippi_change_mtu(struct net_device *dev, int new_mtu);
int hippi_mac_addr(struct net_device *dev, void *p);
int hippi_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p);
struct net_device *alloc_hippi_dev(int sizeof_priv);
diff --git a/net/802/hippi.c b/net/802/hippi.c
index ade1a52..5e4427b 100644
--- a/net/802/hippi.c
+++ b/net/802/hippi.c
@@ -116,18 +116,6 @@ __be16 hippi_type_trans(struct sk_buff *skb, struct net_device *dev)

EXPORT_SYMBOL(hippi_type_trans);

-int hippi_change_mtu(struct net_device *dev, int new_mtu)
-{
- /*
- * HIPPI's got these nice large MTUs.
- */
- if ((new_mtu < 68) || (new_mtu > 65280))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-EXPORT_SYMBOL(hippi_change_mtu);
-
/*
* For HIPPI we will actually use the lower 4 bytes of the hardware
* address as the I-FIELD rather than the actual hardware address.
@@ -174,6 +162,8 @@ static void hippi_setup(struct net_device *dev)
dev->type = ARPHRD_HIPPI;
dev->hard_header_len = HIPPI_HLEN;
dev->mtu = 65280;
+ dev->min_mtu = 68;
+ dev->max_mtu = 65280;
dev->addr_len = HIPPI_ALEN;
dev->tx_queue_len = 25 /* 5 */;
memset(dev->broadcast, 0xFF, HIPPI_ALEN);
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 49e16b6..112679d 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -158,17 +158,6 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
return 0;
}

-static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu)
-{
- /* check ranges */
- if ((new_mtu < 68) || (new_mtu > batadv_hardif_min_mtu(dev)))
- return -EINVAL;
-
- dev->mtu = new_mtu;
-
- return 0;
-}
-
/**
* batadv_interface_set_rx_mode - set the rx mode of a device
* @dev: registered network device to modify
@@ -920,7 +909,6 @@ static const struct net_device_ops batadv_netdev_ops = {
.ndo_vlan_rx_add_vid = batadv_interface_add_vid,
.ndo_vlan_rx_kill_vid = batadv_interface_kill_vid,
.ndo_set_mac_address = batadv_interface_set_mac_addr,
- .ndo_change_mtu = batadv_interface_change_mtu,
.ndo_set_rx_mode = batadv_interface_set_rx_mode,
.ndo_start_xmit = batadv_interface_tx,
.ndo_validate_addr = eth_validate_addr,
@@ -987,6 +975,7 @@ struct net_device *batadv_softif_create(struct net *net, const char *name)
dev_net_set(soft_iface, net);

soft_iface->rtnl_link_ops = &batadv_link_ops;
+ soft_iface->max_mtu = batadv_hardif_min_mtu(soft_iface);

ret = register_netdevice(soft_iface);
if (ret < 0) {
--
2.10.0

2016-10-19 02:35:14

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next 5/6] net: use core MTU range checking in virt drivers

hyperv_net:
- set min/max_mtu

virtio_net:
- set min/max_mtu
- remove virtnet_change_mtu

vmxnet3:
- set min/max_mtu

CC: [email protected]
CC: [email protected]
CC: "K. Y. Srinivasan" <[email protected]>
CC: Haiyang Zhang <[email protected]>
CC: "Michael S. Tsirkin" <[email protected]>
CC: Shrikrishna Khare <[email protected]>
CC: "VMware, Inc." <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/net/hyperv/hyperv_net.h | 4 ++--
drivers/net/hyperv/netvsc_drv.c | 14 +++++++-------
drivers/net/virtio_net.c | 23 ++++++++++-------------
drivers/net/vmxnet3/vmxnet3_drv.c | 7 ++++---
4 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index f4fbcb5..3958ada 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -606,8 +606,8 @@ struct nvsp_message {
} __packed;


-#define NETVSC_MTU 65536
-#define NETVSC_MTU_MIN 68
+#define NETVSC_MTU 65535
+#define NETVSC_MTU_MIN ETH_MIN_MTU

#define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */
#define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index f0919bd..3dc9679 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -872,19 +872,12 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
struct netvsc_device *nvdev = ndevctx->nvdev;
struct hv_device *hdev = ndevctx->device_ctx;
struct netvsc_device_info device_info;
- int limit = ETH_DATA_LEN;
u32 num_chn;
int ret = 0;

if (ndevctx->start_remove || !nvdev || nvdev->destroy)
return -ENODEV;

- if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
- limit = NETVSC_MTU - ETH_HLEN;
-
- if (mtu < NETVSC_MTU_MIN || mtu > limit)
- return -EINVAL;
-
ret = netvsc_close(ndev);
if (ret)
goto out;
@@ -1343,6 +1336,13 @@ static int netvsc_probe(struct hv_device *dev,

netif_carrier_off(net);

+ /* MTU range: 68 - 1500 or 65521 */
+ net->min_mtu = NETVSC_MTU_MIN;
+ if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
+ net->max_mtu = NETVSC_MTU - ETH_HLEN;
+ else
+ net->max_mtu = ETH_DATA_LEN;
+
netvsc_init_settings(net);

net_device_ctx = netdev_priv(net);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fad84f3..4885a42 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1419,17 +1419,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
.set_settings = virtnet_set_settings,
};

-#define MIN_MTU 68
-#define MAX_MTU 65535
-
-static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
-{
- if (new_mtu < MIN_MTU || new_mtu > MAX_MTU)
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static const struct net_device_ops virtnet_netdev = {
.ndo_open = virtnet_open,
.ndo_stop = virtnet_close,
@@ -1437,7 +1426,6 @@ static const struct net_device_ops virtnet_netdev = {
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = virtnet_set_mac_address,
.ndo_set_rx_mode = virtnet_set_rx_mode,
- .ndo_change_mtu = virtnet_change_mtu,
.ndo_get_stats64 = virtnet_stats,
.ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
@@ -1748,6 +1736,9 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
return true;
}

+#define MIN_MTU ETH_MIN_MTU
+#define MAX_MTU 65535
+
static int virtnet_probe(struct virtio_device *vdev)
{
int i, err;
@@ -1821,6 +1812,10 @@ static int virtnet_probe(struct virtio_device *vdev)

dev->vlan_features = dev->features;

+ /* MTU range: 68 - 65535 */
+ dev->min_mtu = MIN_MTU;
+ dev->max_mtu = MAX_MTU;
+
/* Configuration may specify what MAC to use. Otherwise random. */
if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
virtio_cread_bytes(vdev,
@@ -1875,8 +1870,10 @@ static int virtnet_probe(struct virtio_device *vdev)
mtu = virtio_cread16(vdev,
offsetof(struct virtio_net_config,
mtu));
- if (virtnet_change_mtu(dev, mtu))
+ if (mtu >= dev->min_mtu && mtu <= dev->max_mtu) {
+ dev->mtu = mtu;
__virtio_clear_bit(vdev, VIRTIO_NET_F_MTU);
+ }
}

if (vi->any_header_sg)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index b5554f2..0c36de1 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -2969,9 +2969,6 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
int err = 0;

- if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU)
- return -EINVAL;
-
netdev->mtu = new_mtu;

/*
@@ -3428,6 +3425,10 @@ vmxnet3_probe_device(struct pci_dev *pdev,
vmxnet3_set_ethtool_ops(netdev);
netdev->watchdog_timeo = 5 * HZ;

+ /* MTU range: 60 - 9000 */
+ netdev->min_mtu = VMXNET3_MIN_MTU;
+ netdev->max_mtu = VMXNET3_MAX_MTU;
+
INIT_WORK(&adapter->work, vmxnet3_reset_work);
set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);

--
2.10.0

2016-10-19 02:35:26

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next 4/6] net: use core MTU range checking in core net infra

geneve:
- Merge __geneve_change_mtu back into geneve_change_mtu, set max_mtu
- This one isn't quite as straight-forward as others, could use some
closer inspection and testing

macvlan:
- set min/max_mtu

tun:
- set min/max_mtu, remove tun_net_change_mtu

vxlan:
- Merge __vxlan_change_mtu back into vxlan_change_mtu, set min/max_mtu
- This one is also not as straight-forward and could use closer inspection
and testing from vxlan folks

bridge:
- set max_mtu via br_min_mtu()

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

sch_teql:
- set min/max_mtu (note: max_mtu previously unchecked, used max of 65535)

CC: [email protected]
CC: Nicolas Dichtel <[email protected]>
CC: Hannes Frederic Sowa <[email protected]>
CC: Tom Herbert <[email protected]>
CC: Daniel Borkmann <[email protected]>
CC: Alexander Duyck <[email protected]>
CC: Paolo Abeni <[email protected]>
CC: Jiri Benc <[email protected]>
CC: WANG Cong <[email protected]>
CC: Roopa Prabhu <[email protected]>
CC: Pravin B Shelar <[email protected]>
CC: Sabrina Dubroca <[email protected]>
CC: Patrick McHardy <[email protected]>
CC: Stephen Hemminger <[email protected]>
CC: Pravin Shelar <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/net/geneve.c | 48 +++++++++++-----------------
drivers/net/macvlan.c | 6 +++-
drivers/net/tun.c | 20 ++++--------
drivers/net/vxlan.c | 62 ++++++++++++++++++------------------
net/bridge/br_device.c | 9 +++---
net/openvswitch/vport-internal_dev.c | 10 ------
net/sched/sch_teql.c | 5 ++-
7 files changed, 67 insertions(+), 93 deletions(-)

diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 3c20e87..752bcaa 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1034,39 +1034,18 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
return geneve_xmit_skb(skb, dev, info);
}

-static int __geneve_change_mtu(struct net_device *dev, int new_mtu, bool strict)
+static int geneve_change_mtu(struct net_device *dev, int new_mtu)
{
- struct geneve_dev *geneve = netdev_priv(dev);
- /* The max_mtu calculation does not take account of GENEVE
- * options, to avoid excluding potentially valid
- * configurations.
+ /* Only possible if called internally, ndo_change_mtu path's new_mtu
+ * is guaranteed to be between dev->min_mtu and dev->max_mtu.
*/
- int max_mtu = IP_MAX_MTU - GENEVE_BASE_HLEN - dev->hard_header_len;
-
- if (geneve->remote.sa.sa_family == AF_INET6)
- max_mtu -= sizeof(struct ipv6hdr);
- else
- max_mtu -= sizeof(struct iphdr);
-
- if (new_mtu < 68)
- return -EINVAL;
-
- if (new_mtu > max_mtu) {
- if (strict)
- return -EINVAL;
-
- new_mtu = max_mtu;
- }
+ if (new_mtu > dev->max_mtu)
+ new_mtu = dev->max_mtu;

dev->mtu = new_mtu;
return 0;
}

-static int geneve_change_mtu(struct net_device *dev, int new_mtu)
-{
- return __geneve_change_mtu(dev, new_mtu, true);
-}
-
static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
{
struct ip_tunnel_info *info = skb_tunnel_info(skb);
@@ -1170,6 +1149,14 @@ static void geneve_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;

+ /* MTU range: 68 - (something less than 65535) */
+ dev->min_mtu = ETH_MIN_MTU;
+ /* The max_mtu calculation does not take account of GENEVE
+ * options, to avoid excluding potentially valid
+ * configurations. This will be further reduced by IPvX hdr size.
+ */
+ dev->max_mtu = IP_MAX_MTU - GENEVE_BASE_HLEN - dev->hard_header_len;
+
netif_keep_dst(dev);
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
@@ -1285,10 +1272,13 @@ static int geneve_configure(struct net *net, struct net_device *dev,

/* make enough headroom for basic scenario */
encap_len = GENEVE_BASE_HLEN + ETH_HLEN;
- if (remote->sa.sa_family == AF_INET)
+ if (remote->sa.sa_family == AF_INET) {
encap_len += sizeof(struct iphdr);
- else
+ dev->max_mtu -= sizeof(struct iphdr);
+ } else {
encap_len += sizeof(struct ipv6hdr);
+ dev->max_mtu -= sizeof(struct ipv6hdr);
+ }
dev->needed_headroom = encap_len + ETH_HLEN;

if (metadata) {
@@ -1488,7 +1478,7 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
/* openvswitch users expect packet sizes to be unrestricted,
* so set the largest MTU we can.
*/
- err = __geneve_change_mtu(dev, IP_MAX_MTU, false);
+ err = geneve_change_mtu(dev, IP_MAX_MTU);
if (err)
goto err;

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 3234fcd..0e0cb2d 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -777,7 +777,7 @@ static int macvlan_change_mtu(struct net_device *dev, int new_mtu)
{
struct macvlan_dev *vlan = netdev_priv(dev);

- if (new_mtu < 68 || vlan->lowerdev->mtu < new_mtu)
+ if (vlan->lowerdev->mtu < new_mtu)
return -EINVAL;
dev->mtu = new_mtu;
return 0;
@@ -1297,6 +1297,10 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
else if (dev->mtu > lowerdev->mtu)
return -EINVAL;

+ /* MTU range: 68 - lowerdev->max_mtu */
+ dev->min_mtu = ETH_MIN_MTU;
+ dev->max_mtu = lowerdev->max_mtu;
+
if (!tb[IFLA_ADDRESS])
eth_hw_addr_random(dev);

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 8093e39..9328568 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -925,18 +925,6 @@ static void tun_net_mclist(struct net_device *dev)
*/
}

-#define MIN_MTU 68
-#define MAX_MTU 65535
-
-static int
-tun_net_change_mtu(struct net_device *dev, int new_mtu)
-{
- if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU)
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static netdev_features_t tun_net_fix_features(struct net_device *dev,
netdev_features_t features)
{
@@ -1014,7 +1002,6 @@ static const struct net_device_ops tun_netdev_ops = {
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
- .ndo_change_mtu = tun_net_change_mtu,
.ndo_fix_features = tun_net_fix_features,
.ndo_select_queue = tun_select_queue,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1029,7 +1016,6 @@ static const struct net_device_ops tap_netdev_ops = {
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
- .ndo_change_mtu = tun_net_change_mtu,
.ndo_fix_features = tun_net_fix_features,
.ndo_set_rx_mode = tun_net_mclist,
.ndo_set_mac_address = eth_mac_addr,
@@ -1062,6 +1048,9 @@ static void tun_flow_uninit(struct tun_struct *tun)
tun_flow_flush(tun);
}

+#define MIN_MTU 68
+#define MAX_MTU 65535
+
/* Initialize net device. */
static void tun_net_init(struct net_device *dev)
{
@@ -1092,6 +1081,9 @@ static void tun_net_init(struct net_device *dev)

break;
}
+
+ dev->min_mtu = MIN_MTU;
+ dev->max_mtu = MAX_MTU - dev->hard_header_len;
}

/* Character device part */
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index e7d1668..98207ae 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2367,43 +2367,31 @@ 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)
+static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
{
- int max_mtu = IP_MAX_MTU;
-
- if (lowerdev)
- max_mtu = lowerdev->mtu;
+ struct vxlan_dev *vxlan = netdev_priv(dev);
+ struct vxlan_rdst *dst = &vxlan->default_dst;
+ struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
+ dst->remote_ifindex);
+ bool use_ipv6 = false;

if (dst->remote_ip.sa.sa_family == AF_INET6)
- max_mtu -= VXLAN6_HEADROOM;
- else
- max_mtu -= VXLAN_HEADROOM;
-
- if (new_mtu < 68)
- return -EINVAL;
+ use_ipv6 = true;

- if (new_mtu > max_mtu) {
- if (strict)
+ /* We re-check this, because users *could* alter the mtu of the
+ * lower device after we've initialized dev->max_mtu.
+ */
+ if (lowerdev) {
+ dev->max_mtu = lowerdev->mtu -
+ (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
+ if (new_mtu > dev->max_mtu)
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 = __dev_get_by_index(vxlan->net,
- dst->remote_ifindex);
- return __vxlan_change_mtu(dev, lowerdev, dst, new_mtu, true);
-}
-
static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
@@ -2795,6 +2783,10 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
vxlan_ether_setup(dev);
}

+ /* MTU range: 68 - 65535 */
+ dev->min_mtu = 68;
+ dev->max_mtu = IP_MAX_MTU;
+
vxlan->net = src_net;

dst->remote_vni = conf->vni;
@@ -2837,8 +2829,11 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
}
#endif

- if (!conf->mtu)
- dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
+ if (!conf->mtu) {
+ dev->mtu = lowerdev->mtu -
+ (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
+ dev->max_mtu = dev->mtu;
+ }

needed_headroom = lowerdev->hard_header_len;
} else if (vxlan_addr_multicast(&dst->remote_ip)) {
@@ -2847,9 +2842,14 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
}

if (conf->mtu) {
- err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false);
- if (err)
- return err;
+ if (lowerdev)
+ dev->max_mtu = lowerdev->mtu;
+ dev->max_mtu -= (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
+
+ dev->mtu = conf->mtu;
+
+ if (conf->mtu > dev->max_mtu)
+ dev->mtu = dev->max_mtu;
}

if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 89a687f..81fc79a 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -184,17 +184,15 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev,

static int br_change_mtu(struct net_device *dev, int new_mtu)
{
+#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
struct net_bridge *br = netdev_priv(dev);
- if (new_mtu < 68 || new_mtu > br_min_mtu(br))
- return -EINVAL;
-
- dev->mtu = new_mtu;

-#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
/* remember the MTU in the rtable for PMTU */
dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
#endif

+ dev->mtu = new_mtu;
+
return 0;
}

@@ -390,6 +388,7 @@ void br_dev_setup(struct net_device *dev)
dev->hw_features = COMMON_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX;
dev->vlan_features = COMMON_FEATURES;
+ dev->max_mtu = br_min_mtu(br);

br->dev = dev;
spin_lock_init(&br->lock);
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index e7da290..d5d6cae 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -89,15 +89,6 @@ 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)
-{
- if (new_mtu < 68)
- return -EINVAL;
-
- netdev->mtu = new_mtu;
- return 0;
-}
-
static void internal_dev_destructor(struct net_device *dev)
{
struct vport *vport = ovs_internal_dev_get_vport(dev);
@@ -148,7 +139,6 @@ 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,
- .ndo_change_mtu = internal_dev_change_mtu,
.ndo_get_stats64 = internal_get_stats,
.ndo_set_rx_headroom = internal_set_rx_headroom,
};
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 2cd9b44..b019636 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -418,9 +418,6 @@ static int teql_master_mtu(struct net_device *dev, int new_mtu)
struct teql_master *m = netdev_priv(dev);
struct Qdisc *q;

- if (new_mtu < 68)
- return -EINVAL;
-
q = m->slaves;
if (q) {
do {
@@ -460,6 +457,8 @@ static __init void teql_master_setup(struct net_device *dev)
dev->netdev_ops = &teql_netdev_ops;
dev->type = ARPHRD_VOID;
dev->mtu = 1500;
+ dev->min_mtu = 68;
+ dev->max_mtu = 65535;
dev->tx_queue_len = 100;
dev->flags = IFF_NOARP;
dev->hard_header_len = LL_MAX_HEADER;
--
2.10.0

2016-10-19 14:12:39

by Sabrina Dubroca

[permalink] [raw]
Subject: Re: [PATCH net-next 4/6] net: use core MTU range checking in core net infra

2016-10-18, 22:33:31 -0400, Jarod Wilson wrote:
> geneve:
> - Merge __geneve_change_mtu back into geneve_change_mtu, set max_mtu
> - This one isn't quite as straight-forward as others, could use some
> closer inspection and testing
>
> macvlan:
> - set min/max_mtu
>
> tun:
> - set min/max_mtu, remove tun_net_change_mtu
>
> vxlan:
> - Merge __vxlan_change_mtu back into vxlan_change_mtu, set min/max_mtu
> - This one is also not as straight-forward and could use closer inspection
> and testing from vxlan folks
>
> bridge:
> - set max_mtu via br_min_mtu()
>
> 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
>
> sch_teql:
> - set min/max_mtu (note: max_mtu previously unchecked, used max of 65535)

Nothing for other virtual netdevices? (dummy, veth, bond, etc) Their
MTU is limited to 1500 now. Also missing macsec and ip_gre, probably
others that are using ether_setup.


[...]
> diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
> index 89a687f..81fc79a 100644
> --- a/net/bridge/br_device.c
> +++ b/net/bridge/br_device.c
> @@ -184,17 +184,15 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev,
>
> static int br_change_mtu(struct net_device *dev, int new_mtu)
> {
> +#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
> struct net_bridge *br = netdev_priv(dev);
> - if (new_mtu < 68 || new_mtu > br_min_mtu(br))
> - return -EINVAL;
> -
> - dev->mtu = new_mtu;
>
> -#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
> /* remember the MTU in the rtable for PMTU */
> dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
> #endif
>
> + dev->mtu = new_mtu;
> +
> return 0;
> }
>
> @@ -390,6 +388,7 @@ void br_dev_setup(struct net_device *dev)
> dev->hw_features = COMMON_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
> NETIF_F_HW_VLAN_STAG_TX;
> dev->vlan_features = COMMON_FEATURES;
> + dev->max_mtu = br_min_mtu(br);

br_min_mtu uses br->port_list, which is only initialized a few lines
later (right after the spin_lock_init() at the end of the context of
this diff).

Besides, I don't think this works: br_min_mtu(br) changes when you add
and remove ports, or when you change the MTU of an enslaved
device. But this makes the max MTU for the bridge fixed (to 1500).

>
> br->dev = dev;
> spin_lock_init(&br->lock);

> diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
> index e7da290..d5d6cae 100644
> --- a/net/openvswitch/vport-internal_dev.c
> +++ b/net/openvswitch/vport-internal_dev.c
> @@ -89,15 +89,6 @@ 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)
> -{
> - if (new_mtu < 68)
> - return -EINVAL;
> -
> - netdev->mtu = new_mtu;
> - return 0;
> -}
> -
> static void internal_dev_destructor(struct net_device *dev)
> {
> struct vport *vport = ovs_internal_dev_get_vport(dev);
> @@ -148,7 +139,6 @@ 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,
> - .ndo_change_mtu = internal_dev_change_mtu,
> .ndo_get_stats64 = internal_get_stats,
> .ndo_set_rx_headroom = internal_set_rx_headroom,
> };

vport-internal uses ether_setup, so the MTU is currently limited to
1500, no?


--
Sabrina

2016-10-19 14:15:32

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 5/6] net: use core MTU range checking in virt drivers

On Wed, Oct 19, 2016 at 04:59:46PM +0300, Michael S. Tsirkin wrote:
> On Tue, Oct 18, 2016 at 10:33:32PM -0400, Jarod Wilson wrote:
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index fad84f3..4885a42 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1419,17 +1419,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
> > .set_settings = virtnet_set_settings,
> > };
> >
> > -#define MIN_MTU 68
> > -#define MAX_MTU 65535
> > -
> > -static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
> > -{
> > - if (new_mtu < MIN_MTU || new_mtu > MAX_MTU)
> > - return -EINVAL;
> > - dev->mtu = new_mtu;
> > - return 0;
> > -}
> > -
> > static const struct net_device_ops virtnet_netdev = {
> > .ndo_open = virtnet_open,
> > .ndo_stop = virtnet_close,
> > @@ -1437,7 +1426,6 @@ static const struct net_device_ops virtnet_netdev = {
> > .ndo_validate_addr = eth_validate_addr,
> > .ndo_set_mac_address = virtnet_set_mac_address,
> > .ndo_set_rx_mode = virtnet_set_rx_mode,
> > - .ndo_change_mtu = virtnet_change_mtu,
> > .ndo_get_stats64 = virtnet_stats,
> > .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
> > .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
> > @@ -1748,6 +1736,9 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
> > return true;
> > }
> >
> > +#define MIN_MTU ETH_MIN_MTU
> > +#define MAX_MTU 65535
> > +
>
> Do we need a common macro for this?

Probably. That value crops up in multiple drivers.

> > static int virtnet_probe(struct virtio_device *vdev)
> > {
> > int i, err;
> > @@ -1821,6 +1812,10 @@ static int virtnet_probe(struct virtio_device *vdev)
> >
> > dev->vlan_features = dev->features;
> >
> > + /* MTU range: 68 - 65535 */
> > + dev->min_mtu = MIN_MTU;
> > + dev->max_mtu = MAX_MTU;
> > +
> > /* Configuration may specify what MAC to use. Otherwise random. */
> > if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
> > virtio_cread_bytes(vdev,
> > @@ -1875,8 +1870,10 @@ static int virtnet_probe(struct virtio_device *vdev)
> > mtu = virtio_cread16(vdev,
> > offsetof(struct virtio_net_config,
> > mtu));
> > - if (virtnet_change_mtu(dev, mtu))
> > + if (mtu >= dev->min_mtu && mtu <= dev->max_mtu) {
> > + dev->mtu = mtu;
> > __virtio_clear_bit(vdev, VIRTIO_NET_F_MTU);
>
> I think the logic is wrong here:
>
> If mtu is legal, we set it but do not tell host.
> If it's out of range we tell host we use it
> but don't actually.
>
> Should be the reverse.

Ah, yes, looks like it should be:

if (mtu < dev->min_mtu || mtu > dev->max_mtu)
__virtio_clear_bit(vdev, VIRTIO_NET_F_MTU);
else
dev->mtu = mtu;

--
Jarod Wilson
[email protected]

2016-10-19 14:16:57

by Michael S. Tsirkin

[permalink] [raw]
Subject: Re: [PATCH net-next 5/6] net: use core MTU range checking in virt drivers

On Tue, Oct 18, 2016 at 10:33:32PM -0400, Jarod Wilson wrote:
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index fad84f3..4885a42 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1419,17 +1419,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
> .set_settings = virtnet_set_settings,
> };
>
> -#define MIN_MTU 68
> -#define MAX_MTU 65535
> -
> -static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
> -{
> - if (new_mtu < MIN_MTU || new_mtu > MAX_MTU)
> - return -EINVAL;
> - dev->mtu = new_mtu;
> - return 0;
> -}
> -
> static const struct net_device_ops virtnet_netdev = {
> .ndo_open = virtnet_open,
> .ndo_stop = virtnet_close,
> @@ -1437,7 +1426,6 @@ static const struct net_device_ops virtnet_netdev = {
> .ndo_validate_addr = eth_validate_addr,
> .ndo_set_mac_address = virtnet_set_mac_address,
> .ndo_set_rx_mode = virtnet_set_rx_mode,
> - .ndo_change_mtu = virtnet_change_mtu,
> .ndo_get_stats64 = virtnet_stats,
> .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
> .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
> @@ -1748,6 +1736,9 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
> return true;
> }
>
> +#define MIN_MTU ETH_MIN_MTU
> +#define MAX_MTU 65535
> +

Do we need a common macro for this?

> static int virtnet_probe(struct virtio_device *vdev)
> {
> int i, err;
> @@ -1821,6 +1812,10 @@ static int virtnet_probe(struct virtio_device *vdev)
>
> dev->vlan_features = dev->features;
>
> + /* MTU range: 68 - 65535 */
> + dev->min_mtu = MIN_MTU;
> + dev->max_mtu = MAX_MTU;
> +
> /* Configuration may specify what MAC to use. Otherwise random. */
> if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
> virtio_cread_bytes(vdev,
> @@ -1875,8 +1870,10 @@ static int virtnet_probe(struct virtio_device *vdev)
> mtu = virtio_cread16(vdev,
> offsetof(struct virtio_net_config,
> mtu));
> - if (virtnet_change_mtu(dev, mtu))
> + if (mtu >= dev->min_mtu && mtu <= dev->max_mtu) {
> + dev->mtu = mtu;
> __virtio_clear_bit(vdev, VIRTIO_NET_F_MTU);

I think the logic is wrong here:

If mtu is legal, we set it but do not tell host.
If it's out of range we tell host we use it
but don't actually.

Should be the reverse.

> + }
> }
>
> if (vi->any_header_sg)

--
MST

2016-10-19 14:18:11

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 5/6] net: use core MTU range checking in virt drivers

On Wed, Oct 19, 2016 at 05:03:43PM +0300, Michael S. Tsirkin wrote:
> On Wed, Oct 19, 2016 at 04:59:46PM +0300, Michael S. Tsirkin wrote:
> > On Tue, Oct 18, 2016 at 10:33:32PM -0400, Jarod Wilson wrote:
> > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > index fad84f3..4885a42 100644
> > > --- a/drivers/net/virtio_net.c
> > > +++ b/drivers/net/virtio_net.c
> > > @@ -1419,17 +1419,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
> > > .set_settings = virtnet_set_settings,
> > > };
> > >
> > > -#define MIN_MTU 68
> > > -#define MAX_MTU 65535
> > > -
> > > -static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
> > > -{
> > > - if (new_mtu < MIN_MTU || new_mtu > MAX_MTU)
> > > - return -EINVAL;
> > > - dev->mtu = new_mtu;
> > > - return 0;
> > > -}
> > > -
> > > static const struct net_device_ops virtnet_netdev = {
> > > .ndo_open = virtnet_open,
> > > .ndo_stop = virtnet_close,
> > > @@ -1437,7 +1426,6 @@ static const struct net_device_ops virtnet_netdev = {
> > > .ndo_validate_addr = eth_validate_addr,
> > > .ndo_set_mac_address = virtnet_set_mac_address,
> > > .ndo_set_rx_mode = virtnet_set_rx_mode,
> > > - .ndo_change_mtu = virtnet_change_mtu,
> > > .ndo_get_stats64 = virtnet_stats,
> > > .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
> > > .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
> > > @@ -1748,6 +1736,9 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
> > > return true;
> > > }
> > >
> > > +#define MIN_MTU ETH_MIN_MTU
> > > +#define MAX_MTU 65535
> > > +
> >
> > Do we need a common macro for this?
>
> I think it's actually IP_MAX_MTU.

Ah, yes, it is. I'm not sure why I didn't use that...

--
Jarod Wilson
[email protected]

2016-10-19 14:23:34

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 5/6] net: use core MTU range checking in virt drivers

On Wed, Oct 19, 2016 at 02:07:47PM +0000, Haiyang Zhang wrote:
>
>
> > -----Original Message-----
> > From: Jarod Wilson [mailto:[email protected]]
> > Sent: Tuesday, October 18, 2016 10:34 PM
> > To: [email protected]
> > Cc: Jarod Wilson <[email protected]>; [email protected];
> > [email protected]; KY Srinivasan
> > <[email protected]>; Haiyang Zhang <[email protected]>; Michael S.
> > Tsirkin <[email protected]>; Shrikrishna Khare <[email protected]>; VMware,
> > Inc. <[email protected]>
> > Subject: [PATCH net-next 5/6] net: use core MTU range checking in virt
> > drivers
> >
> > hyperv_net:
> > - set min/max_mtu
> >
> > virtio_net:
> > - set min/max_mtu
> > - remove virtnet_change_mtu
> >
> > vmxnet3:
> > - set min/max_mtu
> >
> > CC: [email protected]
> > CC: [email protected]
> > CC: "K. Y. Srinivasan" <[email protected]>
> > CC: Haiyang Zhang <[email protected]>
> > CC: "Michael S. Tsirkin" <[email protected]>
> > CC: Shrikrishna Khare <[email protected]>
> > CC: "VMware, Inc." <[email protected]>
> > Signed-off-by: Jarod Wilson <[email protected]>
> > ---
> > drivers/net/hyperv/hyperv_net.h | 4 ++--
> > drivers/net/hyperv/netvsc_drv.c | 14 +++++++-------
> > drivers/net/virtio_net.c | 23 ++++++++++-------------
> > drivers/net/vmxnet3/vmxnet3_drv.c | 7 ++++---
> > 4 files changed, 23 insertions(+), 25 deletions(-)
> >
> > diff --git a/drivers/net/hyperv/hyperv_net.h
> > b/drivers/net/hyperv/hyperv_net.h
> > index f4fbcb5..3958ada 100644
> > --- a/drivers/net/hyperv/hyperv_net.h
> > +++ b/drivers/net/hyperv/hyperv_net.h
> > @@ -606,8 +606,8 @@ struct nvsp_message {
> > } __packed;
> >
> >
> > -#define NETVSC_MTU 65536
> > -#define NETVSC_MTU_MIN 68
> > +#define NETVSC_MTU 65535
>
> Why change it to 65535? For Hyperv host, this should be 65536.

Forgot to call this change out, sorry. That was changed, because of
IP_MAX_MTU being 0xFFFFU -> 65535.

> > @@ -1343,6 +1336,13 @@ static int netvsc_probe(struct hv_device *dev,
> >
> > netif_carrier_off(net);
> >
> > + /* MTU range: 68 - 1500 or 65521 */
> > + net->min_mtu = NETVSC_MTU_MIN;
> > + if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
> > + net->max_mtu = NETVSC_MTU - ETH_HLEN;
> > + else
> > + net->max_mtu = ETH_DATA_LEN;
> > +
> > netvsc_init_settings(net);
> >
> > net_device_ctx = netdev_priv(net);
>
> nvdev->nvsp_version is not set until after rndis_filter_device_add()
> is successfully completed.
> You need to move this part to the place just before this line:
> ret = register_netdev(net);

Okay, will fix that up.

--
Jarod Wilson
[email protected]

2016-10-19 14:27:15

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 2/6] net: use core MTU range checking in wireless drivers

On Wed, Oct 19, 2016 at 09:38:33AM +0200, Johannes Berg wrote:
> On Tue, 2016-10-18 at 22:33 -0400, Jarod Wilson wrote:
> > - set max_mtu in wil6210 driver
> > - set max_mtu in atmel driver
> > - set min/max_mtu in cisco airo driver, remove airo_change_mtu
> > - set min/max_mtu in ipw2100/ipw2200 drivers, remove
> > libipw_change_mtu
> > - set min/max_mtu in p80211netdev, remove wlan_change_mtu
>
> I guess we should do the same in net/mac80211/iface.c?

Yeah. I thought I'd located all places this needed to happen, but
obviously not. I'll get this added and do another sweep for others I might
have missed.

--
Jarod Wilson
[email protected]

2016-10-19 14:37:32

by Robin Holt

[permalink] [raw]
Subject: Re: [PATCH net-next 6/6] net: use core MTU range checking in misc drivers

On Tue, Oct 18, 2016 at 9:33 PM, Jarod Wilson <[email protected]> wrote:
> CC: [email protected]
> CC: Stefan Richter <[email protected]>
> CC: Faisal Latif <[email protected]>
> CC: [email protected]
> CC: Cliff Whickman <[email protected]>

Acked-by: Robin Holt <[email protected]>

> CC: Jes Sorensen <[email protected]>
> CC: Marek Lindner <[email protected]>
> CC: Simon Wunderlich <[email protected]>
> CC: Antonio Quartulli <[email protected]>
> Signed-off-by: Jarod Wilson <[email protected]>

2016-10-19 14:40:18

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 4/6] net: use core MTU range checking in core net infra

On Wed, Oct 19, 2016 at 03:55:29PM +0200, Sabrina Dubroca wrote:
> 2016-10-18, 22:33:31 -0400, Jarod Wilson wrote:
> > geneve:
> > - Merge __geneve_change_mtu back into geneve_change_mtu, set max_mtu
> > - This one isn't quite as straight-forward as others, could use some
> > closer inspection and testing
> >
> > macvlan:
> > - set min/max_mtu
> >
> > tun:
> > - set min/max_mtu, remove tun_net_change_mtu
> >
> > vxlan:
> > - Merge __vxlan_change_mtu back into vxlan_change_mtu, set min/max_mtu
> > - This one is also not as straight-forward and could use closer inspection
> > and testing from vxlan folks
> >
> > bridge:
> > - set max_mtu via br_min_mtu()
> >
> > 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
> >
> > sch_teql:
> > - set min/max_mtu (note: max_mtu previously unchecked, used max of 65535)
>
> Nothing for other virtual netdevices? (dummy, veth, bond, etc) Their
> MTU is limited to 1500 now. Also missing macsec and ip_gre, probably
> others that are using ether_setup.

Yeah, I've clearly missed more than I thought. Doing another sweep now.
I'm thinking more and more that we ought to back out the patch that sets
min/max in ether_setup, save it for last, after we're sure everyone that
calls it has been prepared.

> [...]
> > diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
> > index 89a687f..81fc79a 100644
> > --- a/net/bridge/br_device.c
> > +++ b/net/bridge/br_device.c
> > @@ -184,17 +184,15 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev,
> >
> > static int br_change_mtu(struct net_device *dev, int new_mtu)
> > {
> > +#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
> > struct net_bridge *br = netdev_priv(dev);
> > - if (new_mtu < 68 || new_mtu > br_min_mtu(br))
> > - return -EINVAL;
> > -
> > - dev->mtu = new_mtu;
> >
> > -#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
> > /* remember the MTU in the rtable for PMTU */
> > dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
> > #endif
> >
> > + dev->mtu = new_mtu;
> > +
> > return 0;
> > }
> >
> > @@ -390,6 +388,7 @@ void br_dev_setup(struct net_device *dev)
> > dev->hw_features = COMMON_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
> > NETIF_F_HW_VLAN_STAG_TX;
> > dev->vlan_features = COMMON_FEATURES;
> > + dev->max_mtu = br_min_mtu(br);
>
> br_min_mtu uses br->port_list, which is only initialized a few lines
> later (right after the spin_lock_init() at the end of the context of
> this diff).

Ah, okay, I'd just grouped it with the other dev->foo settings.

> Besides, I don't think this works: br_min_mtu(br) changes when you add
> and remove ports, or when you change the MTU of an enslaved
> device. But this makes the max MTU for the bridge fixed (to 1500).

Okay, how about this: set no max_mtu (or set it to IP_MAX_MTU/65535), and
then retain a check against the possibly ever-changing br_min_mtu(br) in
br_change_mtu()?

> > diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
> > index e7da290..d5d6cae 100644
> > --- a/net/openvswitch/vport-internal_dev.c
> > +++ b/net/openvswitch/vport-internal_dev.c
> > @@ -89,15 +89,6 @@ 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)
> > -{
> > - if (new_mtu < 68)
> > - return -EINVAL;
> > -
> > - netdev->mtu = new_mtu;
> > - return 0;
> > -}
> > -
> > static void internal_dev_destructor(struct net_device *dev)
> > {
> > struct vport *vport = ovs_internal_dev_get_vport(dev);
> > @@ -148,7 +139,6 @@ 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,
> > - .ndo_change_mtu = internal_dev_change_mtu,
> > .ndo_get_stats64 = internal_get_stats,
> > .ndo_set_rx_headroom = internal_set_rx_headroom,
> > };
>
> vport-internal uses ether_setup, so the MTU is currently limited to
> 1500, no?

Yeah. Sweep ongoing...

--
Jarod Wilson
[email protected]

2016-10-19 14:46:45

by Jiri Benc

[permalink] [raw]
Subject: Re: [PATCH net-next 4/6] net: use core MTU range checking in core net infra

On Tue, 18 Oct 2016 22:33:31 -0400, Jarod Wilson wrote:
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -2367,43 +2367,31 @@ 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)
> +static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
> {
> - int max_mtu = IP_MAX_MTU;
> -
> - if (lowerdev)
> - max_mtu = lowerdev->mtu;
> + struct vxlan_dev *vxlan = netdev_priv(dev);
> + struct vxlan_rdst *dst = &vxlan->default_dst;
> + struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
> + dst->remote_ifindex);
> + bool use_ipv6 = false;
>
> if (dst->remote_ip.sa.sa_family == AF_INET6)
> - max_mtu -= VXLAN6_HEADROOM;
> - else
> - max_mtu -= VXLAN_HEADROOM;
> -
> - if (new_mtu < 68)
> - return -EINVAL;
> + use_ipv6 = true;
>
> - if (new_mtu > max_mtu) {
> - if (strict)
> + /* We re-check this, because users *could* alter the mtu of the
> + * lower device after we've initialized dev->max_mtu.
> + */
> + if (lowerdev) {
> + dev->max_mtu = lowerdev->mtu -
> + (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> + if (new_mtu > dev->max_mtu)
> return -EINVAL;
> -
> - new_mtu = max_mtu;
> }
>
> dev->mtu = new_mtu;
> return 0;
> }

Sorry for the silly question, how does the min_mtu and max_mtu stuff
works? I noticed your patches but haven't looked in depth into them.

When the ndo_change_mtu callback is defined, is the dev->min_mtu and
dev->max_mtu checked first and if the desired mtu is not within range,
ndo_change_mtu is not called?

Or does ndo_change_mtu override the checks?

In either case, the code does not look correct. In the first case,
increasing of lowerdev MTU wouldn't allow increasing of vxlan MTU
without deleting and recreating the vxlan interface. In the second
case, you're missing check against the min_mtu.

>
> -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 = __dev_get_by_index(vxlan->net,
> - dst->remote_ifindex);
> - return __vxlan_change_mtu(dev, lowerdev, dst, new_mtu, true);
> -}
> -
> static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
> {
> struct vxlan_dev *vxlan = netdev_priv(dev);
> @@ -2795,6 +2783,10 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
> vxlan_ether_setup(dev);
> }
>
> + /* MTU range: 68 - 65535 */
> + dev->min_mtu = 68;
> + dev->max_mtu = IP_MAX_MTU;
> +
> vxlan->net = src_net;
>
> dst->remote_vni = conf->vni;
> @@ -2837,8 +2829,11 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
> }
> #endif
>
> - if (!conf->mtu)
> - dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> + if (!conf->mtu) {
> + dev->mtu = lowerdev->mtu -
> + (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> + dev->max_mtu = dev->mtu;
> + }
>
> needed_headroom = lowerdev->hard_header_len;
> } else if (vxlan_addr_multicast(&dst->remote_ip)) {
> @@ -2847,9 +2842,14 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
> }
>
> if (conf->mtu) {
> - err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false);
> - if (err)
> - return err;
> + if (lowerdev)
> + dev->max_mtu = lowerdev->mtu;
> + dev->max_mtu -= (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> +
> + dev->mtu = conf->mtu;
> +
> + if (conf->mtu > dev->max_mtu)
> + dev->mtu = dev->max_mtu;
> }

You removed the check for min_mtu but it's needed here. The conf->mtu
value comes from the user space and can be anything.

>
> if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)

Jiri

2016-10-19 14:51:55

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 4/6] net: use core MTU range checking in core net infra

On Wed, Oct 19, 2016 at 02:17:03PM +0200, Jiri Benc wrote:
> On Tue, 18 Oct 2016 22:33:31 -0400, Jarod Wilson wrote:
> > --- a/drivers/net/vxlan.c
> > +++ b/drivers/net/vxlan.c
> > @@ -2367,43 +2367,31 @@ 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)
> > +static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
> > {
> > - int max_mtu = IP_MAX_MTU;
> > -
> > - if (lowerdev)
> > - max_mtu = lowerdev->mtu;
> > + struct vxlan_dev *vxlan = netdev_priv(dev);
> > + struct vxlan_rdst *dst = &vxlan->default_dst;
> > + struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
> > + dst->remote_ifindex);
> > + bool use_ipv6 = false;
> >
> > if (dst->remote_ip.sa.sa_family == AF_INET6)
> > - max_mtu -= VXLAN6_HEADROOM;
> > - else
> > - max_mtu -= VXLAN_HEADROOM;
> > -
> > - if (new_mtu < 68)
> > - return -EINVAL;
> > + use_ipv6 = true;
> >
> > - if (new_mtu > max_mtu) {
> > - if (strict)
> > + /* We re-check this, because users *could* alter the mtu of the
> > + * lower device after we've initialized dev->max_mtu.
> > + */
> > + if (lowerdev) {
> > + dev->max_mtu = lowerdev->mtu -
> > + (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> > + if (new_mtu > dev->max_mtu)
> > return -EINVAL;
> > -
> > - new_mtu = max_mtu;
> > }
> >
> > dev->mtu = new_mtu;
> > return 0;
> > }
>
> Sorry for the silly question, how does the min_mtu and max_mtu stuff
> works? I noticed your patches but haven't looked in depth into them.
>
> When the ndo_change_mtu callback is defined, is the dev->min_mtu and
> dev->max_mtu checked first and if the desired mtu is not within range,
> ndo_change_mtu is not called?
>
> Or does ndo_change_mtu override the checks?

The former. If the new value is outside min/max, ndo_change_mtu doesn't
get called, which is exactly the chicken and egg problem I introduced by
setting max_mtu to 1500 in ether_setup before having all drivers that call
ether_setup set a more appropriate max_mtu first. :\

> In either case, the code does not look correct. In the first case,
> increasing of lowerdev MTU wouldn't allow increasing of vxlan MTU
> without deleting and recreating the vxlan interface. In the second
> case, you're missing check against the min_mtu.

Okay, this sounds like a similar case to bridge that Sabrina pointed out.
Looks like virtual devices will need to just set no max_mtu directly (or
IP_MAX_MTU), and do dynamic checks in their ndo_change_mtu if they need to
compare against underlying devices on the fly.

...
> > @@ -2847,9 +2842,14 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
> > }
> >
> > if (conf->mtu) {
> > - err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false);
> > - if (err)
> > - return err;
> > + if (lowerdev)
> > + dev->max_mtu = lowerdev->mtu;
> > + dev->max_mtu -= (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> > +
> > + dev->mtu = conf->mtu;
> > +
> > + if (conf->mtu > dev->max_mtu)
> > + dev->mtu = dev->max_mtu;
> > }
>
> You removed the check for min_mtu but it's needed here. The conf->mtu
> value comes from the user space and can be anything.

Hm. Not sure why I did that... Will put it back now...

--
Jarod Wilson
[email protected]

2016-10-19 15:00:03

by Aaron Conole

[permalink] [raw]
Subject: Re: [PATCH net-next 5/6] net: use core MTU range checking in virt drivers

Jarod Wilson <[email protected]> writes:

> hyperv_net:
> - set min/max_mtu
>
> virtio_net:
> - set min/max_mtu
> - remove virtnet_change_mtu
>
> vmxnet3:
> - set min/max_mtu
>
> CC: [email protected]
> CC: [email protected]
> CC: "K. Y. Srinivasan" <[email protected]>
> CC: Haiyang Zhang <[email protected]>
> CC: "Michael S. Tsirkin" <[email protected]>
> CC: Shrikrishna Khare <[email protected]>
> CC: "VMware, Inc." <[email protected]>
> Signed-off-by: Jarod Wilson <[email protected]>
> ---


The virtnet change looks good to me. It simplifies an enhancement that
I was about to propose, so I'll let yours land first.

-Aaron

2016-10-19 15:28:13

by Sabrina Dubroca

[permalink] [raw]
Subject: Re: [PATCH net-next 4/6] net: use core MTU range checking in core net infra

2016-10-19, 10:40:06 -0400, Jarod Wilson wrote:
> On Wed, Oct 19, 2016 at 03:55:29PM +0200, Sabrina Dubroca wrote:
> > 2016-10-18, 22:33:31 -0400, Jarod Wilson wrote:
> > > geneve:
> > > - Merge __geneve_change_mtu back into geneve_change_mtu, set max_mtu
> > > - This one isn't quite as straight-forward as others, could use some
> > > closer inspection and testing
> > >
> > > macvlan:
> > > - set min/max_mtu
> > >
> > > tun:
> > > - set min/max_mtu, remove tun_net_change_mtu
> > >
> > > vxlan:
> > > - Merge __vxlan_change_mtu back into vxlan_change_mtu, set min/max_mtu
> > > - This one is also not as straight-forward and could use closer inspection
> > > and testing from vxlan folks
> > >
> > > bridge:
> > > - set max_mtu via br_min_mtu()
> > >
> > > 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
> > >
> > > sch_teql:
> > > - set min/max_mtu (note: max_mtu previously unchecked, used max of 65535)
> >
> > Nothing for other virtual netdevices? (dummy, veth, bond, etc) Their
> > MTU is limited to 1500 now. Also missing macsec and ip_gre, probably
> > others that are using ether_setup.
>
> Yeah, I've clearly missed more than I thought. Doing another sweep now.

Thanks.


> I'm thinking more and more that we ought to back out the patch that sets
> min/max in ether_setup, save it for last, after we're sure everyone that
> calls it has been prepared.

I'm not sure how that would work now, if some of the patches that
already went in for ethernet drivers assume that ether_setup will
configure a basic {min,max}_mtu pair (at least e100 makes that
assumption, but that might be the only one).

> > [...]
> > > diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
> > > index 89a687f..81fc79a 100644
> > > --- a/net/bridge/br_device.c
> > > +++ b/net/bridge/br_device.c
> > > @@ -184,17 +184,15 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev,
> > >
> > > static int br_change_mtu(struct net_device *dev, int new_mtu)
> > > {
> > > +#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
> > > struct net_bridge *br = netdev_priv(dev);
> > > - if (new_mtu < 68 || new_mtu > br_min_mtu(br))
> > > - return -EINVAL;
> > > -
> > > - dev->mtu = new_mtu;
> > >
> > > -#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
> > > /* remember the MTU in the rtable for PMTU */
> > > dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
> > > #endif
> > >
> > > + dev->mtu = new_mtu;
> > > +
> > > return 0;
> > > }
> > >
> > > @@ -390,6 +388,7 @@ void br_dev_setup(struct net_device *dev)
> > > dev->hw_features = COMMON_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
> > > NETIF_F_HW_VLAN_STAG_TX;
> > > dev->vlan_features = COMMON_FEATURES;
> > > + dev->max_mtu = br_min_mtu(br);
> >
> > br_min_mtu uses br->port_list, which is only initialized a few lines
> > later (right after the spin_lock_init() at the end of the context of
> > this diff).
>
> Ah, okay, I'd just grouped it with the other dev->foo settings.
>
> > Besides, I don't think this works: br_min_mtu(br) changes when you add
> > and remove ports, or when you change the MTU of an enslaved
> > device. But this makes the max MTU for the bridge fixed (to 1500).
>
> Okay, how about this: set no max_mtu (or set it to IP_MAX_MTU/65535), and
> then retain a check against the possibly ever-changing br_min_mtu(br) in
> br_change_mtu()?

Sounds good to me.


--
Sabrina

2016-10-19 15:42:38

by Haiyang Zhang

[permalink] [raw]
Subject: RE: [PATCH net-next 5/6] net: use core MTU range checking in virt drivers



> -----Original Message-----
> From: Jarod Wilson [mailto:[email protected]]
> Sent: Tuesday, October 18, 2016 10:34 PM
> To: [email protected]
> Cc: Jarod Wilson <[email protected]>; [email protected];
> [email protected]; KY Srinivasan
> <[email protected]>; Haiyang Zhang <[email protected]>; Michael S.
> Tsirkin <[email protected]>; Shrikrishna Khare <[email protected]>; VMware,
> Inc. <[email protected]>
> Subject: [PATCH net-next 5/6] net: use core MTU range checking in virt
> drivers
>
> hyperv_net:
> - set min/max_mtu
>
> virtio_net:
> - set min/max_mtu
> - remove virtnet_change_mtu
>
> vmxnet3:
> - set min/max_mtu
>
> CC: [email protected]
> CC: [email protected]
> CC: "K. Y. Srinivasan" <[email protected]>
> CC: Haiyang Zhang <[email protected]>
> CC: "Michael S. Tsirkin" <[email protected]>
> CC: Shrikrishna Khare <[email protected]>
> CC: "VMware, Inc." <[email protected]>
> Signed-off-by: Jarod Wilson <[email protected]>
> ---
> drivers/net/hyperv/hyperv_net.h | 4 ++--
> drivers/net/hyperv/netvsc_drv.c | 14 +++++++-------
> drivers/net/virtio_net.c | 23 ++++++++++-------------
> drivers/net/vmxnet3/vmxnet3_drv.c | 7 ++++---
> 4 files changed, 23 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/net/hyperv/hyperv_net.h
> b/drivers/net/hyperv/hyperv_net.h
> index f4fbcb5..3958ada 100644
> --- a/drivers/net/hyperv/hyperv_net.h
> +++ b/drivers/net/hyperv/hyperv_net.h
> @@ -606,8 +606,8 @@ struct nvsp_message {
> } __packed;
>
>
> -#define NETVSC_MTU 65536
> -#define NETVSC_MTU_MIN 68
> +#define NETVSC_MTU 65535

Why change it to 65535? For Hyperv host, this should be 65536.


> @@ -1343,6 +1336,13 @@ static int netvsc_probe(struct hv_device *dev,
>
> netif_carrier_off(net);
>
> + /* MTU range: 68 - 1500 or 65521 */
> + net->min_mtu = NETVSC_MTU_MIN;
> + if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
> + net->max_mtu = NETVSC_MTU - ETH_HLEN;
> + else
> + net->max_mtu = ETH_DATA_LEN;
> +
> netvsc_init_settings(net);
>
> net_device_ctx = netdev_priv(net);

nvdev->nvsp_version is not set until after rndis_filter_device_add()
is successfully completed.
You need to move this part to the place just before this line:
ret = register_netdev(net);

Thanks,
- Haiyang

2016-10-19 15:44:13

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH net-next 2/6] net: use core MTU range checking in wireless drivers

On Tue, 2016-10-18 at 22:33 -0400, Jarod Wilson wrote:
> - set max_mtu in wil6210 driver
> - set max_mtu in atmel driver
> - set min/max_mtu in cisco airo driver, remove airo_change_mtu
> - set min/max_mtu in ipw2100/ipw2200 drivers, remove
> libipw_change_mtu
> - set min/max_mtu in p80211netdev, remove wlan_change_mtu

I guess we should do the same in net/mac80211/iface.c?

johannes

2016-10-19 15:46:58

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 4/6] net: use core MTU range checking in core net infra

On Wed, Oct 19, 2016 at 05:28:00PM +0200, Sabrina Dubroca wrote:
> 2016-10-19, 10:40:06 -0400, Jarod Wilson wrote:
> > On Wed, Oct 19, 2016 at 03:55:29PM +0200, Sabrina Dubroca wrote:
> > > 2016-10-18, 22:33:31 -0400, Jarod Wilson wrote:
...
> > I'm thinking more and more that we ought to back out the patch that sets
> > min/max in ether_setup, save it for last, after we're sure everyone that
> > calls it has been prepared.
>
> I'm not sure how that would work now, if some of the patches that
> already went in for ethernet drivers assume that ether_setup will
> configure a basic {min,max}_mtu pair (at least e100 makes that
> assumption, but that might be the only one).

Argh. Yeah. Hrm. Would have to do the revert *and* have e100 and possibly
others set their own min/max pair. So I guess it's a race to fix all the
fallout... Crap.

> > > [...]
> > > > diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
> > > > index 89a687f..81fc79a 100644
> > > > --- a/net/bridge/br_device.c
> > > > +++ b/net/bridge/br_device.c
> > > > @@ -184,17 +184,15 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev,
> > > >
> > > > static int br_change_mtu(struct net_device *dev, int new_mtu)
> > > > {
> > > > +#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
> > > > struct net_bridge *br = netdev_priv(dev);
> > > > - if (new_mtu < 68 || new_mtu > br_min_mtu(br))
> > > > - return -EINVAL;
> > > > -
> > > > - dev->mtu = new_mtu;
> > > >
> > > > -#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
> > > > /* remember the MTU in the rtable for PMTU */
> > > > dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
> > > > #endif
> > > >
> > > > + dev->mtu = new_mtu;
> > > > +
> > > > return 0;
> > > > }
> > > >
> > > > @@ -390,6 +388,7 @@ void br_dev_setup(struct net_device *dev)
> > > > dev->hw_features = COMMON_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
> > > > NETIF_F_HW_VLAN_STAG_TX;
> > > > dev->vlan_features = COMMON_FEATURES;
> > > > + dev->max_mtu = br_min_mtu(br);
> > >
> > > br_min_mtu uses br->port_list, which is only initialized a few lines
> > > later (right after the spin_lock_init() at the end of the context of
> > > this diff).
> >
> > Ah, okay, I'd just grouped it with the other dev->foo settings.
> >
> > > Besides, I don't think this works: br_min_mtu(br) changes when you add
> > > and remove ports, or when you change the MTU of an enslaved
> > > device. But this makes the max MTU for the bridge fixed (to 1500).
> >
> > Okay, how about this: set no max_mtu (or set it to IP_MAX_MTU/65535), and
> > then retain a check against the possibly ever-changing br_min_mtu(br) in
> > br_change_mtu()?
>
> Sounds good to me.

I think I have something here locally that looks sane. Working on a few
other similar cases now.

--
Jarod Wilson
[email protected]

2016-10-19 14:29:00

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH net-next 2/6] net: use core MTU range checking in wireless drivers


> > I guess we should do the same in net/mac80211/iface.c?
>
> Yeah. I thought I'd located all places this needed to happen, but
> obviously not. I'll get this added and do another sweep for others I
> might have missed.

No worries. I can also do it if you prefer, just wanted to ask :)

johannes

2016-10-19 16:05:56

by Sabrina Dubroca

[permalink] [raw]
Subject: Re: [PATCH net-next 6/6] net: use core MTU range checking in misc drivers

2016-10-18, 22:33:33 -0400, Jarod Wilson wrote:
[...]
> diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
> index 309311b..b5f125c 100644
> --- a/drivers/firewire/net.c
> +++ b/drivers/firewire/net.c
> @@ -1349,15 +1349,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
> return NETDEV_TX_OK;
> }
>
> -static int fwnet_change_mtu(struct net_device *net, int new_mtu)
> -{
> - if (new_mtu < 68)
> - return -EINVAL;
> -
> - net->mtu = new_mtu;
> - return 0;
> -}
> -

This doesn't do any upper bound checking.

> static const struct ethtool_ops fwnet_ethtool_ops = {
> .get_link = ethtool_op_get_link,
> };
> @@ -1366,7 +1357,6 @@ static const struct net_device_ops fwnet_netdev_ops = {
> .ndo_open = fwnet_open,
> .ndo_stop = fwnet_stop,
> .ndo_start_xmit = fwnet_tx,
> - .ndo_change_mtu = fwnet_change_mtu,
> };
>
> static void fwnet_init_dev(struct net_device *net)
> @@ -1481,6 +1471,8 @@ static int fwnet_probe(struct fw_unit *unit,
> max_mtu = (1 << (card->max_receive + 1))
> - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> net->mtu = min(1500U, max_mtu);
> + net->min_mtu = ETH_MIN_MTU;
> + net->max_mtu = net->mtu;

But that will now prevent increasing the MTU above the initial value?

--
Sabrina

2016-10-19 14:19:36

by Michael S. Tsirkin

[permalink] [raw]
Subject: Re: [PATCH net-next 5/6] net: use core MTU range checking in virt drivers

On Wed, Oct 19, 2016 at 04:59:46PM +0300, Michael S. Tsirkin wrote:
> On Tue, Oct 18, 2016 at 10:33:32PM -0400, Jarod Wilson wrote:
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index fad84f3..4885a42 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1419,17 +1419,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
> > .set_settings = virtnet_set_settings,
> > };
> >
> > -#define MIN_MTU 68
> > -#define MAX_MTU 65535
> > -
> > -static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
> > -{
> > - if (new_mtu < MIN_MTU || new_mtu > MAX_MTU)
> > - return -EINVAL;
> > - dev->mtu = new_mtu;
> > - return 0;
> > -}
> > -
> > static const struct net_device_ops virtnet_netdev = {
> > .ndo_open = virtnet_open,
> > .ndo_stop = virtnet_close,
> > @@ -1437,7 +1426,6 @@ static const struct net_device_ops virtnet_netdev = {
> > .ndo_validate_addr = eth_validate_addr,
> > .ndo_set_mac_address = virtnet_set_mac_address,
> > .ndo_set_rx_mode = virtnet_set_rx_mode,
> > - .ndo_change_mtu = virtnet_change_mtu,
> > .ndo_get_stats64 = virtnet_stats,
> > .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
> > .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
> > @@ -1748,6 +1736,9 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
> > return true;
> > }
> >
> > +#define MIN_MTU ETH_MIN_MTU
> > +#define MAX_MTU 65535
> > +
>
> Do we need a common macro for this?

I think it's actually IP_MAX_MTU.

> > static int virtnet_probe(struct virtio_device *vdev)
> > {
> > int i, err;
> > @@ -1821,6 +1812,10 @@ static int virtnet_probe(struct virtio_device *vdev)
> >
> > dev->vlan_features = dev->features;
> >
> > + /* MTU range: 68 - 65535 */
> > + dev->min_mtu = MIN_MTU;
> > + dev->max_mtu = MAX_MTU;
> > +
> > /* Configuration may specify what MAC to use. Otherwise random. */
> > if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
> > virtio_cread_bytes(vdev,
> > @@ -1875,8 +1870,10 @@ static int virtnet_probe(struct virtio_device *vdev)
> > mtu = virtio_cread16(vdev,
> > offsetof(struct virtio_net_config,
> > mtu));
> > - if (virtnet_change_mtu(dev, mtu))
> > + if (mtu >= dev->min_mtu && mtu <= dev->max_mtu) {
> > + dev->mtu = mtu;
> > __virtio_clear_bit(vdev, VIRTIO_NET_F_MTU);
>
> I think the logic is wrong here:
>
> If mtu is legal, we set it but do not tell host.
> If it's out of range we tell host we use it
> but don't actually.
>
> Should be the reverse.
>
> > + }
> > }
> >
> > if (vi->any_header_sg)
>
> --
> MST

2016-10-19 19:10:09

by David Miller

[permalink] [raw]
Subject: Re: [PATCH net-next 0/6] net: use core MTU range checking everywhere

From: Jarod Wilson <[email protected]>
Date: Tue, 18 Oct 2016 22:33:27 -0400

> This stack of patches should get absolutely everything in the kernel
> converted from doing their own MTU range checking to the core MTU range
> checking.

I'm expecting a respin of this series.

2016-10-19 19:29:11

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 0/6] net: use core MTU range checking everywhere

On Wed, Oct 19, 2016 at 03:10:05PM -0400, David Miller wrote:
> From: Jarod Wilson <[email protected]>
> Date: Tue, 18 Oct 2016 22:33:27 -0400
>
> > This stack of patches should get absolutely everything in the kernel
> > converted from doing their own MTU range checking to the core MTU range
> > checking.
>
> I'm expecting a respin of this series.

Absolutely. Will address all review comments, and have some additional
patches to add to the series to hopefully have absolutely everything
functional, asap.

--
Jarod Wilson
[email protected]

2016-10-19 22:22:09

by Shrikrishna Khare

[permalink] [raw]
Subject: Re: [PATCH net-next 5/6] net: use core MTU range checking in virt drivers



On Wed, 19 Oct 2016, Jarod Wilson wrote:

> hyperv_net:
> - set min/max_mtu
>
> virtio_net:
> - set min/max_mtu
> - remove virtnet_change_mtu
>
> vmxnet3:
> - set min/max_mtu
>
> CC: [email protected]
> CC: [email protected]
> CC: "K. Y. Srinivasan" <[email protected]>
> CC: Haiyang Zhang <[email protected]>
> CC: "Michael S. Tsirkin" <[email protected]>
> CC: Shrikrishna Khare <[email protected]>
> CC: "VMware, Inc." <[email protected]>
> Signed-off-by: Jarod Wilson <[email protected]>
> ---

The vmxnet3 part of the change looks good to me.

Thanks,
Shri

2016-10-19 22:39:22

by Stefan Richter

[permalink] [raw]
Subject: Re: [PATCH net-next 6/6] net: use core MTU range checking in misc drivers

On Oct 19 Sabrina Dubroca wrote:
> 2016-10-18, 22:33:33 -0400, Jarod Wilson wrote:
> [...]
> > diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
> > index 309311b..b5f125c 100644
> > --- a/drivers/firewire/net.c
> > +++ b/drivers/firewire/net.c
> > @@ -1349,15 +1349,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
> > return NETDEV_TX_OK;
> > }
> >
> > -static int fwnet_change_mtu(struct net_device *net, int new_mtu)
> > -{
> > - if (new_mtu < 68)
> > - return -EINVAL;
> > -
> > - net->mtu = new_mtu;
> > - return 0;
> > -}
> > -
>
> This doesn't do any upper bound checking.

I need to check more closely, but I think the RFC 2734 encapsulation spec
and our implementation do not impose a particular upper limit. Though I
guess it's bad to let userland set arbitrarily large values here.

> > static const struct ethtool_ops fwnet_ethtool_ops = {
> > .get_link = ethtool_op_get_link,
> > };
> > @@ -1366,7 +1357,6 @@ static const struct net_device_ops fwnet_netdev_ops = {
> > .ndo_open = fwnet_open,
> > .ndo_stop = fwnet_stop,
> > .ndo_start_xmit = fwnet_tx,
> > - .ndo_change_mtu = fwnet_change_mtu,
> > };
> >
> > static void fwnet_init_dev(struct net_device *net)
> > @@ -1481,6 +1471,8 @@ static int fwnet_probe(struct fw_unit *unit,
> > max_mtu = (1 << (card->max_receive + 1))
> > - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> > net->mtu = min(1500U, max_mtu);
> > + net->min_mtu = ETH_MIN_MTU;
> > + net->max_mtu = net->mtu;
>
> But that will now prevent increasing the MTU above the initial value?

Indeed, therefore NAK.

PS:
If the IP packet plus encapsulation header fits into IEEE 1394 packet
payload, it is transported without link fragmentation. If it does not
fit, link fragmentation occurs (which reduces bandwidth a bit and
consumes additional buffering resources at the transmitter and the
receiver).

Broadcast and multicast packets are transmitted via IEEE 1394 asynchronous
stream packets at a low bus speed (because our code does not attempt to
find the maximum speed and size that is supported by all potential
listeners). This limits the payload to 512 bytes.

Unicast packets are transmitted via IEEE 1394 asynchronous write request
packets at optimum speed. In most cases, this means that 2048 bytes
payload is possible, in some cases 4096 bytes. Many CardBus FireWire
cards support only 1024 bytes payload of these packets though.
Furthermore, some low-speed long-haul cablings may cap the bus speed and
thereby the payload size to 1024 or 512 bytes, but this is uncommon in
practice.
--
Stefan Richter
-======----- =-=- =-=--
http://arcgraph.de/sr/

2016-10-20 03:16:48

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 6/6] net: use core MTU range checking in misc drivers

On Thu, Oct 20, 2016 at 12:38:46AM +0200, Stefan Richter wrote:
> On Oct 19 Sabrina Dubroca wrote:
> > 2016-10-18, 22:33:33 -0400, Jarod Wilson wrote:
> > [...]
> > > diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
> > > index 309311b..b5f125c 100644
> > > --- a/drivers/firewire/net.c
> > > +++ b/drivers/firewire/net.c
> > > @@ -1349,15 +1349,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
> > > return NETDEV_TX_OK;
> > > }
> > >
> > > -static int fwnet_change_mtu(struct net_device *net, int new_mtu)
> > > -{
> > > - if (new_mtu < 68)
> > > - return -EINVAL;
> > > -
> > > - net->mtu = new_mtu;
> > > - return 0;
> > > -}
> > > -
> >
> > This doesn't do any upper bound checking.
>
> I need to check more closely, but I think the RFC 2734 encapsulation spec
> and our implementation do not impose a particular upper limit. Though I
> guess it's bad to let userland set arbitrarily large values here.

In which case, that would suggest using IP_MAX_MTU (65535) here.

> > > static const struct ethtool_ops fwnet_ethtool_ops = {
> > > .get_link = ethtool_op_get_link,
> > > };
> > > @@ -1366,7 +1357,6 @@ static const struct net_device_ops fwnet_netdev_ops = {
> > > .ndo_open = fwnet_open,
> > > .ndo_stop = fwnet_stop,
> > > .ndo_start_xmit = fwnet_tx,
> > > - .ndo_change_mtu = fwnet_change_mtu,
> > > };
> > >
> > > static void fwnet_init_dev(struct net_device *net)
> > > @@ -1481,6 +1471,8 @@ static int fwnet_probe(struct fw_unit *unit,
> > > max_mtu = (1 << (card->max_receive + 1))
> > > - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> > > net->mtu = min(1500U, max_mtu);
> > > + net->min_mtu = ETH_MIN_MTU;
> > > + net->max_mtu = net->mtu;
> >
> > But that will now prevent increasing the MTU above the initial value?
>
> Indeed, therefore NAK.

However, there's an explicit calculation for 'max_mtu' right there that I
glazed right over. It would seem perhaps *that* should be used for
net->max_mtu here, no?

> PS:
> If the IP packet plus encapsulation header fits into IEEE 1394 packet
> payload, it is transported without link fragmentation. If it does not
> fit, link fragmentation occurs (which reduces bandwidth a bit and
> consumes additional buffering resources at the transmitter and the
> receiver).
>
> Broadcast and multicast packets are transmitted via IEEE 1394 asynchronous
> stream packets at a low bus speed (because our code does not attempt to
> find the maximum speed and size that is supported by all potential
> listeners). This limits the payload to 512 bytes.
>
> Unicast packets are transmitted via IEEE 1394 asynchronous write request
> packets at optimum speed. In most cases, this means that 2048 bytes
> payload is possible, in some cases 4096 bytes. Many CardBus FireWire
> cards support only 1024 bytes payload of these packets though.
> Furthermore, some low-speed long-haul cablings may cap the bus speed and
> thereby the payload size to 1024 or 512 bytes, but this is uncommon in
> practice.

Thorough as always, Stefan! :)

--
Jarod Wilson
[email protected]

2016-10-20 17:55:36

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next v2 0/9] net: use core MTU range checking everywhere

This stack of patches should get absolutely everything in the kernel
converted from doing their own MTU range checking to the core MTU range
checking. This second spin includes alterations to hopefully fix all
concerns raised with the first, as well as including some additional
changes to drivers and infrastructure where I completely missed necessary
updates.

These have all been built through the 0-day build infrastructure via the
(rebasing) master branch at https://github.com/jarodwilson/linux-muck, which
at the time of the most recent compile across 147 configs, was based on
net-next at commit 7b1536ef0aa0.

Jarod Wilson (9):
ethernet: use net core MTU range checking in more drivers
net: use core MTU range checking in USB NIC drivers
net: use core MTU range checking in wireless drivers
net: use core MTU range checking in WAN drivers
net: use core MTU range checking in core net infra
net: use core MTU range checking in virt drivers
net: use core MTU range checking in misc drivers
s390/net: use net core MTU range checking
ipv4/6: use core net MTU range checking

CC: [email protected]

arch/um/drivers/net_kern.c | 8 ---
drivers/char/pcmcia/synclink_cs.c | 1 -
drivers/firewire/net.c | 18 ++----
drivers/hsi/clients/ssi_protocol.c | 14 ++---
drivers/infiniband/hw/nes/nes.c | 1 -
drivers/infiniband/hw/nes/nes.h | 4 +-
drivers/infiniband/hw/nes/nes_nic.c | 10 +---
drivers/infiniband/ulp/ipoib/ipoib_main.c | 1 +
drivers/message/fusion/mptlan.c | 15 ++---
drivers/misc/sgi-xp/xpnet.c | 21 ++-----
drivers/net/ethernet/alteon/acenic.c | 5 +-
drivers/net/ethernet/amazon/ena/ena_netdev.c | 9 +--
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 5 --
drivers/net/ethernet/amd/xgbe/xgbe-main.c | 2 +
drivers/net/ethernet/broadcom/sb1250-mac.c | 12 +---
drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 4 +-
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 6 +-
.../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 6 +-
drivers/net/ethernet/emulex/benet/be_main.c | 22 ++------
drivers/net/ethernet/ibm/ibmveth.c | 6 +-
drivers/net/ethernet/ibm/ibmvnic.c | 16 ++----
drivers/net/ethernet/jme.c | 12 ++--
drivers/net/ethernet/marvell/mv643xx_eth.c | 7 ++-
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 3 +
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 3 +
drivers/net/ethernet/natsemi/ns83820.c | 11 +---
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c | 12 ----
.../net/ethernet/qlogic/netxen/netxen_nic_main.c | 7 +++
drivers/net/ethernet/qlogic/qlge/qlge_main.c | 7 +++
drivers/net/ethernet/qualcomm/emac/emac.c | 13 ++---
drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 7 ++-
drivers/net/fddi/skfp/skfddi.c | 1 -
drivers/net/fjes/fjes_main.c | 2 +
drivers/net/geneve.c | 48 +++++++---------
drivers/net/hippi/rrunner.c | 1 -
drivers/net/hyperv/hyperv_net.h | 4 +-
drivers/net/hyperv/netvsc_drv.c | 14 ++---
drivers/net/macsec.c | 2 +
drivers/net/macvlan.c | 8 ++-
drivers/net/ntb_netdev.c | 3 +
drivers/net/rionet.c | 15 +----
drivers/net/slip/slip.c | 11 ++--
drivers/net/tun.c | 20 ++-----
drivers/net/usb/asix_devices.c | 4 +-
drivers/net/usb/ax88179_178a.c | 4 +-
drivers/net/usb/cdc-phonet.c | 12 +---
drivers/net/usb/cdc_ncm.c | 5 +-
drivers/net/usb/lan78xx.c | 8 +--
drivers/net/usb/r8152.c | 15 ++++-
drivers/net/usb/sierra_net.c | 13 +----
drivers/net/usb/smsc75xx.c | 4 +-
drivers/net/usb/usbnet.c | 4 +-
drivers/net/veth.c | 17 +-----
drivers/net/virtio_net.c | 23 ++++----
drivers/net/vmxnet3/vmxnet3_drv.c | 7 ++-
drivers/net/vxlan.c | 64 ++++++++++++----------
drivers/net/wan/c101.c | 1 -
drivers/net/wan/cosa.c | 1 -
drivers/net/wan/dscc4.c | 1 -
drivers/net/wan/farsync.c | 1 -
drivers/net/wan/fsl_ucc_hdlc.c | 1 -
drivers/net/wan/hdlc.c | 11 +---
drivers/net/wan/hdlc_fr.c | 3 +-
drivers/net/wan/hostess_sv11.c | 1 -
drivers/net/wan/ixp4xx_hss.c | 1 -
drivers/net/wan/lmc/lmc_main.c | 1 -
drivers/net/wan/n2.c | 1 -
drivers/net/wan/pc300too.c | 1 -
drivers/net/wan/pci200syn.c | 1 -
drivers/net/wan/sealevel.c | 1 -
drivers/net/wan/wanxl.c | 1 -
drivers/net/wan/x25_asy.c | 5 +-
drivers/net/wimax/i2400m/netdev.c | 22 +-------
drivers/net/wireless/ath/wil6210/netdev.c | 17 +-----
drivers/net/wireless/atmel/atmel.c | 13 ++---
drivers/net/wireless/cisco/airo.c | 14 +----
drivers/net/wireless/intel/ipw2x00/ipw2100.c | 3 +-
drivers/net/wireless/intel/ipw2x00/ipw2200.c | 8 ++-
drivers/net/wireless/intel/ipw2x00/libipw.h | 1 -
drivers/net/wireless/intel/ipw2x00/libipw_module.c | 9 ---
drivers/net/wireless/intersil/hostap/hostap_main.c | 15 +----
drivers/net/wireless/intersil/orinoco/main.c | 6 +-
drivers/net/xen-netback/interface.c | 5 +-
drivers/net/xen-netfront.c | 2 +
drivers/s390/net/ctcm_main.c | 5 +-
drivers/s390/net/netiucv.c | 24 +-------
drivers/s390/net/qeth_core_main.c | 4 --
drivers/s390/net/qeth_l2_main.c | 2 +
drivers/s390/net/qeth_l3_main.c | 2 +
drivers/staging/unisys/include/iochannel.h | 10 ++--
drivers/staging/unisys/visornic/visornic_main.c | 4 +-
drivers/staging/wlan-ng/p80211netdev.c | 18 ++----
drivers/tty/n_gsm.c | 12 +---
drivers/tty/synclink.c | 1 -
drivers/tty/synclink_gt.c | 1 -
drivers/tty/synclinkmp.c | 1 -
drivers/usb/gadget/function/f_phonet.c | 11 +---
drivers/usb/gadget/function/u_ether.c | 14 ++---
include/linux/fddidevice.h | 1 -
include/linux/hdlc.h | 2 -
include/linux/hippidevice.h | 1 -
include/uapi/linux/if_ether.h | 1 +
net/802/fddi.c | 11 +---
net/802/hippi.c | 14 +----
net/8021q/vlan_dev.c | 3 +
net/atm/lec.c | 11 +---
net/batman-adv/soft-interface.c | 13 +----
net/bridge/br_device.c | 3 +-
net/hsr/hsr_device.c | 1 +
net/ipv4/ip_tunnel.c | 6 +-
net/ipv6/ip6_tunnel.c | 4 +-
net/ipv6/ip6_vti.c | 21 +------
net/ipv6/sit.c | 14 +----
net/mac80211/iface.c | 15 ++---
net/openvswitch/vport-internal_dev.c | 10 ----
net/phonet/pep-gprs.c | 12 +---
net/sched/sch_teql.c | 5 +-
117 files changed, 316 insertions(+), 665 deletions(-)

--
2.10.0

2016-10-20 17:56:02

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next v2 8/9] s390/net: use net core MTU range checking

ctcm:
- min_mtu = 576, max_mtu = 65527

netiucv:
- min_mtu = 576, max_mtu = 65535

qeth:
- min_mtu = 64, max_mtu = 65535

CC: [email protected]
CC: [email protected]
CC: Ursula Braun <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/s390/net/ctcm_main.c | 5 ++---
drivers/s390/net/netiucv.c | 24 ++----------------------
drivers/s390/net/qeth_core_main.c | 4 ----
drivers/s390/net/qeth_l2_main.c | 2 ++
drivers/s390/net/qeth_l3_main.c | 2 ++
5 files changed, 8 insertions(+), 29 deletions(-)

diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index ad17fc5..ac65f12 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -1032,9 +1032,6 @@ static int ctcm_change_mtu(struct net_device *dev, int new_mtu)
struct ctcm_priv *priv;
int max_bufsize;

- if (new_mtu < 576 || new_mtu > 65527)
- return -EINVAL;
-
priv = dev->ml_priv;
max_bufsize = priv->channel[CTCM_READ]->max_bufsize;

@@ -1123,6 +1120,8 @@ void static ctcm_dev_setup(struct net_device *dev)
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 100;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ dev->min_mtu = 576;
+ dev->max_mtu = 65527;
}

/*
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 2f0f391..2981024 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1428,27 +1428,6 @@ static struct net_device_stats *netiucv_stats (struct net_device * dev)
return &priv->stats;
}

-/**
- * netiucv_change_mtu
- * @dev: Pointer to interface struct.
- * @new_mtu: The new MTU to use for this interface.
- *
- * Sets MTU of an interface.
- *
- * Returns 0 on success, -EINVAL if MTU is out of valid range.
- * (valid range is 576 .. NETIUCV_MTU_MAX).
- */
-static int netiucv_change_mtu(struct net_device * dev, int new_mtu)
-{
- IUCV_DBF_TEXT(trace, 3, __func__);
- if (new_mtu < 576 || new_mtu > NETIUCV_MTU_MAX) {
- IUCV_DBF_TEXT(setup, 2, "given MTU out of valid range\n");
- return -EINVAL;
- }
- dev->mtu = new_mtu;
- return 0;
-}
-
/*
* attributes in sysfs
*/
@@ -1986,12 +1965,13 @@ static const struct net_device_ops netiucv_netdev_ops = {
.ndo_stop = netiucv_close,
.ndo_get_stats = netiucv_stats,
.ndo_start_xmit = netiucv_tx,
- .ndo_change_mtu = netiucv_change_mtu,
};

static void netiucv_setup_netdevice(struct net_device *dev)
{
dev->mtu = NETIUCV_MTU_DEFAULT;
+ dev->min_mtu = 576;
+ dev->max_mtu = NETIUCV_MTU_MAX;
dev->destructor = netiucv_free_netdevice;
dev->hard_header_len = NETIUCV_HDRLEN;
dev->addr_len = 0;
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 20cf296..e335583 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -4202,10 +4202,6 @@ int qeth_change_mtu(struct net_device *dev, int new_mtu)
sprintf(dbf_text, "%8x", new_mtu);
QETH_CARD_TEXT(card, 4, dbf_text);

- if (new_mtu < 64)
- return -EINVAL;
- if (new_mtu > 65535)
- return -EINVAL;
if ((!qeth_is_supported(card, IPA_IP_FRAGMENTATION)) &&
(!qeth_mtu_is_valid(card, new_mtu)))
return -EINVAL;
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index bb27058..9c921c28 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1107,6 +1107,8 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
card->dev->ml_priv = card;
card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
card->dev->mtu = card->info.initial_mtu;
+ card->dev->min_mtu = 64;
+ card->dev->max_mtu = ETH_MAX_MTU;
card->dev->netdev_ops = &qeth_l2_netdev_ops;
card->dev->ethtool_ops =
(card->info.type != QETH_CARD_TYPE_OSN) ?
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 272d9e7..ac37d05 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -3140,6 +3140,8 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
card->dev->ml_priv = card;
card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
card->dev->mtu = card->info.initial_mtu;
+ card->dev->min_mtu = 64;
+ card->dev->max_mtu = ETH_MAX_MTU;
card->dev->ethtool_ops = &qeth_l3_ethtool_ops;
card->dev->features |= NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
--
2.10.0

2016-10-20 17:55:46

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next v2 1/9] ethernet: use net core MTU range checking in more drivers

Somehow, I missed a healthy number of ethernet drivers in the last pass.
Most of these drivers either were in need of an updated max_mtu to make
jumbo frames possible to enable again. In a few cases, also setting a
different min_mtu to match previous lower bounds. There are also a few
drivers that had no upper bounds checking, so they're getting a brand new
ETH_MAX_MTU that is identical to IP_MAX_MTU, but accessible by includes
all ethernet and ethernet-like drivers all have already.

acenic:
- min_mtu = 0, max_mtu = 9000

amazon/ena:
- min_mtu = 128, max_mtu = adapter->max_mtu

amd/xgbe:
- min_mtu = 0, max_mtu = 9000

sb1250:
- min_mtu = 0, max_mtu = 1518

cxgb3:
- min_mtu = 81, max_mtu = 65535

cxgb4:
- min_mtu = 81, max_mtu = 9600

cxgb4vf:
- min_mtu = 81, max_mtu = 65535

benet:
- min_mtu = 256, max_mtu = 9000

ibmveth:
- min_mtu = 68, max_mtu = 65535

ibmvnic:
- min_mtu = adapter->min_mtu, max_mtu = adapter->max_mtu
- remove now redundant ibmvnic_change_mtu

jme:
- min_mtu = 1280, max_mtu = 9202

mv643xx_eth:
- min_mtu = 64, max_mtu = 9500

mlxsw:
- min_mtu = 0, max_mtu = 65535
- Basically bypassing the core checks, and instead relying on dynamic
checks in the respective switch drivers' ndo_change_mtu functions

ns83820:
- min_mtu = 0
- remove redundant ns83820_change_mtu, only checked for mtu > 1500

netxen:
- min_mtu = 0, max_mtu = 8000 (P2), max_mtu = 9600 (P3)

qlge:
- min_mtu = 1500, max_mtu = 9000
- driver only supports setting mtu to 1500 or 9000, so the core check only
rules out < 1500 and > 9000, qlge_change_mtu still needs to check that
the value is 1500 or 9000

qualcomm/emac:
- min_mtu = 46, max_mtu = 9194

xilinx_axienet:
- min_mtu = 64, max_mtu = 9000

Fixes: 61e84623ace3 ("net: centralize net_device min/max MTU checking")
CC: [email protected]
CC: Jes Sorensen <[email protected]>
CC: Netanel Belgazal <[email protected]>
CC: Tom Lendacky <[email protected]>
CC: Santosh Raspatur <[email protected]>
CC: Hariprasad S <[email protected]>
CC: Sathya Perla <[email protected]>
CC: Ajit Khaparde <[email protected]>
CC: Sriharsha Basavapatna <[email protected]>
CC: Somnath Kotur <[email protected]>
CC: Thomas Falcon <[email protected]>
CC: John Allen <[email protected]>
CC: Guo-Fu Tseng <[email protected]>
CC: Sebastian Hesselbarth <[email protected]>
CC: Jiri Pirko <[email protected]>
CC: Ido Schimmel <[email protected]>
CC: Manish Chopra <[email protected]>
CC: Sony Chacko <[email protected]>
CC: Rajesh Borundia <[email protected]>
CC: Timur Tabi <[email protected]>
CC: Anirudha Sarangi <[email protected]>
CC: John Linn <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/net/ethernet/alteon/acenic.c | 5 ++---
drivers/net/ethernet/amazon/ena/ena_netdev.c | 9 ++-------
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 5 -----
drivers/net/ethernet/amd/xgbe/xgbe-main.c | 2 ++
drivers/net/ethernet/broadcom/sb1250-mac.c | 12 ++----------
drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 4 ++--
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 6 ++++--
.../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 6 ++----
drivers/net/ethernet/emulex/benet/be_main.c | 22 ++++------------------
drivers/net/ethernet/ibm/ibmveth.c | 6 +++---
drivers/net/ethernet/ibm/ibmvnic.c | 16 ++++------------
drivers/net/ethernet/jme.c | 12 ++++--------
drivers/net/ethernet/marvell/mv643xx_eth.c | 7 ++++---
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 3 +++
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 3 +++
drivers/net/ethernet/natsemi/ns83820.c | 11 ++---------
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c | 12 ------------
.../net/ethernet/qlogic/netxen/netxen_nic_main.c | 7 +++++++
drivers/net/ethernet/qlogic/qlge/qlge_main.c | 7 +++++++
drivers/net/ethernet/qualcomm/emac/emac.c | 13 ++++++-------
drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 7 ++++---
include/uapi/linux/if_ether.h | 1 +
22 files changed, 68 insertions(+), 108 deletions(-)

diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c
index b90a26b..a5c1e29 100644
--- a/drivers/net/ethernet/alteon/acenic.c
+++ b/drivers/net/ethernet/alteon/acenic.c
@@ -474,6 +474,8 @@ static int acenic_probe_one(struct pci_dev *pdev,
dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;

dev->watchdog_timeo = 5*HZ;
+ dev->min_mtu = 0;
+ dev->max_mtu = ACE_JUMBO_MTU;

dev->netdev_ops = &ace_netdev_ops;
dev->ethtool_ops = &ace_ethtool_ops;
@@ -2548,9 +2550,6 @@ static int ace_change_mtu(struct net_device *dev, int new_mtu)
struct ace_private *ap = netdev_priv(dev);
struct ace_regs __iomem *regs = ap->regs;

- if (new_mtu > ACE_JUMBO_MTU)
- return -EINVAL;
-
writel(new_mtu + ETH_HLEN + 4, &regs->IfMtu);
dev->mtu = new_mtu;

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index bfeaec5..2a55ab0 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -103,13 +103,6 @@ static int ena_change_mtu(struct net_device *dev, int new_mtu)
struct ena_adapter *adapter = netdev_priv(dev);
int ret;

- if ((new_mtu > adapter->max_mtu) || (new_mtu < ENA_MIN_MTU)) {
- netif_err(adapter, drv, dev,
- "Invalid MTU setting. new_mtu: %d\n", new_mtu);
-
- return -EINVAL;
- }
-
ret = ena_com_set_dev_mtu(adapter->ena_dev, new_mtu);
if (!ret) {
netif_dbg(adapter, drv, dev, "set MTU to %d\n", new_mtu);
@@ -2755,6 +2748,8 @@ static void ena_set_conf_feat_params(struct ena_adapter *adapter,
ena_set_dev_offloads(feat, netdev);

adapter->max_mtu = feat->dev_attr.max_mtu;
+ netdev->max_mtu = adapter->max_mtu;
+ netdev->min_mtu = ENA_MIN_MTU;
}

static int ena_rss_init_default(struct ena_adapter *adapter)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 7f9216d..c4e6682 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -257,11 +257,6 @@ static int xgbe_calc_rx_buf_size(struct net_device *netdev, unsigned int mtu)
{
unsigned int rx_buf_size;

- if (mtu > XGMAC_JUMBO_PACKET_MTU) {
- netdev_alert(netdev, "MTU exceeds maximum supported value\n");
- return -EINVAL;
- }
-
rx_buf_size = mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
rx_buf_size = clamp_val(rx_buf_size, XGBE_RX_MIN_BUF_SIZE, PAGE_SIZE);

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index 9de0788..667e120 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -738,6 +738,8 @@ static int xgbe_probe(struct platform_device *pdev)
pdata->netdev_features = netdev->features;

netdev->priv_flags |= IFF_UNICAST_FLT;
+ netdev->min_mtu = 0;
+ netdev->max_mtu = XGMAC_JUMBO_PACKET_MTU;

/* Use default watchdog timeout */
netdev->watchdog_timeo = 0;
diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c
index f1b8118..cb312e4 100644
--- a/drivers/net/ethernet/broadcom/sb1250-mac.c
+++ b/drivers/net/ethernet/broadcom/sb1250-mac.c
@@ -2147,15 +2147,6 @@ static void sbmac_setmulti(struct sbmac_softc *sc)
}
}

-static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
-{
- if (new_mtu > ENET_PACKET_SIZE)
- return -EINVAL;
- _dev->mtu = new_mtu;
- pr_info("changing the mtu to %d\n", new_mtu);
- return 0;
-}
-
static const struct net_device_ops sbmac_netdev_ops = {
.ndo_open = sbmac_open,
.ndo_stop = sbmac_close,
@@ -2163,7 +2154,6 @@ static const struct net_device_ops sbmac_netdev_ops = {
.ndo_set_rx_mode = sbmac_set_rx_mode,
.ndo_tx_timeout = sbmac_tx_timeout,
.ndo_do_ioctl = sbmac_mii_ioctl,
- .ndo_change_mtu = sb1250_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2229,6 +2219,8 @@ static int sbmac_init(struct platform_device *pldev, long long base)

dev->netdev_ops = &sbmac_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
+ dev->max_mtu = 0;
+ dev->max_mtu = ENET_PACKET_SIZE;

netif_napi_add(dev, &sc->napi, sbmac_poll, 16);

diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
index 43da891..092b3c1 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
@@ -2531,8 +2531,6 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
struct adapter *adapter = pi->adapter;
int ret;

- if (new_mtu < 81) /* accommodate SACK */
- return -EINVAL;
if ((ret = t3_mac_set_mtu(&pi->mac, new_mtu)))
return ret;
dev->mtu = new_mtu;
@@ -3295,6 +3293,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)

netdev->netdev_ops = &cxgb_netdev_ops;
netdev->ethtool_ops = &cxgb_ethtool_ops;
+ netdev->min_mtu = 81;
+ netdev->max_mtu = ETH_MAX_MTU;
}

pci_set_drvdata(pdev, adapter);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index f320497..b0bb23f 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2502,8 +2502,6 @@ static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
int ret;
struct port_info *pi = netdev_priv(dev);

- if (new_mtu < 81 || new_mtu > MAX_MTU) /* accommodate SACK */
- return -EINVAL;
ret = t4_set_rxmode(pi->adapter, pi->adapter->pf, pi->viid, new_mtu, -1,
-1, -1, -1, true);
if (!ret)
@@ -4803,6 +4801,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)

netdev->priv_flags |= IFF_UNICAST_FLT;

+ /* MTU range: 81 - 9600 */
+ netdev->min_mtu = 81;
+ netdev->max_mtu = MAX_MTU;
+
netdev->netdev_ops = &cxgb4_netdev_ops;
#ifdef CONFIG_CHELSIO_T4_DCB
netdev->dcbnl_ops = &cxgb4_dcb_ops;
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index 100b2cc..5d4da0e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -1108,10 +1108,6 @@ static int cxgb4vf_change_mtu(struct net_device *dev, int new_mtu)
int ret;
struct port_info *pi = netdev_priv(dev);

- /* accommodate SACK */
- if (new_mtu < 81)
- return -EINVAL;
-
ret = t4vf_set_rxmode(pi->adapter, pi->viid, new_mtu,
-1, -1, -1, -1, true);
if (!ret)
@@ -2966,6 +2962,8 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_HIGHDMA;

netdev->priv_flags |= IFF_UNICAST_FLT;
+ netdev->min_mtu = 81;
+ netdev->max_mtu = ETH_MAX_MTU;

netdev->netdev_ops = &cxgb4vf_netdev_ops;
netdev->ethtool_ops = &cxgb4vf_ethtool_ops;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index cece8a0..3f6152c 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1406,23 +1406,6 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}

-static int be_change_mtu(struct net_device *netdev, int new_mtu)
-{
- struct be_adapter *adapter = netdev_priv(netdev);
- struct device *dev = &adapter->pdev->dev;
-
- if (new_mtu < BE_MIN_MTU || new_mtu > BE_MAX_MTU) {
- dev_info(dev, "MTU must be between %d and %d bytes\n",
- BE_MIN_MTU, BE_MAX_MTU);
- return -EINVAL;
- }
-
- dev_info(dev, "MTU changed from %d to %d bytes\n",
- netdev->mtu, new_mtu);
- netdev->mtu = new_mtu;
- return 0;
-}
-
static inline bool be_in_all_promisc(struct be_adapter *adapter)
{
return (adapter->if_flags & BE_IF_FLAGS_ALL_PROMISCUOUS) ==
@@ -5216,7 +5199,6 @@ static const struct net_device_ops be_netdev_ops = {
.ndo_start_xmit = be_xmit,
.ndo_set_rx_mode = be_set_rx_mode,
.ndo_set_mac_address = be_mac_addr_set,
- .ndo_change_mtu = be_change_mtu,
.ndo_get_stats64 = be_get_stats64,
.ndo_validate_addr = eth_validate_addr,
.ndo_vlan_rx_add_vid = be_vlan_add_vid,
@@ -5266,6 +5248,10 @@ static void be_netdev_init(struct net_device *netdev)
netdev->netdev_ops = &be_netdev_ops;

netdev->ethtool_ops = &be_ethtool_ops;
+
+ /* MTU range: 256 - 9000 */
+ netdev->min_mtu = BE_MIN_MTU;
+ netdev->max_mtu = BE_MAX_MTU;
}

static void be_cleanup(struct be_adapter *adapter)
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index ebe6071..29c05d0 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -1349,9 +1349,6 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
int i, rc;
int need_restart = 0;

- if (new_mtu < IBMVETH_MIN_MTU)
- return -EINVAL;
-
for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
if (new_mtu_oh <= adapter->rx_buff_pool[i].buff_size)
break;
@@ -1551,6 +1548,9 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
netdev->hw_features |= NETIF_F_TSO;
}

+ netdev->min_mtu = IBMVETH_MIN_MTU;
+ netdev->min_mtu = ETH_MAX_MTU;
+
memcpy(netdev->dev_addr, mac_addr_p, ETH_ALEN);

if (firmware_has_feature(FW_FEATURE_CMO))
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index bfe17d9..657206b 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -902,17 +902,6 @@ static int ibmvnic_set_mac(struct net_device *netdev, void *p)
return 0;
}

-static int ibmvnic_change_mtu(struct net_device *netdev, int new_mtu)
-{
- struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-
- if (new_mtu > adapter->req_mtu || new_mtu < adapter->min_mtu)
- return -EINVAL;
-
- netdev->mtu = new_mtu;
- return 0;
-}
-
static void ibmvnic_tx_timeout(struct net_device *dev)
{
struct ibmvnic_adapter *adapter = netdev_priv(dev);
@@ -1029,7 +1018,6 @@ static const struct net_device_ops ibmvnic_netdev_ops = {
.ndo_set_rx_mode = ibmvnic_set_multi,
.ndo_set_mac_address = ibmvnic_set_mac,
.ndo_validate_addr = eth_validate_addr,
- .ndo_change_mtu = ibmvnic_change_mtu,
.ndo_tx_timeout = ibmvnic_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ibmvnic_netpoll_controller,
@@ -2638,10 +2626,12 @@ static void handle_query_cap_rsp(union ibmvnic_crq *crq,
break;
case MIN_MTU:
adapter->min_mtu = be64_to_cpu(crq->query_capability.number);
+ netdev->min_mtu = adapter->min_mtu;
netdev_dbg(netdev, "min_mtu = %lld\n", adapter->min_mtu);
break;
case MAX_MTU:
adapter->max_mtu = be64_to_cpu(crq->query_capability.number);
+ netdev->max_mtu = adapter->max_mtu;
netdev_dbg(netdev, "max_mtu = %lld\n", adapter->max_mtu);
break;
case MAX_MULTICAST_FILTERS:
@@ -3654,6 +3644,8 @@ static void handle_crq_init_rsp(struct work_struct *work)
goto task_failed;

netdev->real_num_tx_queues = adapter->req_tx_queues;
+ netdev->min_mtu = adapter->min_mtu;
+ netdev->max_mtu = adapter->max_mtu;

if (adapter->failover) {
adapter->failover = false;
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 836ebd8..f9fcab5 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -2357,14 +2357,6 @@ jme_change_mtu(struct net_device *netdev, int new_mtu)
{
struct jme_adapter *jme = netdev_priv(netdev);

- if (new_mtu == jme->old_mtu)
- return 0;
-
- if (((new_mtu + ETH_HLEN) > MAX_ETHERNET_JUMBO_PACKET_SIZE) ||
- ((new_mtu) < IPV6_MIN_MTU))
- return -EINVAL;
-
-
netdev->mtu = new_mtu;
netdev_update_features(netdev);

@@ -3063,6 +3055,10 @@ jme_init_one(struct pci_dev *pdev,
if (using_dac)
netdev->features |= NETIF_F_HIGHDMA;

+ /* MTU range: 1280 - 9202*/
+ netdev->min_mtu = IPV6_MIN_MTU;
+ netdev->max_mtu = MAX_ETHERNET_JUMBO_PACKET_SIZE - ETH_HLEN;
+
SET_NETDEV_DEV(netdev, &pdev->dev);
pci_set_drvdata(pdev, netdev);

diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 18e6bb6..68675d8 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2585,9 +2585,6 @@ static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);

- if (new_mtu < 64 || new_mtu > 9500)
- return -EINVAL;
-
dev->mtu = new_mtu;
mv643xx_eth_recalc_skb_size(mp);
tx_set_rate(mp, 1000000000, 16777216);
@@ -3206,6 +3203,10 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
dev->priv_flags |= IFF_UNICAST_FLT;
dev->gso_max_segs = MV643XX_MAX_TSO_SEGS;

+ /* MTU range: 64 - 9500 */
+ dev->min_mtu = 64;
+ dev->max_mtu = 9500;
+
SET_NETDEV_DEV(dev, &pdev->dev);

if (mp->shared->win_protect)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 99805fd..6d8cb22 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -2284,6 +2284,9 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
dev->hw_features |= NETIF_F_HW_TC;

+ dev->min_mtu = 0;
+ dev->max_mtu = ETH_MAX_MTU;
+
/* Each packet needs to have a Tx header (metadata) on top all other
* headers.
*/
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index c0c23e2..66af63d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -994,6 +994,9 @@ static int mlxsw_sx_port_create(struct mlxsw_sx *mlxsw_sx, u8 local_port)
dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_LLTX | NETIF_F_SG |
NETIF_F_VLAN_CHALLENGED;

+ dev->min_mtu = 0;
+ dev->max_mtu = ETH_MAX_MTU;
+
/* Each packet needs to have a Tx header (metadata) on top all other
* headers.
*/
diff --git a/drivers/net/ethernet/natsemi/ns83820.c b/drivers/net/ethernet/natsemi/ns83820.c
index 569ade6..a34631e 100644
--- a/drivers/net/ethernet/natsemi/ns83820.c
+++ b/drivers/net/ethernet/natsemi/ns83820.c
@@ -1679,14 +1679,6 @@ static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
}
}

-static int ns83820_change_mtu(struct net_device *ndev, int new_mtu)
-{
- if (new_mtu > RX_BUF_SIZE)
- return -EINVAL;
- ndev->mtu = new_mtu;
- return 0;
-}
-
static void ns83820_set_multicast(struct net_device *ndev)
{
struct ns83820 *dev = PRIV(ndev);
@@ -1933,7 +1925,6 @@ static const struct net_device_ops netdev_ops = {
.ndo_stop = ns83820_stop,
.ndo_start_xmit = ns83820_hard_start_xmit,
.ndo_get_stats = ns83820_get_stats,
- .ndo_change_mtu = ns83820_change_mtu,
.ndo_set_rx_mode = ns83820_set_multicast,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
@@ -2190,6 +2181,8 @@ static int ns83820_init_one(struct pci_dev *pci_dev,
ndev->features |= NETIF_F_SG;
ndev->features |= NETIF_F_IP_CSUM;

+ ndev->min_mtu = 0;
+
#ifdef NS83820_VLAN_ACCEL_SUPPORT
/* We also support hardware vlan acceleration */
ndev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
index 2b10f1b..a996801 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
@@ -987,20 +987,8 @@ int netxen_send_lro_cleanup(struct netxen_adapter *adapter)
int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
- int max_mtu;
int rc = 0;

- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- max_mtu = P3_MAX_MTU;
- else
- max_mtu = P2_MAX_MTU;
-
- if (mtu > max_mtu) {
- printk(KERN_ERR "%s: mtu > %d bytes unsupported\n",
- netdev->name, max_mtu);
- return -EINVAL;
- }
-
if (adapter->set_mtu)
rc = adapter->set_mtu(adapter, mtu);

diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 7a0281a..561fb94 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -1572,6 +1572,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->physical_port = i;
}

+ /* MTU range: 0 - 8000 (P2) or 9600 (P3) */
+ netdev->min_mtu = 0;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ netdev->max_mtu = P3_MAX_MTU;
+ else
+ netdev->max_mtu = P2_MAX_MTU;
+
netxen_nic_clear_stats(adapter);

err = netxen_setup_intr(adapter);
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index fd4a8e4..1409412 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -4788,6 +4788,13 @@ static int qlge_probe(struct pci_dev *pdev,
ndev->ethtool_ops = &qlge_ethtool_ops;
ndev->watchdog_timeo = 10 * HZ;

+ /* MTU range: this driver only supports 1500 or 9000, so this only
+ * filters out values above or below, and we'll rely on
+ * qlge_change_mtu to make sure only 1500 or 9000 are allowed
+ */
+ ndev->min_mtu = ETH_DATA_LEN;
+ ndev->max_mtu = 9000;
+
err = register_netdev(ndev);
if (err) {
dev_err(&pdev->dev, "net device registration failed.\n");
diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c
index 9bf3b2b..e4e1925 100644
--- a/drivers/net/ethernet/qualcomm/emac/emac.c
+++ b/drivers/net/ethernet/qualcomm/emac/emac.c
@@ -239,15 +239,8 @@ static void emac_rx_mode_set(struct net_device *netdev)
/* Change the Maximum Transfer Unit (MTU) */
static int emac_change_mtu(struct net_device *netdev, int new_mtu)
{
- unsigned int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
struct emac_adapter *adpt = netdev_priv(netdev);

- if ((max_frame < EMAC_MIN_ETH_FRAME_SIZE) ||
- (max_frame > EMAC_MAX_ETH_FRAME_SIZE)) {
- netdev_err(adpt->netdev, "error: invalid MTU setting\n");
- return -EINVAL;
- }
-
netif_info(adpt, hw, adpt->netdev,
"changing MTU from %d to %d\n", netdev->mtu,
new_mtu);
@@ -679,6 +672,12 @@ static int emac_probe(struct platform_device *pdev)
netdev->vlan_features |= NETIF_F_SG | NETIF_F_HW_CSUM |
NETIF_F_TSO | NETIF_F_TSO6;

+ /* MTU range: 46 - 9194 */
+ netdev->min_mtu = EMAC_MIN_ETH_FRAME_SIZE -
+ (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
+ netdev->max_mtu = EMAC_MAX_ETH_FRAME_SIZE -
+ (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
+
INIT_WORK(&adpt->work_thread, emac_work_thread);

/* Initialize queues */
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index c688d68..c9c8a3b 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1034,9 +1034,6 @@ static int axienet_change_mtu(struct net_device *ndev, int new_mtu)
XAE_TRL_SIZE) > lp->rxmem)
return -EINVAL;

- if ((new_mtu > XAE_JUMBO_MTU) || (new_mtu < 64))
- return -EINVAL;
-
ndev->mtu = new_mtu;

return 0;
@@ -1475,6 +1472,10 @@ static int axienet_probe(struct platform_device *pdev)
ndev->netdev_ops = &axienet_netdev_ops;
ndev->ethtool_ops = &axienet_ethtool_ops;

+ /* MTU range: 64 - 9000 */
+ ndev->min_mtu = 64;
+ ndev->max_mtu = XAE_JUMBO_MTU;
+
lp = netdev_priv(ndev);
lp->ndev = ndev;
lp->dev = &pdev->dev;
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index 864d6f2..3e5185e 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -36,6 +36,7 @@
#define ETH_FCS_LEN 4 /* Octets in the FCS */

#define ETH_MIN_MTU 68 /* Min IPv4 MTU per RFC791 */
+#define ETH_MAX_MTU 0xFFFFU /* 65535, same as IP_MAX_MTU */

/*
* These are the defined Ethernet Protocol ID's.
--
2.10.0

2016-10-20 17:55:53

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next v2 4/9] net: use core MTU range checking in WAN drivers

- set min/max_mtu in all hdlc drivers, remove hdlc_change_mtu
- sent max_mtu in lec driver, remove lec_change_mtu
- set min/max_mtu in x25_asy driver

CC: [email protected]
CC: Krzysztof Halasa <[email protected]>
CC: Krzysztof Halasa <[email protected]>
CC: Jan "Yenya" Kasprzak <[email protected]>
CC: Francois Romieu <[email protected]>
CC: Kevin Curtis <[email protected]>
CC: Zhao Qiang <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/char/pcmcia/synclink_cs.c | 1 -
drivers/net/wan/c101.c | 1 -
drivers/net/wan/cosa.c | 1 -
drivers/net/wan/dscc4.c | 1 -
drivers/net/wan/farsync.c | 1 -
drivers/net/wan/fsl_ucc_hdlc.c | 1 -
drivers/net/wan/hdlc.c | 11 ++---------
drivers/net/wan/hdlc_fr.c | 3 ++-
drivers/net/wan/hostess_sv11.c | 1 -
drivers/net/wan/ixp4xx_hss.c | 1 -
drivers/net/wan/lmc/lmc_main.c | 1 -
drivers/net/wan/n2.c | 1 -
drivers/net/wan/pc300too.c | 1 -
drivers/net/wan/pci200syn.c | 1 -
drivers/net/wan/sealevel.c | 1 -
drivers/net/wan/wanxl.c | 1 -
drivers/net/wan/x25_asy.c | 5 ++---
drivers/tty/synclink.c | 1 -
drivers/tty/synclink_gt.c | 1 -
drivers/tty/synclinkmp.c | 1 -
include/linux/hdlc.h | 2 --
net/atm/lec.c | 11 +----------
22 files changed, 7 insertions(+), 42 deletions(-)

diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index d28922d..a7dd5f4 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -4248,7 +4248,6 @@ static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size)
static const struct net_device_ops hdlcdev_ops = {
.ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlcdev_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout,
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index 09a5075..2371e07 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -302,7 +302,6 @@ static void c101_destroy_card(card_t *card)
static const struct net_device_ops c101_ops = {
.ndo_open = c101_open,
.ndo_stop = c101_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = c101_ioctl,
};
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index b87fe0a..087eb26 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -432,7 +432,6 @@ module_exit(cosa_exit);
static const struct net_device_ops cosa_ops = {
.ndo_open = cosa_net_open,
.ndo_stop = cosa_net_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = cosa_net_ioctl,
.ndo_tx_timeout = cosa_net_timeout,
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 6292259..7351e54 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -887,7 +887,6 @@ static inline int dscc4_set_quartz(struct dscc4_dev_priv *dpriv, int hz)
static const struct net_device_ops dscc4_ops = {
.ndo_open = dscc4_open,
.ndo_stop = dscc4_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = dscc4_ioctl,
.ndo_tx_timeout = dscc4_tx_timeout,
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 3c9cbf9..03696d3 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -2394,7 +2394,6 @@ fst_init_card(struct fst_card_info *card)
static const struct net_device_ops fst_ops = {
.ndo_open = fst_open,
.ndo_stop = fst_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = fst_ioctl,
.ndo_tx_timeout = fst_tx_timeout,
diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
index 6564753..e38ce4d 100644
--- a/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/drivers/net/wan/fsl_ucc_hdlc.c
@@ -992,7 +992,6 @@ static const struct dev_pm_ops uhdlc_pm_ops = {
static const struct net_device_ops uhdlc_ops = {
.ndo_open = uhdlc_open,
.ndo_stop = uhdlc_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = uhdlc_ioctl,
};
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index 9bd4aa8..7221a53 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -46,14 +46,6 @@ static const char* version = "HDLC support module revision 1.22";

static struct hdlc_proto *first_proto;

-int hdlc_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *p, struct net_device *orig_dev)
{
@@ -237,6 +229,8 @@ static void hdlc_setup_dev(struct net_device *dev)
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
dev->priv_flags = IFF_WAN_HDLC;
dev->mtu = HDLC_MAX_MTU;
+ dev->min_mtu = 68;
+ dev->max_mtu = HDLC_MAX_MTU;
dev->type = ARPHRD_RAWHDLC;
dev->hard_header_len = 16;
dev->addr_len = 0;
@@ -353,7 +347,6 @@ MODULE_AUTHOR("Krzysztof Halasa <[email protected]>");
MODULE_DESCRIPTION("HDLC support module");
MODULE_LICENSE("GPL v2");

-EXPORT_SYMBOL(hdlc_change_mtu);
EXPORT_SYMBOL(hdlc_start_xmit);
EXPORT_SYMBOL(hdlc_open);
EXPORT_SYMBOL(hdlc_close);
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index b6e0cfb..eb91528 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1053,7 +1053,6 @@ static void pvc_setup(struct net_device *dev)
static const struct net_device_ops pvc_ops = {
.ndo_open = pvc_open,
.ndo_stop = pvc_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = pvc_xmit,
.ndo_do_ioctl = pvc_ioctl,
};
@@ -1096,6 +1095,8 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
}
dev->netdev_ops = &pvc_ops;
dev->mtu = HDLC_MAX_MTU;
+ dev->min_mtu = 68;
+ dev->max_mtu = HDLC_MAX_MTU;
dev->priv_flags |= IFF_NO_QUEUE;
dev->ml_priv = pvc;

diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index 3d74166..dd6bb33 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -180,7 +180,6 @@ static int hostess_attach(struct net_device *dev, unsigned short encoding,
static const struct net_device_ops hostess_ops = {
.ndo_open = hostess_open,
.ndo_stop = hostess_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hostess_ioctl,
};
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index e7bbdb7..6a505c2 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -1321,7 +1321,6 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static const struct net_device_ops hss_hdlc_ops = {
.ndo_open = hss_hdlc_open,
.ndo_stop = hss_hdlc_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hss_hdlc_ioctl,
};
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 299140c..001b779 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -808,7 +808,6 @@ static int lmc_attach(struct net_device *dev, unsigned short encoding,
static const struct net_device_ops lmc_ops = {
.ndo_open = lmc_open,
.ndo_stop = lmc_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = lmc_ioctl,
.ndo_tx_timeout = lmc_driver_timeout,
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index 315bf09..c8f4517 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -330,7 +330,6 @@ static void n2_destroy_card(card_t *card)
static const struct net_device_ops n2_ops = {
.ndo_open = n2_open,
.ndo_stop = n2_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = n2_ioctl,
};
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c
index db36385..e1dd1ec 100644
--- a/drivers/net/wan/pc300too.c
+++ b/drivers/net/wan/pc300too.c
@@ -291,7 +291,6 @@ static void pc300_pci_remove_one(struct pci_dev *pdev)
static const struct net_device_ops pc300_ops = {
.ndo_open = pc300_open,
.ndo_stop = pc300_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = pc300_ioctl,
};
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index e845562..4e437c5 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -270,7 +270,6 @@ static void pci200_pci_remove_one(struct pci_dev *pdev)
static const struct net_device_ops pci200_ops = {
.ndo_open = pci200_open,
.ndo_stop = pci200_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = pci200_ioctl,
};
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 27860b4..fbb5aa2 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -174,7 +174,6 @@ static int sealevel_attach(struct net_device *dev, unsigned short encoding,
static const struct net_device_ops sealevel_ops = {
.ndo_open = sealevel_open,
.ndo_stop = sealevel_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = sealevel_ioctl,
};
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index a20d688..0c73175 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -551,7 +551,6 @@ static void wanxl_pci_remove_one(struct pci_dev *pdev)
static const struct net_device_ops wanxl_ops = {
.ndo_open = wanxl_open,
.ndo_stop = wanxl_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = wanxl_ioctl,
.ndo_get_stats = wanxl_get_stats,
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 1bc5e93..878b05d 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -124,9 +124,6 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
unsigned char *xbuff, *rbuff;
int len;

- if (newmtu > 65534)
- return -EINVAL;
-
len = 2 * newmtu;
xbuff = kmalloc(len + 4, GFP_ATOMIC);
rbuff = kmalloc(len + 4, GFP_ATOMIC);
@@ -751,6 +748,8 @@ static void x25_asy_setup(struct net_device *dev)
*/

dev->mtu = SL_MTU;
+ dev->min_mtu = 0;
+ dev->max_mtu = 65534;
dev->netdev_ops = &x25_asy_netdev_ops;
dev->watchdog_timeo = HZ*20;
dev->hard_header_len = 0;
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c
index c13e27e..415885c 100644
--- a/drivers/tty/synclink.c
+++ b/drivers/tty/synclink.c
@@ -7973,7 +7973,6 @@ static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size)
static const struct net_device_ops hdlcdev_ops = {
.ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlcdev_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout,
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index 7aca2d4..8267bcf 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -1768,7 +1768,6 @@ static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
static const struct net_device_ops hdlcdev_ops = {
.ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlcdev_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout,
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c
index dec1565..d66620f 100644
--- a/drivers/tty/synclinkmp.c
+++ b/drivers/tty/synclinkmp.c
@@ -1887,7 +1887,6 @@ static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
static const struct net_device_ops hdlcdev_ops = {
.ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close,
- .ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlcdev_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout,
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h
index e31bcd4..97585d9 100644
--- a/include/linux/hdlc.h
+++ b/include/linux/hdlc.h
@@ -93,8 +93,6 @@ static __inline__ void debug_frame(const struct sk_buff *skb)
int hdlc_open(struct net_device *dev);
/* Must be called by hardware driver when HDLC device is being closed */
void hdlc_close(struct net_device *dev);
-/* May be used by hardware driver */
-int hdlc_change_mtu(struct net_device *dev, int new_mtu);
/* Must be pointed to by hw driver's dev->netdev_ops->ndo_start_xmit */
netdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev);

diff --git a/net/atm/lec.c b/net/atm/lec.c
index 5d26938..779b3fa 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -544,15 +544,6 @@ send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
return 0;
}

-/* shamelessly stolen from drivers/net/net_init.c */
-static int lec_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > 18190))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static void lec_set_multicast_list(struct net_device *dev)
{
/*
@@ -565,7 +556,6 @@ static const struct net_device_ops lec_netdev_ops = {
.ndo_open = lec_open,
.ndo_stop = lec_close,
.ndo_start_xmit = lec_start_xmit,
- .ndo_change_mtu = lec_change_mtu,
.ndo_tx_timeout = lec_tx_timeout,
.ndo_set_rx_mode = lec_set_multicast_list,
};
@@ -742,6 +732,7 @@ static int lecd_attach(struct atm_vcc *vcc, int arg)
if (!dev_lec[i])
return -ENOMEM;
dev_lec[i]->netdev_ops = &lec_netdev_ops;
+ dev_lec[i]->max_mtu = 18190;
snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
if (register_netdev(dev_lec[i])) {
free_netdev(dev_lec[i]);
--
2.10.0

2016-10-20 17:56:05

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next v2 7/9] net: use core MTU range checking in misc drivers

firewire-net:
- set min/max_mtu
- remove fwnet_change_mtu

nes:
- set max_mtu
- clean up nes_netdev_change_mtu

xpnet:
- set min/max_mtu
- remove xpnet_dev_change_mtu

hippi:
- set min/max_mtu
- remove hippi_change_mtu

batman-adv:
- set max_mtu
- remove batadv_interface_change_mtu
- initialization is a little async, not 100% certain that max_mtu is set
in the optimal place, don't have hardware to test with

rionet:
- set min/max_mtu
- remove rionet_change_mtu

slip:
- set min/max_mtu
- streamline sl_change_mtu

um/net_kern:
- remove pointless ndo_change_mtu

hsi/clients/ssi_protocol:
- use core MTU range checking
- remove now redundant ssip_pn_set_mtu

ipoib:
- set a default max MTU value
- Note: ipoib's actual max MTU can vary, depending on if the device is in
connected mode or not, so we'll just set the max_mtu value to the max
possible, and let the ndo_change_mtu function continue to validate any new
MTU change requests with checks for CM or not. Note that ipoib has no
min_mtu set, and thus, the network core's mtu > 0 check is the only lower
bounds here.

mptlan:
- use net core MTU range checking
- remove now redundant mpt_lan_change_mtu

fddi:
- min_mtu = 21, max_mtu = 4470
- remove now redundant fddi_change_mtu (including export)

fjes:
- min_mtu = 8192, max_mtu = 65536
- The max_mtu value is actually one over IP_MAX_MTU here, but the idea is to
get past the core net MTU range checks so fjes_change_mtu can validate a
new MTU against what it supports (see fjes_support_mtu in fjes_hw.c)

hsr:
- min_mtu = 0 (calls ether_setup, max_mtu is 1500)

f_phonet:
- min_mtu = 6, max_mtu = 65541

u_ether:
- min_mtu = 14, max_mtu = 15412

phonet/pep-gprs:
- min_mtu = 576, max_mtu = 65530
- remove redundant gprs_set_mtu

CC: [email protected]
CC: [email protected]
CC: Stefan Richter <[email protected]>
CC: Faisal Latif <[email protected]>
CC: [email protected]
CC: Cliff Whickman <[email protected]>
CC: Robin Holt <[email protected]>
CC: Jes Sorensen <[email protected]>
CC: Marek Lindner <[email protected]>
CC: Simon Wunderlich <[email protected]>
CC: Antonio Quartulli <[email protected]>
CC: Sathya Prakash <[email protected]>
CC: Chaitra P B <[email protected]>
CC: Suganath Prabu Subramani <[email protected]>
CC: [email protected]
CC: Sebastian Reichel <[email protected]>
CC: Felipe Balbi <[email protected]>
CC: Arvid Brodin <[email protected]>
CC: Remi Denis-Courmont <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
arch/um/drivers/net_kern.c | 8 --------
drivers/firewire/net.c | 18 ++++--------------
drivers/hsi/clients/ssi_protocol.c | 14 ++++----------
drivers/infiniband/hw/nes/nes.c | 1 -
drivers/infiniband/hw/nes/nes.h | 4 ++--
drivers/infiniband/hw/nes/nes_nic.c | 10 +++-------
drivers/infiniband/ulp/ipoib/ipoib_main.c | 1 +
drivers/message/fusion/mptlan.c | 15 ++++-----------
drivers/misc/sgi-xp/xpnet.c | 21 ++++-----------------
drivers/net/fddi/skfp/skfddi.c | 1 -
drivers/net/fjes/fjes_main.c | 2 ++
drivers/net/hippi/rrunner.c | 1 -
drivers/net/rionet.c | 15 +++------------
drivers/net/slip/slip.c | 11 +++++------
drivers/usb/gadget/function/f_phonet.c | 11 ++---------
drivers/usb/gadget/function/u_ether.c | 14 ++++----------
include/linux/fddidevice.h | 1 -
include/linux/hippidevice.h | 1 -
net/802/fddi.c | 11 ++---------
net/802/hippi.c | 14 ++------------
net/batman-adv/soft-interface.c | 13 +------------
net/hsr/hsr_device.c | 1 +
net/phonet/pep-gprs.c | 12 ++----------
23 files changed, 46 insertions(+), 154 deletions(-)

diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 2cd5b68..1669240 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -256,13 +256,6 @@ static void uml_net_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}

-static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
-{
- dev->mtu = new_mtu;
-
- return 0;
-}
-
#ifdef CONFIG_NET_POLL_CONTROLLER
static void uml_net_poll_controller(struct net_device *dev)
{
@@ -374,7 +367,6 @@ static const struct net_device_ops uml_netdev_ops = {
.ndo_set_rx_mode = uml_net_set_multicast_list,
.ndo_tx_timeout = uml_net_tx_timeout,
.ndo_set_mac_address = eth_mac_addr,
- .ndo_change_mtu = uml_net_change_mtu,
.ndo_validate_addr = eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = uml_net_poll_controller,
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 309311b..8430222 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -1349,15 +1349,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
return NETDEV_TX_OK;
}

-static int fwnet_change_mtu(struct net_device *net, int new_mtu)
-{
- if (new_mtu < 68)
- return -EINVAL;
-
- net->mtu = new_mtu;
- return 0;
-}
-
static const struct ethtool_ops fwnet_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
@@ -1366,7 +1357,6 @@ static const struct net_device_ops fwnet_netdev_ops = {
.ndo_open = fwnet_open,
.ndo_stop = fwnet_stop,
.ndo_start_xmit = fwnet_tx,
- .ndo_change_mtu = fwnet_change_mtu,
};

static void fwnet_init_dev(struct net_device *net)
@@ -1435,7 +1425,6 @@ static int fwnet_probe(struct fw_unit *unit,
struct net_device *net;
bool allocated_netdev = false;
struct fwnet_device *dev;
- unsigned max_mtu;
int ret;
union fwnet_hwaddr *ha;

@@ -1478,9 +1467,10 @@ static int fwnet_probe(struct fw_unit *unit,
* Use the RFC 2734 default 1500 octets or the maximum payload
* as initial MTU
*/
- max_mtu = (1 << (card->max_receive + 1))
- - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
- net->mtu = min(1500U, max_mtu);
+ net->max_mtu = (1 << (card->max_receive + 1))
+ - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
+ net->mtu = min(1500U, net->max_mtu);
+ net->min_mtu = ETH_MIN_MTU;

/* Set our hardware address while we're at it */
ha = (union fwnet_hwaddr *)net->dev_addr;
diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c
index 6031cd1..7ef8196 100644
--- a/drivers/hsi/clients/ssi_protocol.c
+++ b/drivers/hsi/clients/ssi_protocol.c
@@ -960,15 +960,6 @@ static int ssip_pn_stop(struct net_device *dev)
return 0;
}

-static int ssip_pn_set_mtu(struct net_device *dev, int new_mtu)
-{
- if (new_mtu > SSIP_MAX_MTU || new_mtu < PHONET_MIN_MTU)
- return -EINVAL;
- dev->mtu = new_mtu;
-
- return 0;
-}
-
static void ssip_xmit_work(struct work_struct *work)
{
struct ssi_protocol *ssi =
@@ -1060,7 +1051,6 @@ static const struct net_device_ops ssip_pn_ops = {
.ndo_open = ssip_pn_open,
.ndo_stop = ssip_pn_stop,
.ndo_start_xmit = ssip_pn_xmit,
- .ndo_change_mtu = ssip_pn_set_mtu,
};

static void ssip_pn_setup(struct net_device *dev)
@@ -1136,6 +1126,10 @@ static int ssi_protocol_probe(struct device *dev)
goto out1;
}

+ /* MTU range: 6 - 65535 */
+ ssi->netdev->min_mtu = PHONET_MIN_MTU;
+ ssi->netdev->max_mtu = SSIP_MAX_MTU;
+
SET_NETDEV_DEV(ssi->netdev, dev);
netif_carrier_off(ssi->netdev);
err = register_netdev(ssi->netdev);
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 35cbb17..2baa45a 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -65,7 +65,6 @@ MODULE_DESCRIPTION("NetEffect RNIC Low-level iWARP Driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_VERSION);

-int max_mtu = 9000;
int interrupt_mod_interval = 0;

/* Interoperability */
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index e7430c9..85acd08 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -83,6 +83,8 @@
#define NES_FIRST_QPN 64
#define NES_SW_CONTEXT_ALIGN 1024

+#define NES_MAX_MTU 9000
+
#define NES_NIC_MAX_NICS 16
#define NES_MAX_ARP_TABLE_SIZE 4096

@@ -169,8 +171,6 @@ do { \
#include "nes_cm.h"
#include "nes_mgt.h"

-extern int max_mtu;
-#define max_frame_len (max_mtu+ETH_HLEN)
extern int interrupt_mod_interval;
extern int nes_if_count;
extern int mpa_version;
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 2b27d13..7f8597d 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -981,20 +981,16 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
{
struct nes_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev;
- int ret = 0;
u8 jumbomode = 0;
u32 nic_active;
u32 nic_active_bit;
u32 uc_all_active;
u32 mc_all_active;

- if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu))
- return -EINVAL;
-
netdev->mtu = new_mtu;
nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN;

- if (netdev->mtu > 1500) {
+ if (netdev->mtu > ETH_DATA_LEN) {
jumbomode=1;
}
nes_nic_init_timer_defaults(nesdev, jumbomode);
@@ -1020,7 +1016,7 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
}

- return ret;
+ return 0;
}


@@ -1658,7 +1654,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,

netdev->watchdog_timeo = NES_TX_TIMEOUT;
netdev->irq = nesdev->pcidev->irq;
- netdev->mtu = ETH_DATA_LEN;
+ netdev->max_mtu = NES_MAX_MTU;
netdev->hard_header_len = ETH_HLEN;
netdev->addr_len = ETH_ALEN;
netdev->type = ARPHRD_ETHER;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index cc05921..ae5d7cd 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -2017,6 +2017,7 @@ static struct net_device *ipoib_add_port(const char *format,
/* MTU will be reset when mcast join happens */
priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu);
priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu;
+ priv->dev->max_mtu = IPOIB_CM_MTU;

priv->dev->neigh_priv_len = sizeof(struct ipoib_neigh);

diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 6955c9e..55dd71b 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -549,16 +549,6 @@ mpt_lan_close(struct net_device *dev)
}

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int
-mpt_lan_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < MPT_LAN_MIN_MTU) || (new_mtu > MPT_LAN_MAX_MTU))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* Tx timeout handler. */
static void
mpt_lan_tx_timeout(struct net_device *dev)
@@ -1304,7 +1294,6 @@ static const struct net_device_ops mpt_netdev_ops = {
.ndo_open = mpt_lan_open,
.ndo_stop = mpt_lan_close,
.ndo_start_xmit = mpt_lan_sdu_send,
- .ndo_change_mtu = mpt_lan_change_mtu,
.ndo_tx_timeout = mpt_lan_tx_timeout,
};

@@ -1375,6 +1364,10 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
dev->netdev_ops = &mpt_netdev_ops;
dev->watchdog_timeo = MPT_LAN_TX_TIMEOUT;

+ /* MTU range: 96 - 65280 */
+ dev->min_mtu = MPT_LAN_MIN_MTU;
+ dev->max_mtu = MPT_LAN_MAX_MTU;
+
dlprintk((KERN_INFO MYNAM ": Finished registering dev "
"and setting initial values\n"));

diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 557f978..0c26eaf 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -118,6 +118,8 @@ static DEFINE_SPINLOCK(xpnet_broadcast_lock);
* now, the default is 64KB.
*/
#define XPNET_MAX_MTU (0x800000UL - L1_CACHE_BYTES)
+/* 68 comes from min TCP+IP+MAC header */
+#define XPNET_MIN_MTU 68
/* 32KB has been determined to be the ideal */
#define XPNET_DEF_MTU (0x8000UL)

@@ -330,22 +332,6 @@ xpnet_dev_stop(struct net_device *dev)
return 0;
}

-static int
-xpnet_dev_change_mtu(struct net_device *dev, int new_mtu)
-{
- /* 68 comes from min TCP+IP+MAC header */
- if ((new_mtu < 68) || (new_mtu > XPNET_MAX_MTU)) {
- dev_err(xpnet, "ifconfig %s mtu %d failed; value must be "
- "between 68 and %ld\n", dev->name, new_mtu,
- XPNET_MAX_MTU);
- return -EINVAL;
- }
-
- dev->mtu = new_mtu;
- dev_dbg(xpnet, "ifconfig %s mtu set to %d\n", dev->name, new_mtu);
- return 0;
-}
-
/*
* Notification that the other end has received the message and
* DMA'd the skb information. At this point, they are done with
@@ -519,7 +505,6 @@ static const struct net_device_ops xpnet_netdev_ops = {
.ndo_open = xpnet_dev_open,
.ndo_stop = xpnet_dev_stop,
.ndo_start_xmit = xpnet_dev_hard_start_xmit,
- .ndo_change_mtu = xpnet_dev_change_mtu,
.ndo_tx_timeout = xpnet_dev_tx_timeout,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
@@ -555,6 +540,8 @@ xpnet_init(void)

xpnet_device->netdev_ops = &xpnet_netdev_ops;
xpnet_device->mtu = XPNET_DEF_MTU;
+ xpnet_device->min_mtu = XPNET_MIN_MTU;
+ xpnet_device->max_mtu = XPNET_MAX_MTU;

/*
* Multicast assumes the LSB of the first octet is set for multicast
diff --git a/drivers/net/fddi/skfp/skfddi.c b/drivers/net/fddi/skfp/skfddi.c
index 51acc6d..3a63918 100644
--- a/drivers/net/fddi/skfp/skfddi.c
+++ b/drivers/net/fddi/skfp/skfddi.c
@@ -166,7 +166,6 @@ static const struct net_device_ops skfp_netdev_ops = {
.ndo_stop = skfp_close,
.ndo_start_xmit = skfp_send_pkt,
.ndo_get_stats = skfp_ctl_get_stats,
- .ndo_change_mtu = fddi_change_mtu,
.ndo_set_rx_mode = skfp_ctl_set_multicast_list,
.ndo_set_mac_address = skfp_ctl_set_mac_address,
.ndo_do_ioctl = skfp_ioctl,
diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c
index f36eb4a..b77e4ecf 100644
--- a/drivers/net/fjes/fjes_main.c
+++ b/drivers/net/fjes/fjes_main.c
@@ -1316,6 +1316,8 @@ static void fjes_netdev_setup(struct net_device *netdev)
netdev->netdev_ops = &fjes_netdev_ops;
fjes_set_ethtool_ops(netdev);
netdev->mtu = fjes_support_mtu[3];
+ netdev->min_mtu = fjes_support_mtu[0];
+ netdev->max_mtu = fjes_support_mtu[3];
netdev->flags |= IFF_BROADCAST;
netdev->features |= NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER;
}
diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c
index 95c0b45..f5a9728 100644
--- a/drivers/net/hippi/rrunner.c
+++ b/drivers/net/hippi/rrunner.c
@@ -68,7 +68,6 @@ static const struct net_device_ops rr_netdev_ops = {
.ndo_stop = rr_close,
.ndo_do_ioctl = rr_ioctl,
.ndo_start_xmit = rr_start_xmit,
- .ndo_change_mtu = hippi_change_mtu,
.ndo_set_mac_address = hippi_mac_addr,
};

diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index a31f461..300bb14 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -466,17 +466,6 @@ static void rionet_set_msglevel(struct net_device *ndev, u32 value)
rnet->msg_enable = value;
}

-static int rionet_change_mtu(struct net_device *ndev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > RIONET_MAX_MTU)) {
- printk(KERN_ERR "%s: Invalid MTU size %d\n",
- ndev->name, new_mtu);
- return -EINVAL;
- }
- ndev->mtu = new_mtu;
- return 0;
-}
-
static const struct ethtool_ops rionet_ethtool_ops = {
.get_drvinfo = rionet_get_drvinfo,
.get_msglevel = rionet_get_msglevel,
@@ -488,7 +477,6 @@ static const struct net_device_ops rionet_netdev_ops = {
.ndo_open = rionet_open,
.ndo_stop = rionet_close,
.ndo_start_xmit = rionet_start_xmit,
- .ndo_change_mtu = rionet_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
};
@@ -525,6 +513,9 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)

ndev->netdev_ops = &rionet_netdev_ops;
ndev->mtu = RIONET_MAX_MTU;
+ /* MTU range: 68 - 4082 */
+ ndev->min_mtu = ETH_MIN_MTU;
+ ndev->max_mtu = RIONET_MAX_MTU;
ndev->features = NETIF_F_LLTX;
SET_NETDEV_DEV(ndev, &mport->dev);
ndev->ethtool_ops = &rionet_ethtool_ops;
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index 9ed6d1c..7e933d8 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -561,12 +561,7 @@ static int sl_change_mtu(struct net_device *dev, int new_mtu)
{
struct slip *sl = netdev_priv(dev);

- if (new_mtu < 68 || new_mtu > 65534)
- return -EINVAL;
-
- if (new_mtu != dev->mtu)
- return sl_realloc_bufs(sl, new_mtu);
- return 0;
+ return sl_realloc_bufs(sl, new_mtu);
}

/* Netdevice get statistics request */
@@ -663,6 +658,10 @@ static void sl_setup(struct net_device *dev)
dev->addr_len = 0;
dev->tx_queue_len = 10;

+ /* MTU range: 68 - 65534 */
+ dev->min_mtu = 68;
+ dev->max_mtu = 65534;
+
/* New-style flags. */
dev->flags = IFF_NOARP|IFF_POINTOPOINT|IFF_MULTICAST;
}
diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c
index 0473d61..b4058f0 100644
--- a/drivers/usb/gadget/function/f_phonet.c
+++ b/drivers/usb/gadget/function/f_phonet.c
@@ -261,19 +261,10 @@ static int pn_net_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}

-static int pn_net_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static const struct net_device_ops pn_netdev_ops = {
.ndo_open = pn_net_open,
.ndo_stop = pn_net_close,
.ndo_start_xmit = pn_net_xmit,
- .ndo_change_mtu = pn_net_mtu,
};

static void pn_net_setup(struct net_device *dev)
@@ -282,6 +273,8 @@ static void pn_net_setup(struct net_device *dev)
dev->type = ARPHRD_PHONET;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
dev->mtu = PHONET_DEV_MTU;
+ dev->min_mtu = PHONET_MIN_MTU;
+ dev->max_mtu = PHONET_MAX_MTU;
dev->hard_header_len = 1;
dev->dev_addr[0] = PN_MEDIA_USB;
dev->addr_len = 1;
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index 9c8c9ed..39a6df1 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -142,15 +142,6 @@ static inline int qlen(struct usb_gadget *gadget, unsigned qmult)

/* NETWORK DRIVER HOOKUP (to the layer above this driver) */

-static int ueth_change_mtu(struct net_device *net, int new_mtu)
-{
- if (new_mtu <= ETH_HLEN || new_mtu > GETHER_MAX_ETH_FRAME_LEN)
- return -ERANGE;
- net->mtu = new_mtu;
-
- return 0;
-}
-
static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
{
struct eth_dev *dev = netdev_priv(net);
@@ -736,7 +727,6 @@ static const struct net_device_ops eth_netdev_ops = {
.ndo_open = eth_open,
.ndo_stop = eth_stop,
.ndo_start_xmit = eth_start_xmit,
- .ndo_change_mtu = ueth_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
};
@@ -799,6 +789,10 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,

net->ethtool_ops = &ops;

+ /* MTU range: 14 - 15412 */
+ net->min_mtu = ETH_HLEN;
+ net->max_mtu = GETHER_MAX_ETH_FRAME_LEN;
+
dev->gadget = g;
SET_NETDEV_DEV(net, &g->dev);
SET_NETDEV_DEVTYPE(net, &gadget_type);
diff --git a/include/linux/fddidevice.h b/include/linux/fddidevice.h
index 9a79f01..32c22cf 100644
--- a/include/linux/fddidevice.h
+++ b/include/linux/fddidevice.h
@@ -26,7 +26,6 @@

#ifdef __KERNEL__
__be16 fddi_type_trans(struct sk_buff *skb, struct net_device *dev);
-int fddi_change_mtu(struct net_device *dev, int new_mtu);
struct net_device *alloc_fddidev(int sizeof_priv);
#endif

diff --git a/include/linux/hippidevice.h b/include/linux/hippidevice.h
index 8ec23fb..402f99e 100644
--- a/include/linux/hippidevice.h
+++ b/include/linux/hippidevice.h
@@ -32,7 +32,6 @@ struct hippi_cb {
};

__be16 hippi_type_trans(struct sk_buff *skb, struct net_device *dev);
-int hippi_change_mtu(struct net_device *dev, int new_mtu);
int hippi_mac_addr(struct net_device *dev, void *p);
int hippi_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p);
struct net_device *alloc_hippi_dev(int sizeof_priv);
diff --git a/net/802/fddi.c b/net/802/fddi.c
index 7d3a0af..6356623 100644
--- a/net/802/fddi.c
+++ b/net/802/fddi.c
@@ -141,15 +141,6 @@ __be16 fddi_type_trans(struct sk_buff *skb, struct net_device *dev)

EXPORT_SYMBOL(fddi_type_trans);

-int fddi_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < FDDI_K_SNAP_HLEN) || (new_mtu > FDDI_K_SNAP_DLEN))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-EXPORT_SYMBOL(fddi_change_mtu);
-
static const struct header_ops fddi_header_ops = {
.create = fddi_header,
};
@@ -161,6 +152,8 @@ static void fddi_setup(struct net_device *dev)
dev->type = ARPHRD_FDDI;
dev->hard_header_len = FDDI_K_SNAP_HLEN+3; /* Assume 802.2 SNAP hdr len + 3 pad bytes */
dev->mtu = FDDI_K_SNAP_DLEN; /* Assume max payload of 802.2 SNAP frame */
+ dev->min_mtu = FDDI_K_SNAP_HLEN;
+ dev->max_mtu = FDDI_K_SNAP_DLEN;
dev->addr_len = FDDI_K_ALEN;
dev->tx_queue_len = 100; /* Long queues on FDDI */
dev->flags = IFF_BROADCAST | IFF_MULTICAST;
diff --git a/net/802/hippi.c b/net/802/hippi.c
index ade1a52..5e4427b 100644
--- a/net/802/hippi.c
+++ b/net/802/hippi.c
@@ -116,18 +116,6 @@ __be16 hippi_type_trans(struct sk_buff *skb, struct net_device *dev)

EXPORT_SYMBOL(hippi_type_trans);

-int hippi_change_mtu(struct net_device *dev, int new_mtu)
-{
- /*
- * HIPPI's got these nice large MTUs.
- */
- if ((new_mtu < 68) || (new_mtu > 65280))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-EXPORT_SYMBOL(hippi_change_mtu);
-
/*
* For HIPPI we will actually use the lower 4 bytes of the hardware
* address as the I-FIELD rather than the actual hardware address.
@@ -174,6 +162,8 @@ static void hippi_setup(struct net_device *dev)
dev->type = ARPHRD_HIPPI;
dev->hard_header_len = HIPPI_HLEN;
dev->mtu = 65280;
+ dev->min_mtu = 68;
+ dev->max_mtu = 65280;
dev->addr_len = HIPPI_ALEN;
dev->tx_queue_len = 25 /* 5 */;
memset(dev->broadcast, 0xFF, HIPPI_ALEN);
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 49e16b6..112679d 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -158,17 +158,6 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
return 0;
}

-static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu)
-{
- /* check ranges */
- if ((new_mtu < 68) || (new_mtu > batadv_hardif_min_mtu(dev)))
- return -EINVAL;
-
- dev->mtu = new_mtu;
-
- return 0;
-}
-
/**
* batadv_interface_set_rx_mode - set the rx mode of a device
* @dev: registered network device to modify
@@ -920,7 +909,6 @@ static const struct net_device_ops batadv_netdev_ops = {
.ndo_vlan_rx_add_vid = batadv_interface_add_vid,
.ndo_vlan_rx_kill_vid = batadv_interface_kill_vid,
.ndo_set_mac_address = batadv_interface_set_mac_addr,
- .ndo_change_mtu = batadv_interface_change_mtu,
.ndo_set_rx_mode = batadv_interface_set_rx_mode,
.ndo_start_xmit = batadv_interface_tx,
.ndo_validate_addr = eth_validate_addr,
@@ -987,6 +975,7 @@ struct net_device *batadv_softif_create(struct net *net, const char *name)
dev_net_set(soft_iface, net);

soft_iface->rtnl_link_ops = &batadv_link_ops;
+ soft_iface->max_mtu = batadv_hardif_min_mtu(soft_iface);

ret = register_netdevice(soft_iface);
if (ret < 0) {
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
index 16737cd..fc65b14 100644
--- a/net/hsr/hsr_device.c
+++ b/net/hsr/hsr_device.c
@@ -398,6 +398,7 @@ void hsr_dev_setup(struct net_device *dev)
random_ether_addr(dev->dev_addr);

ether_setup(dev);
+ dev->min_mtu = 0;
dev->header_ops = &hsr_header_ops;
dev->netdev_ops = &hsr_device_ops;
SET_NETDEV_DEVTYPE(dev, &hsr_type);
diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c
index fa8237f..21c28b5 100644
--- a/net/phonet/pep-gprs.c
+++ b/net/phonet/pep-gprs.c
@@ -217,20 +217,10 @@ static netdev_tx_t gprs_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}

-static int gprs_set_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 576) || (new_mtu > (PHONET_MAX_MTU - 11)))
- return -EINVAL;
-
- dev->mtu = new_mtu;
- return 0;
-}
-
static const struct net_device_ops gprs_netdev_ops = {
.ndo_open = gprs_open,
.ndo_stop = gprs_close,
.ndo_start_xmit = gprs_xmit,
- .ndo_change_mtu = gprs_set_mtu,
};

static void gprs_setup(struct net_device *dev)
@@ -239,6 +229,8 @@ static void gprs_setup(struct net_device *dev)
dev->type = ARPHRD_PHONET_PIPE;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
dev->mtu = GPRS_DEFAULT_MTU;
+ dev->min_mtu = 576;
+ dev->max_mtu = (PHONET_MAX_MTU - 11);
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->tx_queue_len = 10;
--
2.10.0

2016-10-20 17:56:26

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next v2 9/9] ipv4/6: use core net MTU range checking

ipv4/ip_tunnel:
- min_mtu = 68, max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen
- preserve all ndo_change_mtu checks for now to prevent regressions

ipv6/ip6_tunnel:
- min_mtu = 68, max_mtu = 0xFFF8 - dev->hard_header_len
- preserve all ndo_change_mtu checks for now to prevent regressions

ipv6/ip6_vti:
- min_mtu = 1280, max_mtu = 65535
- remove redundant vti6_change_mtu

ipv6/sit:
- min_mtu = 1280, max_mtu = 0xFFF8 - t_hlen
- remove redundant ipip6_tunnel_change_mtu

CC: [email protected]
CC: "David S. Miller" <[email protected]>
CC: Alexey Kuznetsov <[email protected]>
CC: James Morris <[email protected]>
CC: Hideaki YOSHIFUJI <[email protected]>
CC: Patrick McHardy <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
net/ipv4/ip_tunnel.c | 6 +++++-
net/ipv6/ip6_tunnel.c | 4 +++-
net/ipv6/ip6_vti.c | 21 ++-------------------
net/ipv6/sit.c | 14 ++------------
4 files changed, 12 insertions(+), 33 deletions(-)

diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 5719d6b..12a92e3 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -358,6 +358,7 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
{
struct ip_tunnel *nt;
struct net_device *dev;
+ int t_hlen;

BUG_ON(!itn->fb_tunnel_dev);
dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
@@ -367,6 +368,9 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
dev->mtu = ip_tunnel_bind_dev(dev);

nt = netdev_priv(dev);
+ t_hlen = nt->hlen + sizeof(struct iphdr);
+ dev->min_mtu = ETH_MIN_MTU;
+ dev->max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
ip_tunnel_add(itn, nt);
return nt;
}
@@ -929,7 +933,7 @@ int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
int t_hlen = tunnel->hlen + sizeof(struct iphdr);
int max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;

- if (new_mtu < 68)
+ if (new_mtu < ETH_MIN_MTU)
return -EINVAL;

if (new_mtu > max_mtu) {
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 6a66adb..3a70567 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1634,7 +1634,7 @@ int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)
struct ip6_tnl *tnl = netdev_priv(dev);

if (tnl->parms.proto == IPPROTO_IPIP) {
- if (new_mtu < 68)
+ if (new_mtu < ETH_MIN_MTU)
return -EINVAL;
} else {
if (new_mtu < IPV6_MIN_MTU)
@@ -1787,6 +1787,8 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
dev->mtu = ETH_DATA_LEN - t_hlen;
if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
dev->mtu -= 8;
+ dev->min_mtu = ETH_MIN_MTU;
+ dev->max_mtu = 0xFFF8 - dev->hard_header_len;

return 0;

diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 8a02ca8..35c5b2d 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -812,30 +812,11 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return err;
}

-/**
- * vti6_tnl_change_mtu - change mtu manually for tunnel device
- * @dev: virtual device associated with tunnel
- * @new_mtu: the new mtu
- *
- * Return:
- * 0 on success,
- * %-EINVAL if mtu too small
- **/
-static int vti6_change_mtu(struct net_device *dev, int new_mtu)
-{
- if (new_mtu < IPV6_MIN_MTU)
- return -EINVAL;
-
- dev->mtu = new_mtu;
- return 0;
-}
-
static const struct net_device_ops vti6_netdev_ops = {
.ndo_init = vti6_dev_init,
.ndo_uninit = vti6_dev_uninit,
.ndo_start_xmit = vti6_tnl_xmit,
.ndo_do_ioctl = vti6_ioctl,
- .ndo_change_mtu = vti6_change_mtu,
.ndo_get_stats64 = ip_tunnel_get_stats64,
.ndo_get_iflink = ip6_tnl_get_iflink,
};
@@ -855,6 +836,8 @@ static void vti6_dev_setup(struct net_device *dev)
dev->type = ARPHRD_TUNNEL6;
dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
dev->mtu = ETH_DATA_LEN;
+ dev->min_mtu = IPV6_MIN_MTU;
+ dev->max_mtu = IP_MAX_MTU;
dev->flags |= IFF_NOARP;
dev->addr_len = sizeof(struct in6_addr);
netif_keep_dst(dev);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index b1cdf80..dc7a344 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1318,23 +1318,11 @@ ipip6_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return err;
}

-static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu)
-{
- struct ip_tunnel *tunnel = netdev_priv(dev);
- int t_hlen = tunnel->hlen + sizeof(struct iphdr);
-
- if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - t_hlen)
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static const struct net_device_ops ipip6_netdev_ops = {
.ndo_init = ipip6_tunnel_init,
.ndo_uninit = ipip6_tunnel_uninit,
.ndo_start_xmit = sit_tunnel_xmit,
.ndo_do_ioctl = ipip6_tunnel_ioctl,
- .ndo_change_mtu = ipip6_tunnel_change_mtu,
.ndo_get_stats64 = ip_tunnel_get_stats64,
.ndo_get_iflink = ip_tunnel_get_iflink,
};
@@ -1365,6 +1353,8 @@ static void ipip6_tunnel_setup(struct net_device *dev)
dev->type = ARPHRD_SIT;
dev->hard_header_len = LL_MAX_HEADER + t_hlen;
dev->mtu = ETH_DATA_LEN - t_hlen;
+ dev->min_mtu = IPV6_MIN_MTU;
+ dev->max_mtu = 0xFFF8 - t_hlen;
dev->flags = IFF_NOARP;
netif_keep_dst(dev);
dev->addr_len = 4;
--
2.10.0

2016-10-20 17:57:12

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next v2 6/9] net: use core MTU range checking in virt drivers

hyperv_net:
- set min/max_mtu, per Haiyang, after rndis_filter_device_add

virtio_net:
- set min/max_mtu
- remove virtnet_change_mtu

vmxnet3:
- set min/max_mtu

xen-netback:
- min_mtu = 0, max_mtu = 65517

xen-netfront:
- min_mtu = 0, max_mtu = 65535

unisys/visor:
- clean up defines a little to not clash with network core or add
redundat definitions

CC: [email protected]
CC: [email protected]
CC: "K. Y. Srinivasan" <[email protected]>
CC: Haiyang Zhang <[email protected]>
CC: "Michael S. Tsirkin" <[email protected]>
CC: Shrikrishna Khare <[email protected]>
CC: "VMware, Inc." <[email protected]>
CC: Wei Liu <[email protected]>
CC: Paul Durrant <[email protected]>
CC: David Kershner <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/net/hyperv/hyperv_net.h | 4 ++--
drivers/net/hyperv/netvsc_drv.c | 14 +++++++-------
drivers/net/virtio_net.c | 23 ++++++++++-------------
drivers/net/vmxnet3/vmxnet3_drv.c | 7 ++++---
drivers/net/xen-netback/interface.c | 5 ++++-
drivers/net/xen-netfront.c | 2 ++
drivers/staging/unisys/include/iochannel.h | 10 ++++------
drivers/staging/unisys/visornic/visornic_main.c | 4 ++--
8 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index f4fbcb5..3958ada 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -606,8 +606,8 @@ struct nvsp_message {
} __packed;


-#define NETVSC_MTU 65536
-#define NETVSC_MTU_MIN 68
+#define NETVSC_MTU 65535
+#define NETVSC_MTU_MIN ETH_MIN_MTU

#define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */
#define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index f0919bd..3b28cf1 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -872,19 +872,12 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
struct netvsc_device *nvdev = ndevctx->nvdev;
struct hv_device *hdev = ndevctx->device_ctx;
struct netvsc_device_info device_info;
- int limit = ETH_DATA_LEN;
u32 num_chn;
int ret = 0;

if (ndevctx->start_remove || !nvdev || nvdev->destroy)
return -ENODEV;

- if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
- limit = NETVSC_MTU - ETH_HLEN;
-
- if (mtu < NETVSC_MTU_MIN || mtu > limit)
- return -EINVAL;
-
ret = netvsc_close(ndev);
if (ret)
goto out;
@@ -1402,6 +1395,13 @@ static int netvsc_probe(struct hv_device *dev,
netif_set_real_num_tx_queues(net, nvdev->num_chn);
netif_set_real_num_rx_queues(net, nvdev->num_chn);

+ /* MTU range: 68 - 1500 or 65521 */
+ net->min_mtu = NETVSC_MTU_MIN;
+ if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
+ net->max_mtu = NETVSC_MTU - ETH_HLEN;
+ else
+ net->max_mtu = ETH_DATA_LEN;
+
ret = register_netdev(net);
if (ret != 0) {
pr_err("Unable to register netdev.\n");
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fad84f3..720809f 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1419,17 +1419,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
.set_settings = virtnet_set_settings,
};

-#define MIN_MTU 68
-#define MAX_MTU 65535
-
-static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
-{
- if (new_mtu < MIN_MTU || new_mtu > MAX_MTU)
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static const struct net_device_ops virtnet_netdev = {
.ndo_open = virtnet_open,
.ndo_stop = virtnet_close,
@@ -1437,7 +1426,6 @@ static const struct net_device_ops virtnet_netdev = {
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = virtnet_set_mac_address,
.ndo_set_rx_mode = virtnet_set_rx_mode,
- .ndo_change_mtu = virtnet_change_mtu,
.ndo_get_stats64 = virtnet_stats,
.ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
@@ -1748,6 +1736,9 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
return true;
}

+#define MIN_MTU ETH_MIN_MTU
+#define MAX_MTU ETH_MAX_MTU
+
static int virtnet_probe(struct virtio_device *vdev)
{
int i, err;
@@ -1821,6 +1812,10 @@ static int virtnet_probe(struct virtio_device *vdev)

dev->vlan_features = dev->features;

+ /* MTU range: 68 - 65535 */
+ dev->min_mtu = MIN_MTU;
+ dev->max_mtu = MAX_MTU;
+
/* Configuration may specify what MAC to use. Otherwise random. */
if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
virtio_cread_bytes(vdev,
@@ -1875,8 +1870,10 @@ static int virtnet_probe(struct virtio_device *vdev)
mtu = virtio_cread16(vdev,
offsetof(struct virtio_net_config,
mtu));
- if (virtnet_change_mtu(dev, mtu))
+ if (mtu < dev->min_mtu || mtu > dev->max_mtu)
__virtio_clear_bit(vdev, VIRTIO_NET_F_MTU);
+ else
+ dev->mtu = mtu;
}

if (vi->any_header_sg)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index b5554f2..0c36de1 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -2969,9 +2969,6 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
int err = 0;

- if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU)
- return -EINVAL;
-
netdev->mtu = new_mtu;

/*
@@ -3428,6 +3425,10 @@ vmxnet3_probe_device(struct pci_dev *pdev,
vmxnet3_set_ethtool_ops(netdev);
netdev->watchdog_timeo = 5 * HZ;

+ /* MTU range: 60 - 9000 */
+ netdev->min_mtu = VMXNET3_MIN_MTU;
+ netdev->max_mtu = VMXNET3_MAX_MTU;
+
INIT_WORK(&adapter->work, vmxnet3_reset_work);
set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);

diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 74dc2bf..e30ffd2 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -302,7 +302,7 @@ static int xenvif_close(struct net_device *dev)
static int xenvif_change_mtu(struct net_device *dev, int mtu)
{
struct xenvif *vif = netdev_priv(dev);
- int max = vif->can_sg ? 65535 - VLAN_ETH_HLEN : ETH_DATA_LEN;
+ int max = vif->can_sg ? ETH_MAX_MTU - VLAN_ETH_HLEN : ETH_DATA_LEN;

if (mtu > max)
return -EINVAL;
@@ -471,6 +471,9 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,

dev->tx_queue_len = XENVIF_QUEUE_LENGTH;

+ dev->min_mtu = 0;
+ dev->max_mtu = ETH_MAX_MTU - VLAN_ETH_HLEN;
+
/*
* Initialise a dummy MAC address. We choose the numerically
* largest non-broadcast address to prevent the address getting
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index e17879d..7d616b0 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1329,6 +1329,8 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
netdev->features |= netdev->hw_features;

netdev->ethtool_ops = &xennet_ethtool_ops;
+ netdev->min_mtu = 0;
+ netdev->max_mtu = XEN_NETIF_MAX_TX_SIZE;
SET_NETDEV_DEV(netdev, &dev->dev);

np->netdev = netdev;
diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h
index cba4433..9081b3f 100644
--- a/drivers/staging/unisys/include/iochannel.h
+++ b/drivers/staging/unisys/include/iochannel.h
@@ -113,12 +113,10 @@ enum net_types {

};

-#define ETH_HEADER_SIZE 14 /* size of ethernet header */
-
#define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */
-#define ETH_MIN_PACKET_SIZE (ETH_HEADER_SIZE + ETH_MIN_DATA_SIZE)
+#define ETH_MIN_PACKET_SIZE (ETH_HLEN + ETH_MIN_DATA_SIZE)

-#define ETH_MAX_MTU 16384 /* maximum data size */
+#define VISOR_ETH_MAX_MTU 16384 /* maximum data size */

#ifndef MAX_MACADDR_LEN
#define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */
@@ -288,7 +286,7 @@ struct net_pkt_xmt {
int len; /* full length of data in the packet */
int num_frags; /* number of fragments in frags containing data */
struct phys_info frags[MAX_PHYS_INFO]; /* physical page information */
- char ethhdr[ETH_HEADER_SIZE]; /* the ethernet header */
+ char ethhdr[ETH_HLEN]; /* the ethernet header */
struct {
/* these are needed for csum at uisnic end */
u8 valid; /* 1 = struct is valid - else ignore */
@@ -323,7 +321,7 @@ struct net_pkt_xmtdone {
*/
#define RCVPOST_BUF_SIZE 4032
#define MAX_NET_RCV_CHAIN \
- ((ETH_MAX_MTU + ETH_HEADER_SIZE + RCVPOST_BUF_SIZE - 1) \
+ ((VISOR_ETH_MAX_MTU + ETH_HLEN + RCVPOST_BUF_SIZE - 1) \
/ RCVPOST_BUF_SIZE)

struct net_pkt_rcvpost {
diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c
index 1367007..f8a584b 100644
--- a/drivers/staging/unisys/visornic/visornic_main.c
+++ b/drivers/staging/unisys/visornic/visornic_main.c
@@ -791,7 +791,7 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
* pointing to
*/
firstfraglen = skb->len - skb->data_len;
- if (firstfraglen < ETH_HEADER_SIZE) {
+ if (firstfraglen < ETH_HLEN) {
spin_unlock_irqrestore(&devdata->priv_lock, flags);
devdata->busy_cnt++;
dev_err(&netdev->dev,
@@ -864,7 +864,7 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
/* copy ethernet header from first frag into ocmdrsp
* - everything else will be pass in frags & DMA'ed
*/
- memcpy(cmdrsp->net.xmt.ethhdr, skb->data, ETH_HEADER_SIZE);
+ memcpy(cmdrsp->net.xmt.ethhdr, skb->data, ETH_HLEN);
/* copy frags info - from skb->data we need to only provide access
* beyond eth header
*/
--
2.10.0

2016-10-20 17:57:35

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next v2 5/9] net: use core MTU range checking in core net infra

geneve:
- Merge __geneve_change_mtu back into geneve_change_mtu, set max_mtu
- This one isn't quite as straight-forward as others, could use some
closer inspection and testing

macvlan:
- set min/max_mtu

tun:
- set min/max_mtu, remove tun_net_change_mtu

vxlan:
- Merge __vxlan_change_mtu back into vxlan_change_mtu
- Set max_mtu to IP_MAX_MTU and retain dynamic MTU range checks in
change_mtu function
- This one is also not as straight-forward and could use closer inspection
and testing from vxlan folks

bridge:
- set max_mtu of IP_MAX_MTU and retain dynamic MTU range checks in
change_mtu function

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

sch_teql:
- set min/max_mtu (note: max_mtu previously unchecked, used max of 65535)

macsec:
- min_mtu = 0, max_mtu = 65535

macvlan:
- min_mtu = 0, max_mtu = 65535

ntb_netdev:
- min_mtu = 0, max_mtu = 65535

veth:
- min_mtu = 68, max_mtu = 65535

8021q:
- min_mtu = 0, max_mtu = 65535

CC: [email protected]
CC: Nicolas Dichtel <[email protected]>
CC: Hannes Frederic Sowa <[email protected]>
CC: Tom Herbert <[email protected]>
CC: Daniel Borkmann <[email protected]>
CC: Alexander Duyck <[email protected]>
CC: Paolo Abeni <[email protected]>
CC: Jiri Benc <[email protected]>
CC: WANG Cong <[email protected]>
CC: Roopa Prabhu <[email protected]>
CC: Pravin B Shelar <[email protected]>
CC: Sabrina Dubroca <[email protected]>
CC: Patrick McHardy <[email protected]>
CC: Stephen Hemminger <[email protected]>
CC: Pravin Shelar <[email protected]>
CC: Maxim Krasnyansky <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/net/geneve.c | 48 +++++++++++----------------
drivers/net/macsec.c | 2 ++
drivers/net/macvlan.c | 8 ++++-
drivers/net/ntb_netdev.c | 3 ++
drivers/net/tun.c | 20 ++++-------
drivers/net/veth.c | 17 ++--------
drivers/net/vxlan.c | 64 +++++++++++++++++++-----------------
net/8021q/vlan_dev.c | 3 ++
net/bridge/br_device.c | 3 +-
net/openvswitch/vport-internal_dev.c | 10 ------
net/sched/sch_teql.c | 5 ++-
11 files changed, 81 insertions(+), 102 deletions(-)

diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 3c20e87..752bcaa 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1034,39 +1034,18 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
return geneve_xmit_skb(skb, dev, info);
}

-static int __geneve_change_mtu(struct net_device *dev, int new_mtu, bool strict)
+static int geneve_change_mtu(struct net_device *dev, int new_mtu)
{
- struct geneve_dev *geneve = netdev_priv(dev);
- /* The max_mtu calculation does not take account of GENEVE
- * options, to avoid excluding potentially valid
- * configurations.
+ /* Only possible if called internally, ndo_change_mtu path's new_mtu
+ * is guaranteed to be between dev->min_mtu and dev->max_mtu.
*/
- int max_mtu = IP_MAX_MTU - GENEVE_BASE_HLEN - dev->hard_header_len;
-
- if (geneve->remote.sa.sa_family == AF_INET6)
- max_mtu -= sizeof(struct ipv6hdr);
- else
- max_mtu -= sizeof(struct iphdr);
-
- if (new_mtu < 68)
- return -EINVAL;
-
- if (new_mtu > max_mtu) {
- if (strict)
- return -EINVAL;
-
- new_mtu = max_mtu;
- }
+ if (new_mtu > dev->max_mtu)
+ new_mtu = dev->max_mtu;

dev->mtu = new_mtu;
return 0;
}

-static int geneve_change_mtu(struct net_device *dev, int new_mtu)
-{
- return __geneve_change_mtu(dev, new_mtu, true);
-}
-
static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
{
struct ip_tunnel_info *info = skb_tunnel_info(skb);
@@ -1170,6 +1149,14 @@ static void geneve_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;

+ /* MTU range: 68 - (something less than 65535) */
+ dev->min_mtu = ETH_MIN_MTU;
+ /* The max_mtu calculation does not take account of GENEVE
+ * options, to avoid excluding potentially valid
+ * configurations. This will be further reduced by IPvX hdr size.
+ */
+ dev->max_mtu = IP_MAX_MTU - GENEVE_BASE_HLEN - dev->hard_header_len;
+
netif_keep_dst(dev);
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
@@ -1285,10 +1272,13 @@ static int geneve_configure(struct net *net, struct net_device *dev,

/* make enough headroom for basic scenario */
encap_len = GENEVE_BASE_HLEN + ETH_HLEN;
- if (remote->sa.sa_family == AF_INET)
+ if (remote->sa.sa_family == AF_INET) {
encap_len += sizeof(struct iphdr);
- else
+ dev->max_mtu -= sizeof(struct iphdr);
+ } else {
encap_len += sizeof(struct ipv6hdr);
+ dev->max_mtu -= sizeof(struct ipv6hdr);
+ }
dev->needed_headroom = encap_len + ETH_HLEN;

if (metadata) {
@@ -1488,7 +1478,7 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
/* openvswitch users expect packet sizes to be unrestricted,
* so set the largest MTU we can.
*/
- err = __geneve_change_mtu(dev, IP_MAX_MTU, false);
+ err = geneve_change_mtu(dev, IP_MAX_MTU);
if (err)
goto err;

diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 3ea47f2..1a134cb 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -2970,6 +2970,8 @@ static void macsec_free_netdev(struct net_device *dev)
static void macsec_setup(struct net_device *dev)
{
ether_setup(dev);
+ dev->min_mtu = 0;
+ dev->max_mtu = ETH_MAX_MTU;
dev->priv_flags |= IFF_NO_QUEUE;
dev->netdev_ops = &macsec_netdev_ops;
dev->destructor = macsec_free_netdev;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 3234fcd..a064415 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -777,7 +777,7 @@ static int macvlan_change_mtu(struct net_device *dev, int new_mtu)
{
struct macvlan_dev *vlan = netdev_priv(dev);

- if (new_mtu < 68 || vlan->lowerdev->mtu < new_mtu)
+ if (vlan->lowerdev->mtu < new_mtu)
return -EINVAL;
dev->mtu = new_mtu;
return 0;
@@ -1085,6 +1085,8 @@ void macvlan_common_setup(struct net_device *dev)
{
ether_setup(dev);

+ dev->min_mtu = 0;
+ dev->max_mtu = ETH_MAX_MTU;
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
netif_keep_dst(dev);
dev->priv_flags |= IFF_UNICAST_FLT;
@@ -1297,6 +1299,10 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
else if (dev->mtu > lowerdev->mtu)
return -EINVAL;

+ /* MTU range: 68 - lowerdev->max_mtu */
+ dev->min_mtu = ETH_MIN_MTU;
+ dev->max_mtu = lowerdev->max_mtu;
+
if (!tb[IFLA_ADDRESS])
eth_hw_addr_random(dev);

diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
index a9acf71..36877ba 100644
--- a/drivers/net/ntb_netdev.c
+++ b/drivers/net/ntb_netdev.c
@@ -433,6 +433,9 @@ static int ntb_netdev_probe(struct device *client_dev)
ndev->netdev_ops = &ntb_netdev_ops;
ndev->ethtool_ops = &ntb_ethtool_ops;

+ ndev->min_mtu = 0;
+ ndev->max_mtu = ETH_MAX_MTU;
+
dev->qp = ntb_transport_create_queue(ndev, client_dev,
&ntb_netdev_handlers);
if (!dev->qp) {
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 8093e39..9328568 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -925,18 +925,6 @@ static void tun_net_mclist(struct net_device *dev)
*/
}

-#define MIN_MTU 68
-#define MAX_MTU 65535
-
-static int
-tun_net_change_mtu(struct net_device *dev, int new_mtu)
-{
- if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU)
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static netdev_features_t tun_net_fix_features(struct net_device *dev,
netdev_features_t features)
{
@@ -1014,7 +1002,6 @@ static const struct net_device_ops tun_netdev_ops = {
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
- .ndo_change_mtu = tun_net_change_mtu,
.ndo_fix_features = tun_net_fix_features,
.ndo_select_queue = tun_select_queue,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1029,7 +1016,6 @@ static const struct net_device_ops tap_netdev_ops = {
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
- .ndo_change_mtu = tun_net_change_mtu,
.ndo_fix_features = tun_net_fix_features,
.ndo_set_rx_mode = tun_net_mclist,
.ndo_set_mac_address = eth_mac_addr,
@@ -1062,6 +1048,9 @@ static void tun_flow_uninit(struct tun_struct *tun)
tun_flow_flush(tun);
}

+#define MIN_MTU 68
+#define MAX_MTU 65535
+
/* Initialize net device. */
static void tun_net_init(struct net_device *dev)
{
@@ -1092,6 +1081,9 @@ static void tun_net_init(struct net_device *dev)

break;
}
+
+ dev->min_mtu = MIN_MTU;
+ dev->max_mtu = MAX_MTU - dev->hard_header_len;
}

/* Character device part */
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index fbc853e..0520952a 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -23,9 +23,6 @@
#define DRV_NAME "veth"
#define DRV_VERSION "1.0"

-#define MIN_MTU 68 /* Min L3 MTU */
-#define MAX_MTU 65535 /* Max L3 MTU (arbitrary) */
-
struct pcpu_vstats {
u64 packets;
u64 bytes;
@@ -216,17 +213,9 @@ static int veth_close(struct net_device *dev)
return 0;
}

-static int is_valid_veth_mtu(int new_mtu)
+static int is_valid_veth_mtu(int mtu)
{
- return new_mtu >= MIN_MTU && new_mtu <= MAX_MTU;
-}
-
-static int veth_change_mtu(struct net_device *dev, int new_mtu)
-{
- if (!is_valid_veth_mtu(new_mtu))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
+ return mtu >= ETH_MIN_MTU && mtu <= ETH_MAX_MTU;
}

static int veth_dev_init(struct net_device *dev)
@@ -300,7 +289,6 @@ static const struct net_device_ops veth_netdev_ops = {
.ndo_open = veth_open,
.ndo_stop = veth_close,
.ndo_start_xmit = veth_xmit,
- .ndo_change_mtu = veth_change_mtu,
.ndo_get_stats64 = veth_get_stats64,
.ndo_set_rx_mode = veth_set_multicast_list,
.ndo_set_mac_address = eth_mac_addr,
@@ -337,6 +325,7 @@ static void veth_setup(struct net_device *dev)
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_STAG_RX);
dev->destructor = veth_dev_free;
+ dev->max_mtu = ETH_MAX_MTU;

dev->hw_features = VETH_FEATURES;
dev->hw_enc_features = VETH_FEATURES;
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index e7d1668..c0170b6 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2367,43 +2367,31 @@ 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)
+static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
{
- int max_mtu = IP_MAX_MTU;
-
- if (lowerdev)
- max_mtu = lowerdev->mtu;
+ struct vxlan_dev *vxlan = netdev_priv(dev);
+ struct vxlan_rdst *dst = &vxlan->default_dst;
+ struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
+ dst->remote_ifindex);
+ bool use_ipv6 = false;

if (dst->remote_ip.sa.sa_family == AF_INET6)
- max_mtu -= VXLAN6_HEADROOM;
- else
- max_mtu -= VXLAN_HEADROOM;
-
- if (new_mtu < 68)
- return -EINVAL;
+ use_ipv6 = true;

- if (new_mtu > max_mtu) {
- if (strict)
+ /* 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);
+ if (new_mtu > max_mtu)
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 = __dev_get_by_index(vxlan->net,
- dst->remote_ifindex);
- return __vxlan_change_mtu(dev, lowerdev, dst, new_mtu, true);
-}
-
static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
@@ -2795,6 +2783,10 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
vxlan_ether_setup(dev);
}

+ /* MTU range: 68 - 65535 */
+ dev->min_mtu = ETH_MIN_MTU;
+ dev->max_mtu = ETH_MAX_MTU;
+
vxlan->net = src_net;

dst->remote_vni = conf->vni;
@@ -2838,7 +2830,8 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
#endif

if (!conf->mtu)
- dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
+ dev->mtu = lowerdev->mtu -
+ (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);

needed_headroom = lowerdev->hard_header_len;
} else if (vxlan_addr_multicast(&dst->remote_ip)) {
@@ -2847,9 +2840,20 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
}

if (conf->mtu) {
- err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false);
- if (err)
- return err;
+ int max_mtu = ETH_MAX_MTU;
+
+ if (lowerdev)
+ max_mtu = lowerdev->mtu;
+
+ max_mtu -= (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
+
+ if (conf->mtu < dev->min_mtu || conf->mtu > dev->max_mtu)
+ return -EINVAL;
+
+ dev->mtu = conf->mtu;
+
+ if (conf->mtu > max_mtu)
+ dev->mtu = max_mtu;
}

if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index fbfacd5..10da6c5 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -826,5 +826,8 @@ void vlan_setup(struct net_device *dev)
dev->destructor = vlan_dev_free;
dev->ethtool_ops = &vlan_ethtool_ops;

+ dev->min_mtu = 0;
+ dev->max_mtu = ETH_MAX_MTU;
+
eth_zero_addr(dev->broadcast);
}
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 89a687f..c08e02b 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -185,7 +185,7 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev,
static int br_change_mtu(struct net_device *dev, int new_mtu)
{
struct net_bridge *br = netdev_priv(dev);
- if (new_mtu < 68 || new_mtu > br_min_mtu(br))
+ if (new_mtu > br_min_mtu(br))
return -EINVAL;

dev->mtu = new_mtu;
@@ -410,6 +410,7 @@ void br_dev_setup(struct net_device *dev)
br->bridge_hello_time = br->hello_time = 2 * HZ;
br->bridge_forward_delay = br->forward_delay = 15 * HZ;
br->ageing_time = BR_DEFAULT_AGEING_TIME;
+ dev->max_mtu = ETH_MAX_MTU;

br_netfilter_rtable_init(br);
br_stp_timer_init(br);
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index e7da290..d5d6cae 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -89,15 +89,6 @@ 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)
-{
- if (new_mtu < 68)
- return -EINVAL;
-
- netdev->mtu = new_mtu;
- return 0;
-}
-
static void internal_dev_destructor(struct net_device *dev)
{
struct vport *vport = ovs_internal_dev_get_vport(dev);
@@ -148,7 +139,6 @@ 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,
- .ndo_change_mtu = internal_dev_change_mtu,
.ndo_get_stats64 = internal_get_stats,
.ndo_set_rx_headroom = internal_set_rx_headroom,
};
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 2cd9b44..b019636 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -418,9 +418,6 @@ static int teql_master_mtu(struct net_device *dev, int new_mtu)
struct teql_master *m = netdev_priv(dev);
struct Qdisc *q;

- if (new_mtu < 68)
- return -EINVAL;
-
q = m->slaves;
if (q) {
do {
@@ -460,6 +457,8 @@ static __init void teql_master_setup(struct net_device *dev)
dev->netdev_ops = &teql_netdev_ops;
dev->type = ARPHRD_VOID;
dev->mtu = 1500;
+ dev->min_mtu = 68;
+ dev->max_mtu = 65535;
dev->tx_queue_len = 100;
dev->flags = IFF_NOARP;
dev->hard_header_len = LL_MAX_HEADER;
--
2.10.0

2016-10-20 17:58:08

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next v2 3/9] net: use core MTU range checking in wireless drivers

- set max_mtu in wil6210 driver
- set max_mtu in atmel driver
- set min/max_mtu in cisco airo driver, remove airo_change_mtu
- set min/max_mtu in ipw2100/ipw2200 drivers, remove libipw_change_mtu
- set min/max_mtu in p80211netdev, remove wlan_change_mtu
- set min/max_mtu in net/mac80211/iface.c and remove ieee80211_change_mtu
- set min/max_mtu in wimax/i2400m and remove i2400m_change_mtu
- set min/max_mtu in intersil/hostap and remove prism2_change_mtu
- set min/max_mtu in intersil/orinoco
- set min/max_mtu in tty/n_gsm and remove gsm_change_mtu

CC: [email protected]
CC: [email protected]
CC: Maya Erez <[email protected]>
CC: Simon Kelley <[email protected]>
CC: Stanislav Yakovlev <[email protected]>
CC: Johannes Berg <[email protected]>
CC: Inaky Perez-Gonzalez <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/net/wimax/i2400m/netdev.c | 22 ++--------------------
drivers/net/wireless/ath/wil6210/netdev.c | 17 +----------------
drivers/net/wireless/atmel/atmel.c | 13 ++++---------
drivers/net/wireless/cisco/airo.c | 14 +++-----------
drivers/net/wireless/intel/ipw2x00/ipw2100.c | 3 ++-
drivers/net/wireless/intel/ipw2x00/ipw2200.c | 8 ++++++--
drivers/net/wireless/intel/ipw2x00/libipw.h | 1 -
drivers/net/wireless/intel/ipw2x00/libipw_module.c | 9 ---------
drivers/net/wireless/intersil/hostap/hostap_main.c | 15 ++-------------
drivers/net/wireless/intersil/orinoco/main.c | 6 +++---
drivers/staging/wlan-ng/p80211netdev.c | 18 +++++-------------
drivers/tty/n_gsm.c | 12 ++----------
net/mac80211/iface.c | 15 ++++-----------
13 files changed, 34 insertions(+), 119 deletions(-)

diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index bb74f4b..7f64e74 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -395,25 +395,6 @@ netdev_tx_t i2400m_hard_start_xmit(struct sk_buff *skb,


static
-int i2400m_change_mtu(struct net_device *net_dev, int new_mtu)
-{
- int result;
- struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
- struct device *dev = i2400m_dev(i2400m);
-
- if (new_mtu >= I2400M_MAX_MTU) {
- dev_err(dev, "Cannot change MTU to %d (max is %d)\n",
- new_mtu, I2400M_MAX_MTU);
- result = -EINVAL;
- } else {
- net_dev->mtu = new_mtu;
- result = 0;
- }
- return result;
-}
-
-
-static
void i2400m_tx_timeout(struct net_device *net_dev)
{
/*
@@ -590,7 +571,6 @@ static const struct net_device_ops i2400m_netdev_ops = {
.ndo_stop = i2400m_stop,
.ndo_start_xmit = i2400m_hard_start_xmit,
.ndo_tx_timeout = i2400m_tx_timeout,
- .ndo_change_mtu = i2400m_change_mtu,
};

static void i2400m_get_drvinfo(struct net_device *net_dev,
@@ -621,6 +601,8 @@ void i2400m_netdev_setup(struct net_device *net_dev)
d_fnstart(3, NULL, "(net_dev %p)\n", net_dev);
ether_setup(net_dev);
net_dev->mtu = I2400M_MAX_MTU;
+ net_dev->min_mtu = 0;
+ net_dev->max_mtu = I2400M_MAX_MTU;
net_dev->tx_queue_len = I2400M_TX_QLEN;
net_dev->features =
NETIF_F_VLAN_CHALLENGED
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 61de5e9..d18372c 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -41,21 +41,6 @@ static int wil_stop(struct net_device *ndev)
return wil_down(wil);
}

-static int wil_change_mtu(struct net_device *ndev, int new_mtu)
-{
- struct wil6210_priv *wil = ndev_to_wil(ndev);
-
- if (new_mtu < 68 || new_mtu > mtu_max) {
- wil_err(wil, "invalid MTU %d\n", new_mtu);
- return -EINVAL;
- }
-
- wil_dbg_misc(wil, "change MTU %d -> %d\n", ndev->mtu, new_mtu);
- ndev->mtu = new_mtu;
-
- return 0;
-}
-
static int wil_do_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
{
struct wil6210_priv *wil = ndev_to_wil(ndev);
@@ -69,7 +54,6 @@ static const struct net_device_ops wil_netdev_ops = {
.ndo_start_xmit = wil_start_xmit,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
- .ndo_change_mtu = wil_change_mtu,
.ndo_do_ioctl = wil_do_ioctl,
};

@@ -126,6 +110,7 @@ static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
static void wil_dev_setup(struct net_device *dev)
{
ether_setup(dev);
+ dev->max_mtu = mtu_max;
dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT;
}

diff --git a/drivers/net/wireless/atmel/atmel.c b/drivers/net/wireless/atmel/atmel.c
index bf2e9a0..eb92d5a 100644
--- a/drivers/net/wireless/atmel/atmel.c
+++ b/drivers/net/wireless/atmel/atmel.c
@@ -1295,14 +1295,6 @@ static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
return &priv->wstats;
}

-static int atmel_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > 2312))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static int atmel_set_mac_address(struct net_device *dev, void *p)
{
struct sockaddr *addr = p;
@@ -1506,7 +1498,6 @@ static const struct file_operations atmel_proc_fops = {
static const struct net_device_ops atmel_netdev_ops = {
.ndo_open = atmel_open,
.ndo_stop = atmel_close,
- .ndo_change_mtu = atmel_change_mtu,
.ndo_set_mac_address = atmel_set_mac_address,
.ndo_start_xmit = start_tx,
.ndo_do_ioctl = atmel_ioctl,
@@ -1600,6 +1591,10 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
dev->irq = irq;
dev->base_addr = port;

+ /* MTU range: 68 - 2312 */
+ dev->min_mtu = 68;
+ dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN;
+
SET_NETDEV_DEV(dev, sys_dev);

if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c
index 69b826d..4b04045 100644
--- a/drivers/net/wireless/cisco/airo.c
+++ b/drivers/net/wireless/cisco/airo.c
@@ -2329,14 +2329,6 @@ static int airo_set_mac_address(struct net_device *dev, void *p)
return 0;
}

-static int airo_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > 2400))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
static LIST_HEAD(airo_devices);

static void add_airo_dev(struct airo_info *ai)
@@ -2656,7 +2648,6 @@ static const struct net_device_ops airo11_netdev_ops = {
.ndo_get_stats = airo_get_stats,
.ndo_set_mac_address = airo_set_mac_address,
.ndo_do_ioctl = airo_ioctl,
- .ndo_change_mtu = airo_change_mtu,
};

static void wifi_setup(struct net_device *dev)
@@ -2668,6 +2659,8 @@ static void wifi_setup(struct net_device *dev)
dev->type = ARPHRD_IEEE80211;
dev->hard_header_len = ETH_HLEN;
dev->mtu = AIRO_DEF_MTU;
+ dev->min_mtu = 68;
+ dev->max_mtu = MIC_MSGLEN_MAX;
dev->addr_len = ETH_ALEN;
dev->tx_queue_len = 100;

@@ -2754,7 +2747,6 @@ static const struct net_device_ops airo_netdev_ops = {
.ndo_set_rx_mode = airo_set_multicast_list,
.ndo_set_mac_address = airo_set_mac_address,
.ndo_do_ioctl = airo_ioctl,
- .ndo_change_mtu = airo_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};

@@ -2766,7 +2758,6 @@ static const struct net_device_ops mpi_netdev_ops = {
.ndo_set_rx_mode = airo_set_multicast_list,
.ndo_set_mac_address = airo_set_mac_address,
.ndo_do_ioctl = airo_ioctl,
- .ndo_change_mtu = airo_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};

@@ -2822,6 +2813,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
dev->irq = irq;
dev->base_addr = port;
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+ dev->max_mtu = MIC_MSGLEN_MAX;

SET_NETDEV_DEV(dev, dmdev);

diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
index bfa542c..6417609 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
@@ -6035,7 +6035,6 @@ static const struct net_device_ops ipw2100_netdev_ops = {
.ndo_open = ipw2100_open,
.ndo_stop = ipw2100_close,
.ndo_start_xmit = libipw_xmit,
- .ndo_change_mtu = libipw_change_mtu,
.ndo_tx_timeout = ipw2100_tx_timeout,
.ndo_set_mac_address = ipw2100_set_address,
.ndo_validate_addr = eth_validate_addr,
@@ -6071,6 +6070,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
dev->wireless_data = &priv->wireless_data;
dev->watchdog_timeo = 3 * HZ;
dev->irq = 0;
+ dev->min_mtu = 68;
+ dev->max_mtu = LIBIPW_DATA_LEN;

/* NOTE: We don't use the wireless_handlers hook
* in dev as the system will start throwing WX requests
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index bfd6861..ef9af8a 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -11561,7 +11561,6 @@ static const struct net_device_ops ipw_prom_netdev_ops = {
.ndo_open = ipw_prom_open,
.ndo_stop = ipw_prom_stop,
.ndo_start_xmit = ipw_prom_hard_start_xmit,
- .ndo_change_mtu = libipw_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
};
@@ -11587,6 +11586,9 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;

+ priv->prom_net_dev->min_mtu = 68;
+ priv->prom_net_dev->max_mtu = LIBIPW_DATA_LEN;
+
priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);

@@ -11619,7 +11621,6 @@ static const struct net_device_ops ipw_netdev_ops = {
.ndo_set_rx_mode = ipw_net_set_multicast_list,
.ndo_set_mac_address = ipw_net_set_mac_address,
.ndo_start_xmit = libipw_xmit,
- .ndo_change_mtu = libipw_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};

@@ -11729,6 +11730,9 @@ static int ipw_pci_probe(struct pci_dev *pdev,
net_dev->wireless_handlers = &ipw_wx_handler_def;
net_dev->ethtool_ops = &ipw_ethtool_ops;

+ net_dev->min_mtu = 68;
+ net_dev->max_mtu = LIBIPW_DATA_LEN;
+
err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
if (err) {
IPW_ERROR("failed to create sysfs device attributes\n");
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw.h b/drivers/net/wireless/intel/ipw2x00/libipw.h
index b057161..b513551 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw.h
+++ b/drivers/net/wireless/intel/ipw2x00/libipw.h
@@ -948,7 +948,6 @@ static inline int libipw_is_cck_rate(u8 rate)
/* libipw.c */
void free_libipw(struct net_device *dev, int monitor);
struct net_device *alloc_libipw(int sizeof_priv, int monitor);
-int libipw_change_mtu(struct net_device *dev, int new_mtu);

void libipw_networks_age(struct libipw_device *ieee, unsigned long age_secs);

diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_module.c b/drivers/net/wireless/intel/ipw2x00/libipw_module.c
index 60f2874..2332075 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_module.c
@@ -118,15 +118,6 @@ static void libipw_networks_initialize(struct libipw_device *ieee)
&ieee->network_free_list);
}

-int libipw_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-EXPORT_SYMBOL(libipw_change_mtu);
-
struct net_device *alloc_libipw(int sizeof_priv, int monitor)
{
struct libipw_device *ieee;
diff --git a/drivers/net/wireless/intersil/hostap/hostap_main.c b/drivers/net/wireless/intersil/hostap/hostap_main.c
index 80d4228..1a16b8c 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_main.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_main.c
@@ -765,16 +765,6 @@ static void hostap_set_multicast_list(struct net_device *dev)
}


-static int prism2_change_mtu(struct net_device *dev, int new_mtu)
-{
- if (new_mtu < PRISM2_MIN_MTU || new_mtu > PRISM2_MAX_MTU)
- return -EINVAL;
-
- dev->mtu = new_mtu;
- return 0;
-}
-
-
static void prism2_tx_timeout(struct net_device *dev)
{
struct hostap_interface *iface;
@@ -813,7 +803,6 @@ static const struct net_device_ops hostap_netdev_ops = {
.ndo_do_ioctl = hostap_ioctl,
.ndo_set_mac_address = prism2_set_mac_address,
.ndo_set_rx_mode = hostap_set_multicast_list,
- .ndo_change_mtu = prism2_change_mtu,
.ndo_tx_timeout = prism2_tx_timeout,
.ndo_validate_addr = eth_validate_addr,
};
@@ -826,7 +815,6 @@ static const struct net_device_ops hostap_mgmt_netdev_ops = {
.ndo_do_ioctl = hostap_ioctl,
.ndo_set_mac_address = prism2_set_mac_address,
.ndo_set_rx_mode = hostap_set_multicast_list,
- .ndo_change_mtu = prism2_change_mtu,
.ndo_tx_timeout = prism2_tx_timeout,
.ndo_validate_addr = eth_validate_addr,
};
@@ -839,7 +827,6 @@ static const struct net_device_ops hostap_master_ops = {
.ndo_do_ioctl = hostap_ioctl,
.ndo_set_mac_address = prism2_set_mac_address,
.ndo_set_rx_mode = hostap_set_multicast_list,
- .ndo_change_mtu = prism2_change_mtu,
.ndo_tx_timeout = prism2_tx_timeout,
.ndo_validate_addr = eth_validate_addr,
};
@@ -851,6 +838,8 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,

iface = netdev_priv(dev);
ether_setup(dev);
+ dev->min_mtu = PRISM2_MIN_MTU;
+ dev->max_mtu = PRISM2_MAX_MTU;
dev->priv_flags &= ~IFF_TX_SKB_SHARING;

/* kernel callbacks */
diff --git a/drivers/net/wireless/intersil/orinoco/main.c b/drivers/net/wireless/intersil/orinoco/main.c
index 7afe200..9d96b7c 100644
--- a/drivers/net/wireless/intersil/orinoco/main.c
+++ b/drivers/net/wireless/intersil/orinoco/main.c
@@ -322,9 +322,6 @@ int orinoco_change_mtu(struct net_device *dev, int new_mtu)
{
struct orinoco_private *priv = ndev_priv(dev);

- if ((new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU))
- return -EINVAL;
-
/* MTU + encapsulation + header length */
if ((new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
(priv->nicbuf_size - ETH_HLEN))
@@ -2288,6 +2285,9 @@ int orinoco_if_add(struct orinoco_private *priv,
dev->base_addr = base_addr;
dev->irq = irq;

+ dev->min_mtu = ORINOCO_MIN_MTU;
+ dev->max_mtu = ORINOCO_MAX_MTU;
+
SET_NETDEV_DEV(dev, priv->dev);
ret = register_netdev(dev);
if (ret)
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index 825a63a..4762d38 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -669,18 +669,6 @@ static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr)
return result;
}

-static int wlan_change_mtu(struct net_device *dev, int new_mtu)
-{
- /* 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
- and another 8 for wep. */
- if ((new_mtu < 68) || (new_mtu > (2312 - 20 - 8)))
- return -EINVAL;
-
- dev->mtu = new_mtu;
-
- return 0;
-}
-
static const struct net_device_ops p80211_netdev_ops = {
.ndo_init = p80211knetdev_init,
.ndo_open = p80211knetdev_open,
@@ -690,7 +678,6 @@ static const struct net_device_ops p80211_netdev_ops = {
.ndo_do_ioctl = p80211knetdev_do_ioctl,
.ndo_set_mac_address = p80211knetdev_set_mac_address,
.ndo_tx_timeout = p80211knetdev_tx_timeout,
- .ndo_change_mtu = wlan_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};

@@ -756,6 +743,11 @@ int wlan_setup(struct wlandevice *wlandev, struct device *physdev)
wdev->wiphy = wiphy;
wdev->iftype = NL80211_IFTYPE_STATION;
netdev->ieee80211_ptr = wdev;
+ netdev->min_mtu = 68;
+ /* 2312 is max 802.11 payload, 20 is overhead,
+ * (ether + llc + snap) and another 8 for wep.
+ */
+ netdev->max_mtu = (2312 - 20 - 8);

netif_stop_queue(netdev);
netif_carrier_off(netdev);
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 54cab59..f3932ba 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2711,15 +2711,6 @@ static void gsm_mux_rx_netchar(struct gsm_dlci *dlci,
return;
}

-static int gsm_change_mtu(struct net_device *net, int new_mtu)
-{
- struct gsm_mux_net *mux_net = netdev_priv(net);
- if ((new_mtu < 8) || (new_mtu > mux_net->dlci->gsm->mtu))
- return -EINVAL;
- net->mtu = new_mtu;
- return 0;
-}
-
static void gsm_mux_net_init(struct net_device *net)
{
static const struct net_device_ops gsm_netdev_ops = {
@@ -2728,7 +2719,6 @@ static void gsm_mux_net_init(struct net_device *net)
.ndo_start_xmit = gsm_mux_net_start_xmit,
.ndo_tx_timeout = gsm_mux_net_tx_timeout,
.ndo_get_stats = gsm_mux_net_get_stats,
- .ndo_change_mtu = gsm_change_mtu,
};

net->netdev_ops = &gsm_netdev_ops;
@@ -2787,6 +2777,8 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc)
return -ENOMEM;
}
net->mtu = dlci->gsm->mtu;
+ net->min_mtu = 8;
+ net->max_mtu = dlci->gsm->mtu;
mux_net = netdev_priv(net);
mux_net->dlci = dlci;
kref_init(&mux_net->ref);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 638ec07..73e6a8f 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -150,15 +150,6 @@ void ieee80211_recalc_idle(struct ieee80211_local *local)
ieee80211_hw_config(local, change);
}

-static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
-{
- if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN)
- return -EINVAL;
-
- dev->mtu = new_mtu;
- return 0;
-}
-
static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
bool check_dup)
{
@@ -1166,7 +1157,6 @@ static const struct net_device_ops ieee80211_dataif_ops = {
.ndo_uninit = ieee80211_uninit,
.ndo_start_xmit = ieee80211_subif_start_xmit,
.ndo_set_rx_mode = ieee80211_set_multicast_list,
- .ndo_change_mtu = ieee80211_change_mtu,
.ndo_set_mac_address = ieee80211_change_mac,
.ndo_select_queue = ieee80211_netdev_select_queue,
.ndo_get_stats64 = ieee80211_get_stats64,
@@ -1200,7 +1190,6 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
.ndo_uninit = ieee80211_uninit,
.ndo_start_xmit = ieee80211_monitor_start_xmit,
.ndo_set_rx_mode = ieee80211_set_multicast_list,
- .ndo_change_mtu = ieee80211_change_mtu,
.ndo_set_mac_address = ieee80211_change_mac,
.ndo_select_queue = ieee80211_monitor_select_queue,
.ndo_get_stats64 = ieee80211_get_stats64,
@@ -1884,6 +1873,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,

netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);

+ /* MTU range: 256 - 2304 */
+ ndev->min_mtu = 256;
+ ndev->max_mtu = IEEE80211_MAX_DATA_LEN;
+
ret = register_netdevice(ndev);
if (ret) {
ieee80211_if_free(ndev);
--
2.10.0

2016-10-20 17:58:11

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net-next v2 2/9] net: use core MTU range checking in USB NIC drivers

usbnet:
- Remove stale new_mtu <= 0 check in usbnet.c
- Set min_mtu = 0, max_mtu = 65535 (sub-drivers must set their own
max_mtu and/or min_mtu as needed)

r8152:
- Set appropriate max_mtu for different variants (1500 or 9194)

lan78xx:
- Set max_mtu = 9000

asix_driver:
- max_mtu = 16384 for ax88178 variant

ax88179:
- max_mtu = 4088

cdc_ncm:
- max_mtu from hardware

cdc-phonet:
- min_mtu = 6, max_mtu = 65541

sierra_net:
- max_mtu = 1500, call usbnet_change_mtu directly
- sierra_net_change_mtu checked for MTU > 1500, then called
usbnet_change_mtu, but if we set max_mtu to let the network core handle
the range check, then we can simply call usbnet_change_mtu directly

smsc75xx:
- max_mtu = 9000

CC: [email protected]
CC: Woojung Huh <[email protected]>
CC: Microchip Linux Driver Support <[email protected]>
CC: Hayes Wang <[email protected]>
CC: Oliver Neukum <[email protected]>
CC: Steve Glendinning <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
drivers/net/usb/asix_devices.c | 4 +---
drivers/net/usb/ax88179_178a.c | 4 +---
drivers/net/usb/cdc-phonet.c | 12 ++----------
drivers/net/usb/cdc_ncm.c | 5 +----
drivers/net/usb/lan78xx.c | 8 +++-----
drivers/net/usb/r8152.c | 15 ++++++++++++---
drivers/net/usb/sierra_net.c | 13 ++-----------
drivers/net/usb/smsc75xx.c | 4 +---
drivers/net/usb/usbnet.c | 4 ++--
9 files changed, 25 insertions(+), 44 deletions(-)

diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index cce2495..7363cc5 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -1026,9 +1026,6 @@ static int ax88178_change_mtu(struct net_device *net, int new_mtu)

netdev_dbg(dev->net, "ax88178_change_mtu() new_mtu=%d\n", new_mtu);

- if (new_mtu <= 0 || ll_mtu > 16384)
- return -EINVAL;
-
if ((ll_mtu % dev->maxpacket) == 0)
return -EDOM;

@@ -1081,6 +1078,7 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)

dev->net->netdev_ops = &ax88178_netdev_ops;
dev->net->ethtool_ops = &ax88178_ethtool_ops;
+ dev->net->max_mtu = 16384 - (dev->net->hard_header_len + 4);

/* Blink LEDS so users know driver saw dongle */
asix_sw_reset(dev, 0, 0);
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index e6338c1..36c70d6 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -907,9 +907,6 @@ static int ax88179_change_mtu(struct net_device *net, int new_mtu)
struct usbnet *dev = netdev_priv(net);
u16 tmp16;

- if (new_mtu <= 0 || new_mtu > 4088)
- return -EINVAL;
-
net->mtu = new_mtu;
dev->hard_mtu = net->mtu + net->hard_header_len;

@@ -1266,6 +1263,7 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->netdev_ops = &ax88179_netdev_ops;
dev->net->ethtool_ops = &ax88179_ethtool_ops;
dev->net->needed_headroom = 8;
+ dev->net->max_mtu = 4088;

/* Initialize MII structure */
dev->mii.dev = dev->net;
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c
index ff2270e..eb52de8 100644
--- a/drivers/net/usb/cdc-phonet.c
+++ b/drivers/net/usb/cdc-phonet.c
@@ -276,21 +276,11 @@ static int usbpn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -ENOIOCTLCMD;
}

-static int usbpn_set_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU))
- return -EINVAL;
-
- dev->mtu = new_mtu;
- return 0;
-}
-
static const struct net_device_ops usbpn_ops = {
.ndo_open = usbpn_open,
.ndo_stop = usbpn_close,
.ndo_start_xmit = usbpn_xmit,
.ndo_do_ioctl = usbpn_ioctl,
- .ndo_change_mtu = usbpn_set_mtu,
};

static void usbpn_setup(struct net_device *dev)
@@ -301,6 +291,8 @@ static void usbpn_setup(struct net_device *dev)
dev->type = ARPHRD_PHONET;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
dev->mtu = PHONET_MAX_MTU;
+ dev->min_mtu = PHONET_MIN_MTU;
+ dev->max_mtu = PHONET_MAX_MTU;
dev->hard_header_len = 1;
dev->dev_addr[0] = PN_MEDIA_USB;
dev->addr_len = 1;
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 877c951..7141817 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -740,10 +740,6 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
int cdc_ncm_change_mtu(struct net_device *net, int new_mtu)
{
struct usbnet *dev = netdev_priv(net);
- int maxmtu = cdc_ncm_max_dgram_size(dev) - cdc_ncm_eth_hlen(dev);
-
- if (new_mtu <= 0 || new_mtu > maxmtu)
- return -EINVAL;

net->mtu = new_mtu;
cdc_ncm_set_dgram_size(dev, new_mtu + cdc_ncm_eth_hlen(dev));
@@ -909,6 +905,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_

/* must handle MTU changes */
dev->net->netdev_ops = &cdc_ncm_netdev_ops;
+ dev->net->max_mtu = cdc_ncm_max_dgram_size(dev) - cdc_ncm_eth_hlen(dev);

return 0;

diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 13f033c..c4e748e 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -1980,11 +1980,6 @@ static int lan78xx_change_mtu(struct net_device *netdev, int new_mtu)
int old_rx_urb_size = dev->rx_urb_size;
int ret;

- if (new_mtu > MAX_SINGLE_PACKET_SIZE)
- return -EINVAL;
-
- if (new_mtu <= 0)
- return -EINVAL;
/* no second zero-length packet read wanted after mtu-sized packets */
if ((ll_mtu % dev->maxpacket) == 0)
return -EDOM;
@@ -3388,6 +3383,9 @@ static int lan78xx_probe(struct usb_interface *intf,
if (netdev->mtu > (dev->hard_mtu - netdev->hard_header_len))
netdev->mtu = dev->hard_mtu - netdev->hard_header_len;

+ /* MTU range: 68 - 9000 */
+ netdev->max_mtu = MAX_SINGLE_PACKET_SIZE;
+
dev->ep_blkin = (intf->cur_altsetting)->endpoint + 0;
dev->ep_blkout = (intf->cur_altsetting)->endpoint + 1;
dev->ep_intr = (intf->cur_altsetting)->endpoint + 2;
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 8d6e13c..4213c28 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -4119,9 +4119,6 @@ static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
break;
}

- if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU)
- return -EINVAL;
-
ret = usb_autopm_get_interface(tp->intf);
if (ret < 0)
return ret;
@@ -4311,6 +4308,18 @@ static int rtl8152_probe(struct usb_interface *intf,
netdev->ethtool_ops = &ops;
netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);

+ /* MTU range: 68 - 1500 or 9194 */
+ netdev->min_mtu = ETH_MIN_MTU;
+ switch (tp->version) {
+ case RTL_VER_01:
+ case RTL_VER_02:
+ netdev->max_mtu = ETH_DATA_LEN;
+ break;
+ default:
+ netdev->max_mtu = RTL8153_MAX_MTU;
+ break;
+ }
+
tp->mii.dev = netdev;
tp->mii.mdio_read = read_mii_word;
tp->mii.mdio_write = write_mii_word;
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index a2515887..12071f1 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -165,7 +165,6 @@ struct lsi_umts {

/* Forward definitions */
static void sierra_sync_timer(unsigned long syncdata);
-static int sierra_net_change_mtu(struct net_device *net, int new_mtu);

/* Our own net device operations structure */
static const struct net_device_ops sierra_net_device_ops = {
@@ -173,7 +172,7 @@ static const struct net_device_ops sierra_net_device_ops = {
.ndo_stop = usbnet_stop,
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_change_mtu = sierra_net_change_mtu,
+ .ndo_change_mtu = usbnet_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
};
@@ -622,15 +621,6 @@ static const struct ethtool_ops sierra_net_ethtool_ops = {
.nway_reset = usbnet_nway_reset,
};

-/* MTU can not be more than 1500 bytes, enforce it. */
-static int sierra_net_change_mtu(struct net_device *net, int new_mtu)
-{
- if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU)
- return -EINVAL;
-
- return usbnet_change_mtu(net, new_mtu);
-}
-
static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
{
int result = 0;
@@ -720,6 +710,7 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)

dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN;
dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+ dev->net->max_mtu = SIERRA_NET_MAX_SUPPORTED_MTU;

/* Set up the netdev */
dev->net->flags |= IFF_NOARP;
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 9af9799..0b17b40 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -925,9 +925,6 @@ static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
struct usbnet *dev = netdev_priv(netdev);
int ret;

- if (new_mtu > MAX_SINGLE_PACKET_SIZE)
- return -EINVAL;
-
ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN);
if (ret < 0) {
netdev_warn(dev->net, "Failed to set mac rx frame length\n");
@@ -1448,6 +1445,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->flags |= IFF_MULTICAST;
dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+ dev->net->max_mtu = MAX_SINGLE_PACKET_SIZE;
return 0;
}

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index d5071e3..3de65ea 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -384,8 +384,6 @@ int usbnet_change_mtu (struct net_device *net, int new_mtu)
int old_hard_mtu = dev->hard_mtu;
int old_rx_urb_size = dev->rx_urb_size;

- if (new_mtu <= 0)
- return -EINVAL;
// no second zero-length packet read wanted after mtu-sized packets
if ((ll_mtu % dev->maxpacket) == 0)
return -EDOM;
@@ -1669,6 +1667,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
* bind() should set rx_urb_size in that case.
*/
dev->hard_mtu = net->mtu + net->hard_header_len;
+ net->min_mtu = 0;
+ net->max_mtu = ETH_MAX_MTU;

net->netdev_ops = &usbnet_netdev_ops;
net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
--
2.10.0

2016-10-20 18:05:16

by Haiyang Zhang

[permalink] [raw]
Subject: RE: [PATCH net-next v2 6/9] net: use core MTU range checking in virt drivers



> -----Original Message-----
> From: Jarod Wilson [mailto:[email protected]]
> Sent: Thursday, October 20, 2016 1:55 PM
> To: [email protected]
> Cc: Jarod Wilson <[email protected]>; [email protected];
> [email protected]; KY Srinivasan
> <[email protected]>; Haiyang Zhang <[email protected]>; Michael S.
> Tsirkin <[email protected]>; Shrikrishna Khare <[email protected]>; VMware,
> Inc. <[email protected]>; Wei Liu <[email protected]>; Paul
> Durrant <[email protected]>; David Kershner
> <[email protected]>
> Subject: [PATCH net-next v2 6/9] net: use core MTU range checking in
> virt drivers
>
> hyperv_net:
> - set min/max_mtu, per Haiyang, after rndis_filter_device_add
>
> virtio_net:
> - set min/max_mtu
> - remove virtnet_change_mtu
>
> vmxnet3:
> - set min/max_mtu
>
> xen-netback:
> - min_mtu = 0, max_mtu = 65517
>
> xen-netfront:
> - min_mtu = 0, max_mtu = 65535
>
> unisys/visor:
> - clean up defines a little to not clash with network core or add
> redundat definitions
>
> CC: [email protected]
> CC: [email protected]
> CC: "K. Y. Srinivasan" <[email protected]>
> CC: Haiyang Zhang <[email protected]>
> CC: "Michael S. Tsirkin" <[email protected]>
> CC: Shrikrishna Khare <[email protected]>
> CC: "VMware, Inc." <[email protected]>
> CC: Wei Liu <[email protected]>
> CC: Paul Durrant <[email protected]>
> CC: David Kershner <[email protected]>
> Signed-off-by: Jarod Wilson <[email protected]>
> ---

The hv_netvsc changes look fine. Thanks.

Reviewed-by: Haiyang Zhang <[email protected]>



2016-10-20 18:22:41

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH net-next v2 3/9] net: use core MTU range checking in wireless drivers

On Thu, 2016-10-20 at 13:55 -0400, Jarod Wilson wrote:
> - set max_mtu in wil6210 driver
> - set max_mtu in atmel driver
> - set min/max_mtu in cisco airo driver, remove airo_change_mtu
> - set min/max_mtu in ipw2100/ipw2200 drivers, remove
> libipw_change_mtu
> - set min/max_mtu in p80211netdev, remove wlan_change_mtu
> - set min/max_mtu in net/mac80211/iface.c and remove ieee80211_change_mtu

For the mac80211 part,

Acked-by: Johannes Berg <[email protected]>

Dave, I'm assuming you'll pick this up, but if you prefer not to I can
also coordinate with Kalle to take this through our trees.

johannes

2016-10-20 18:41:03

by David Miller

[permalink] [raw]
Subject: Re: [PATCH net-next v2 3/9] net: use core MTU range checking in wireless drivers

From: Johannes Berg <[email protected]>
Date: Thu, 20 Oct 2016 20:22:35 +0200

> On Thu, 2016-10-20 at 13:55 -0400, Jarod Wilson wrote:
>> - set max_mtu in wil6210 driver
>> - set max_mtu in atmel driver
>> - set min/max_mtu in cisco airo driver, remove airo_change_mtu
>> - set min/max_mtu in ipw2100/ipw2200 drivers, remove
>> libipw_change_mtu
>> - set min/max_mtu in p80211netdev, remove wlan_change_mtu
>> - set min/max_mtu in net/mac80211/iface.c and remove ieee80211_change_mtu
>
> For the mac80211 part,
>
> Acked-by: Johannes Berg <[email protected]>
>
> Dave, I'm assuming you'll pick this up, but if you prefer not to I can
> also coordinate with Kalle to take this through our trees.

Yeah I'll get this, thanks for asking.

2016-10-20 18:53:48

by David Miller

[permalink] [raw]
Subject: Re: [PATCH net-next v2 0/9] net: use core MTU range checking everywhere

From: Jarod Wilson <[email protected]>
Date: Thu, 20 Oct 2016 13:55:15 -0400

> This stack of patches should get absolutely everything in the kernel
> converted from doing their own MTU range checking to the core MTU range
> checking. This second spin includes alterations to hopefully fix all
> concerns raised with the first, as well as including some additional
> changes to drivers and infrastructure where I completely missed necessary
> updates.
>
> These have all been built through the 0-day build infrastructure via the
> (rebasing) master branch at https://github.com/jarodwilson/linux-muck, which
> at the time of the most recent compile across 147 configs, was based on
> net-next at commit 7b1536ef0aa0.

Series applied, hopefully this gets most of the fallout.

Thanks Jarod.

2016-10-20 20:23:59

by Michael S. Tsirkin

[permalink] [raw]
Subject: Re: [PATCH net-next v2 6/9] net: use core MTU range checking in virt drivers

On Thu, Oct 20, 2016 at 01:55:21PM -0400, Jarod Wilson wrote:
> hyperv_net:
> - set min/max_mtu, per Haiyang, after rndis_filter_device_add
>
> virtio_net:
> - set min/max_mtu
> - remove virtnet_change_mtu
> vmxnet3:
> - set min/max_mtu
>
> xen-netback:
> - min_mtu = 0, max_mtu = 65517
>
> xen-netfront:
> - min_mtu = 0, max_mtu = 65535
>
> unisys/visor:
> - clean up defines a little to not clash with network core or add
> redundat definitions
>
> CC: [email protected]
> CC: [email protected]
> CC: "K. Y. Srinivasan" <[email protected]>
> CC: Haiyang Zhang <[email protected]>
> CC: "Michael S. Tsirkin" <[email protected]>
> CC: Shrikrishna Khare <[email protected]>
> CC: "VMware, Inc." <[email protected]>
> CC: Wei Liu <[email protected]>
> CC: Paul Durrant <[email protected]>
> CC: David Kershner <[email protected]>
> Signed-off-by: Jarod Wilson <[email protected]>
> ---
> drivers/net/hyperv/hyperv_net.h | 4 ++--
> drivers/net/hyperv/netvsc_drv.c | 14 +++++++-------
> drivers/net/virtio_net.c | 23 ++++++++++-------------
> drivers/net/vmxnet3/vmxnet3_drv.c | 7 ++++---
> drivers/net/xen-netback/interface.c | 5 ++++-
> drivers/net/xen-netfront.c | 2 ++
> drivers/staging/unisys/include/iochannel.h | 10 ++++------
> drivers/staging/unisys/visornic/visornic_main.c | 4 ++--
> 8 files changed, 35 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
> index f4fbcb5..3958ada 100644
> --- a/drivers/net/hyperv/hyperv_net.h
> +++ b/drivers/net/hyperv/hyperv_net.h
> @@ -606,8 +606,8 @@ struct nvsp_message {
> } __packed;
>
>
> -#define NETVSC_MTU 65536
> -#define NETVSC_MTU_MIN 68
> +#define NETVSC_MTU 65535
> +#define NETVSC_MTU_MIN ETH_MIN_MTU
>
> #define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */
> #define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */
> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> index f0919bd..3b28cf1 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -872,19 +872,12 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
> struct netvsc_device *nvdev = ndevctx->nvdev;
> struct hv_device *hdev = ndevctx->device_ctx;
> struct netvsc_device_info device_info;
> - int limit = ETH_DATA_LEN;
> u32 num_chn;
> int ret = 0;
>
> if (ndevctx->start_remove || !nvdev || nvdev->destroy)
> return -ENODEV;
>
> - if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
> - limit = NETVSC_MTU - ETH_HLEN;
> -
> - if (mtu < NETVSC_MTU_MIN || mtu > limit)
> - return -EINVAL;
> -
> ret = netvsc_close(ndev);
> if (ret)
> goto out;
> @@ -1402,6 +1395,13 @@ static int netvsc_probe(struct hv_device *dev,
> netif_set_real_num_tx_queues(net, nvdev->num_chn);
> netif_set_real_num_rx_queues(net, nvdev->num_chn);
>
> + /* MTU range: 68 - 1500 or 65521 */
> + net->min_mtu = NETVSC_MTU_MIN;
> + if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
> + net->max_mtu = NETVSC_MTU - ETH_HLEN;
> + else
> + net->max_mtu = ETH_DATA_LEN;
> +
> ret = register_netdev(net);
> if (ret != 0) {
> pr_err("Unable to register netdev.\n");
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index fad84f3..720809f 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1419,17 +1419,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
> .set_settings = virtnet_set_settings,
> };
>
> -#define MIN_MTU 68
> -#define MAX_MTU 65535
> -
> -static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
> -{
> - if (new_mtu < MIN_MTU || new_mtu > MAX_MTU)
> - return -EINVAL;
> - dev->mtu = new_mtu;
> - return 0;
> -}
> -
> static const struct net_device_ops virtnet_netdev = {
> .ndo_open = virtnet_open,
> .ndo_stop = virtnet_close,
> @@ -1437,7 +1426,6 @@ static const struct net_device_ops virtnet_netdev = {
> .ndo_validate_addr = eth_validate_addr,
> .ndo_set_mac_address = virtnet_set_mac_address,
> .ndo_set_rx_mode = virtnet_set_rx_mode,
> - .ndo_change_mtu = virtnet_change_mtu,
> .ndo_get_stats64 = virtnet_stats,
> .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
> .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
> @@ -1748,6 +1736,9 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
> return true;
> }
>
> +#define MIN_MTU ETH_MIN_MTU
> +#define MAX_MTU ETH_MAX_MTU
> +

Can we drop these btw?

> static int virtnet_probe(struct virtio_device *vdev)
> {
> int i, err;
> @@ -1821,6 +1812,10 @@ static int virtnet_probe(struct virtio_device *vdev)
>
> dev->vlan_features = dev->features;
>
> + /* MTU range: 68 - 65535 */
> + dev->min_mtu = MIN_MTU;
> + dev->max_mtu = MAX_MTU;
> +
> /* Configuration may specify what MAC to use. Otherwise random. */
> if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
> virtio_cread_bytes(vdev,
> @@ -1875,8 +1870,10 @@ static int virtnet_probe(struct virtio_device *vdev)
> mtu = virtio_cread16(vdev,
> offsetof(struct virtio_net_config,
> mtu));
> - if (virtnet_change_mtu(dev, mtu))
> + if (mtu < dev->min_mtu || mtu > dev->max_mtu)

In fact the > max_mtu branch does not make sense since a 16 bit
value can't exceed MAX_MTU.

> __virtio_clear_bit(vdev, VIRTIO_NET_F_MTU);
> + else
> + dev->mtu = mtu;
> }
>
> if (vi->any_header_sg)
> diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
> index b5554f2..0c36de1 100644
> --- a/drivers/net/vmxnet3/vmxnet3_drv.c
> +++ b/drivers/net/vmxnet3/vmxnet3_drv.c
> @@ -2969,9 +2969,6 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
> struct vmxnet3_adapter *adapter = netdev_priv(netdev);
> int err = 0;
>
> - if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU)
> - return -EINVAL;
> -
> netdev->mtu = new_mtu;
>
> /*
> @@ -3428,6 +3425,10 @@ vmxnet3_probe_device(struct pci_dev *pdev,
> vmxnet3_set_ethtool_ops(netdev);
> netdev->watchdog_timeo = 5 * HZ;
>
> + /* MTU range: 60 - 9000 */
> + netdev->min_mtu = VMXNET3_MIN_MTU;
> + netdev->max_mtu = VMXNET3_MAX_MTU;
> +
> INIT_WORK(&adapter->work, vmxnet3_reset_work);
> set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
>
> diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
> index 74dc2bf..e30ffd2 100644
> --- a/drivers/net/xen-netback/interface.c
> +++ b/drivers/net/xen-netback/interface.c
> @@ -302,7 +302,7 @@ static int xenvif_close(struct net_device *dev)
> static int xenvif_change_mtu(struct net_device *dev, int mtu)
> {
> struct xenvif *vif = netdev_priv(dev);
> - int max = vif->can_sg ? 65535 - VLAN_ETH_HLEN : ETH_DATA_LEN;
> + int max = vif->can_sg ? ETH_MAX_MTU - VLAN_ETH_HLEN : ETH_DATA_LEN;
>
> if (mtu > max)
> return -EINVAL;
> @@ -471,6 +471,9 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
>
> dev->tx_queue_len = XENVIF_QUEUE_LENGTH;
>
> + dev->min_mtu = 0;
> + dev->max_mtu = ETH_MAX_MTU - VLAN_ETH_HLEN;
> +
> /*
> * Initialise a dummy MAC address. We choose the numerically
> * largest non-broadcast address to prevent the address getting
> diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
> index e17879d..7d616b0 100644
> --- a/drivers/net/xen-netfront.c
> +++ b/drivers/net/xen-netfront.c
> @@ -1329,6 +1329,8 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
> netdev->features |= netdev->hw_features;
>
> netdev->ethtool_ops = &xennet_ethtool_ops;
> + netdev->min_mtu = 0;
> + netdev->max_mtu = XEN_NETIF_MAX_TX_SIZE;
> SET_NETDEV_DEV(netdev, &dev->dev);
>
> np->netdev = netdev;
> diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h
> index cba4433..9081b3f 100644
> --- a/drivers/staging/unisys/include/iochannel.h
> +++ b/drivers/staging/unisys/include/iochannel.h
> @@ -113,12 +113,10 @@ enum net_types {
>
> };
>
> -#define ETH_HEADER_SIZE 14 /* size of ethernet header */
> -
> #define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */
> -#define ETH_MIN_PACKET_SIZE (ETH_HEADER_SIZE + ETH_MIN_DATA_SIZE)
> +#define ETH_MIN_PACKET_SIZE (ETH_HLEN + ETH_MIN_DATA_SIZE)
>
> -#define ETH_MAX_MTU 16384 /* maximum data size */
> +#define VISOR_ETH_MAX_MTU 16384 /* maximum data size */
>
> #ifndef MAX_MACADDR_LEN
> #define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */
> @@ -288,7 +286,7 @@ struct net_pkt_xmt {
> int len; /* full length of data in the packet */
> int num_frags; /* number of fragments in frags containing data */
> struct phys_info frags[MAX_PHYS_INFO]; /* physical page information */
> - char ethhdr[ETH_HEADER_SIZE]; /* the ethernet header */
> + char ethhdr[ETH_HLEN]; /* the ethernet header */
> struct {
> /* these are needed for csum at uisnic end */
> u8 valid; /* 1 = struct is valid - else ignore */
> @@ -323,7 +321,7 @@ struct net_pkt_xmtdone {
> */
> #define RCVPOST_BUF_SIZE 4032
> #define MAX_NET_RCV_CHAIN \
> - ((ETH_MAX_MTU + ETH_HEADER_SIZE + RCVPOST_BUF_SIZE - 1) \
> + ((VISOR_ETH_MAX_MTU + ETH_HLEN + RCVPOST_BUF_SIZE - 1) \
> / RCVPOST_BUF_SIZE)
>
> struct net_pkt_rcvpost {
> diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c
> index 1367007..f8a584b 100644
> --- a/drivers/staging/unisys/visornic/visornic_main.c
> +++ b/drivers/staging/unisys/visornic/visornic_main.c
> @@ -791,7 +791,7 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
> * pointing to
> */
> firstfraglen = skb->len - skb->data_len;
> - if (firstfraglen < ETH_HEADER_SIZE) {
> + if (firstfraglen < ETH_HLEN) {
> spin_unlock_irqrestore(&devdata->priv_lock, flags);
> devdata->busy_cnt++;
> dev_err(&netdev->dev,
> @@ -864,7 +864,7 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
> /* copy ethernet header from first frag into ocmdrsp
> * - everything else will be pass in frags & DMA'ed
> */
> - memcpy(cmdrsp->net.xmt.ethhdr, skb->data, ETH_HEADER_SIZE);
> + memcpy(cmdrsp->net.xmt.ethhdr, skb->data, ETH_HLEN);
> /* copy frags info - from skb->data we need to only provide access
> * beyond eth header
> */
> --
> 2.10.0

2016-10-20 20:45:36

by Kershner, David A

[permalink] [raw]
Subject: RE: [PATCH net-next v2 6/9] net: use core MTU range checking in virt drivers



> -----Original Message-----
> From: Haiyang Zhang [mailto:[email protected]]
> Sent: Thursday, October 20, 2016 2:05 PM
> To: Jarod Wilson <[email protected]>; [email protected]
> Cc: [email protected]; [email protected]; KY
> Srinivasan <[email protected]>; Michael S. Tsirkin <[email protected]>;
> Shrikrishna Khare <[email protected]>; VMware, Inc. <pv-
> [email protected]>; Wei Liu <[email protected]>; Paul Durrant
> <[email protected]>; Kershner, David A
> <[email protected]>
> Subject: RE: [PATCH net-next v2 6/9] net: use core MTU range checking in virt
> drivers
>
>
>
> > -----Original Message-----
> > From: Jarod Wilson [mailto:[email protected]]
> > Sent: Thursday, October 20, 2016 1:55 PM
> > To: [email protected]
> > Cc: Jarod Wilson <[email protected]>; [email protected];
> > [email protected]; KY Srinivasan
> > <[email protected]>; Haiyang Zhang <[email protected]>;
> Michael S.
> > Tsirkin <[email protected]>; Shrikrishna Khare <[email protected]>;
> VMware,
> > Inc. <[email protected]>; Wei Liu <[email protected]>; Paul
> > Durrant <[email protected]>; David Kershner
> > <[email protected]>
> > Subject: [PATCH net-next v2 6/9] net: use core MTU range checking in
> > virt drivers
> >
> > hyperv_net:
> > - set min/max_mtu, per Haiyang, after rndis_filter_device_add
> >
> > virtio_net:
> > - set min/max_mtu
> > - remove virtnet_change_mtu
> >
> > vmxnet3:
> > - set min/max_mtu
> >
> > xen-netback:
> > - min_mtu = 0, max_mtu = 65517
> >
> > xen-netfront:
> > - min_mtu = 0, max_mtu = 65535
> >
> > unisys/visor:
> > - clean up defines a little to not clash with network core or add
> > redundat definitions
> >
> > CC: [email protected]
> > CC: [email protected]
> > CC: "K. Y. Srinivasan" <[email protected]>
> > CC: Haiyang Zhang <[email protected]>
> > CC: "Michael S. Tsirkin" <[email protected]>
> > CC: Shrikrishna Khare <[email protected]>
> > CC: "VMware, Inc." <[email protected]>
> > CC: Wei Liu <[email protected]>
> > CC: Paul Durrant <[email protected]>
> > CC: David Kershner <[email protected]>
> > Signed-off-by: Jarod Wilson <[email protected]>
> > ---
>
> The hv_netvsc changes look fine. Thanks.
>
> Reviewed-by: Haiyang Zhang <[email protected]>
>

The visornic changes look good.

Reviewed-by: David Kershner <[email protected]>




2016-10-21 02:37:36

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next v2 6/9] net: use core MTU range checking in virt drivers

On Thu, Oct 20, 2016 at 11:23:54PM +0300, Michael S. Tsirkin wrote:
> On Thu, Oct 20, 2016 at 01:55:21PM -0400, Jarod Wilson wrote:
...
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index fad84f3..720809f 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1419,17 +1419,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
> > .set_settings = virtnet_set_settings,
> > };
> >
> > -#define MIN_MTU 68
> > -#define MAX_MTU 65535
> > -
> > -static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
> > -{
> > - if (new_mtu < MIN_MTU || new_mtu > MAX_MTU)
> > - return -EINVAL;
> > - dev->mtu = new_mtu;
> > - return 0;
> > -}
> > -
> > static const struct net_device_ops virtnet_netdev = {
> > .ndo_open = virtnet_open,
> > .ndo_stop = virtnet_close,
> > @@ -1437,7 +1426,6 @@ static const struct net_device_ops virtnet_netdev = {
> > .ndo_validate_addr = eth_validate_addr,
> > .ndo_set_mac_address = virtnet_set_mac_address,
> > .ndo_set_rx_mode = virtnet_set_rx_mode,
> > - .ndo_change_mtu = virtnet_change_mtu,
> > .ndo_get_stats64 = virtnet_stats,
> > .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
> > .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
> > @@ -1748,6 +1736,9 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
> > return true;
> > }
> >
> > +#define MIN_MTU ETH_MIN_MTU
> > +#define MAX_MTU ETH_MAX_MTU
> > +
>
> Can we drop these btw?

Bah. Yeah. Should have just used them directly. I didn't add ETH_MAX_MTU
until after doing the virtio_net changes, so I missed that.

> > static int virtnet_probe(struct virtio_device *vdev)
> > {
> > int i, err;
> > @@ -1821,6 +1812,10 @@ static int virtnet_probe(struct virtio_device *vdev)
> >
> > dev->vlan_features = dev->features;
> >
> > + /* MTU range: 68 - 65535 */
> > + dev->min_mtu = MIN_MTU;
> > + dev->max_mtu = MAX_MTU;
> > +
> > /* Configuration may specify what MAC to use. Otherwise random. */
> > if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
> > virtio_cread_bytes(vdev,
> > @@ -1875,8 +1870,10 @@ static int virtnet_probe(struct virtio_device *vdev)
> > mtu = virtio_cread16(vdev,
> > offsetof(struct virtio_net_config,
> > mtu));
> > - if (virtnet_change_mtu(dev, mtu))
> > + if (mtu < dev->min_mtu || mtu > dev->max_mtu)
>
> In fact the > max_mtu branch does not make sense since a 16 bit
> value can't exceed MAX_MTU.

Hm. mtu is declared as an int, not sure if there's any sort of type
promotion to be worried about (not an area I know much/anything about).
Certainly something that could be looked into as a minor optimization,
though it's only in a probe path and shouldn't hurt anything, so ... meh?

--
Jarod Wilson
[email protected]

2016-10-21 03:36:30

by Michael S. Tsirkin

[permalink] [raw]
Subject: Re: [PATCH net-next v2 6/9] net: use core MTU range checking in virt drivers

On Thu, Oct 20, 2016 at 10:37:20PM -0400, Jarod Wilson wrote:
> On Thu, Oct 20, 2016 at 11:23:54PM +0300, Michael S. Tsirkin wrote:
> > On Thu, Oct 20, 2016 at 01:55:21PM -0400, Jarod Wilson wrote:
> ...
> > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > index fad84f3..720809f 100644
> > > --- a/drivers/net/virtio_net.c
> > > +++ b/drivers/net/virtio_net.c
> > > @@ -1419,17 +1419,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
> > > .set_settings = virtnet_set_settings,
> > > };
> > >
> > > -#define MIN_MTU 68
> > > -#define MAX_MTU 65535
> > > -
> > > -static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
> > > -{
> > > - if (new_mtu < MIN_MTU || new_mtu > MAX_MTU)
> > > - return -EINVAL;
> > > - dev->mtu = new_mtu;
> > > - return 0;
> > > -}
> > > -
> > > static const struct net_device_ops virtnet_netdev = {
> > > .ndo_open = virtnet_open,
> > > .ndo_stop = virtnet_close,
> > > @@ -1437,7 +1426,6 @@ static const struct net_device_ops virtnet_netdev = {
> > > .ndo_validate_addr = eth_validate_addr,
> > > .ndo_set_mac_address = virtnet_set_mac_address,
> > > .ndo_set_rx_mode = virtnet_set_rx_mode,
> > > - .ndo_change_mtu = virtnet_change_mtu,
> > > .ndo_get_stats64 = virtnet_stats,
> > > .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
> > > .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
> > > @@ -1748,6 +1736,9 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
> > > return true;
> > > }
> > >
> > > +#define MIN_MTU ETH_MIN_MTU
> > > +#define MAX_MTU ETH_MAX_MTU
> > > +
> >
> > Can we drop these btw?
>
> Bah. Yeah. Should have just used them directly. I didn't add ETH_MAX_MTU
> until after doing the virtio_net changes, so I missed that.
>
> > > static int virtnet_probe(struct virtio_device *vdev)
> > > {
> > > int i, err;
> > > @@ -1821,6 +1812,10 @@ static int virtnet_probe(struct virtio_device *vdev)
> > >
> > > dev->vlan_features = dev->features;
> > >
> > > + /* MTU range: 68 - 65535 */
> > > + dev->min_mtu = MIN_MTU;
> > > + dev->max_mtu = MAX_MTU;
> > > +
> > > /* Configuration may specify what MAC to use. Otherwise random. */
> > > if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
> > > virtio_cread_bytes(vdev,
> > > @@ -1875,8 +1870,10 @@ static int virtnet_probe(struct virtio_device *vdev)
> > > mtu = virtio_cread16(vdev,
> > > offsetof(struct virtio_net_config,
> > > mtu));
> > > - if (virtnet_change_mtu(dev, mtu))
> > > + if (mtu < dev->min_mtu || mtu > dev->max_mtu)
> >
> > In fact the > max_mtu branch does not make sense since a 16 bit
> > value can't exceed MAX_MTU.
>
> Hm. mtu is declared as an int, not sure if there's any sort of type
> promotion to be worried about (not an area I know much/anything about).

Not by design, that's for sure.

> Certainly something that could be looked into as a minor optimization,
> though it's only in a probe path and shouldn't hurt anything, so ... meh?

Right. Aaron said he's working on a patch that essentially does
dev->max_mtu = mtu after validation, so this part will look
a bit silly there.

> --
> Jarod Wilson
> [email protected]

2016-10-21 10:09:17

by Wei Liu

[permalink] [raw]
Subject: Re: [PATCH net-next v2 6/9] net: use core MTU range checking in virt drivers

On Thu, Oct 20, 2016 at 01:55:21PM -0400, Jarod Wilson wrote:
> hyperv_net:
> - set min/max_mtu, per Haiyang, after rndis_filter_device_add
>
> virtio_net:
> - set min/max_mtu
> - remove virtnet_change_mtu
>
> vmxnet3:
> - set min/max_mtu
>
> xen-netback:
> - min_mtu = 0, max_mtu = 65517
>
> xen-netfront:
> - min_mtu = 0, max_mtu = 65535
>
> unisys/visor:
> - clean up defines a little to not clash with network core or add
> redundat definitions
>
> CC: [email protected]
> CC: [email protected]
> CC: "K. Y. Srinivasan" <[email protected]>
> CC: Haiyang Zhang <[email protected]>
> CC: "Michael S. Tsirkin" <[email protected]>
> CC: Shrikrishna Khare <[email protected]>
> CC: "VMware, Inc." <[email protected]>
> CC: Wei Liu <[email protected]>
> CC: Paul Durrant <[email protected]>
> CC: David Kershner <[email protected]>
> Signed-off-by: Jarod Wilson <[email protected]>

Acked-by: Wei Liu <[email protected]>

2016-10-21 12:04:17

by Krzysztof Hałasa

[permalink] [raw]
Subject: Re: [PATCH net-next 3/6] net: use core MTU range checking in WAN drivers

Jarod Wilson <[email protected]> writes:

> - set min/max_mtu in all hdlc drivers, remove hdlc_change_mtu
> - sent max_mtu in lec driver, remove lec_change_mtu

> drivers/net/wan/c101.c | 1 -
> drivers/net/wan/hdlc.c | 11 ++---------
> drivers/net/wan/hdlc_fr.c | 3 ++-
> drivers/net/wan/ixp4xx_hss.c | 1 -
> drivers/net/wan/n2.c | 1 -
> drivers/net/wan/pc300too.c | 1 -
> drivers/net/wan/pci200syn.c | 1 -
> drivers/net/wan/wanxl.c | 1 -
> include/linux/hdlc.h | 2 --

Acked-by: Krzysztof Halasa <[email protected]>
--
Krzysztof Halasa

Industrial Research Institute for Automation and Measurements PIAP
Al. Jerozolimskie 202, 02-486 Warsaw, Poland

2016-10-21 13:24:31

by Aaron Conole

[permalink] [raw]
Subject: Re: [PATCH net-next v2 6/9] net: use core MTU range checking in virt drivers

"Michael S. Tsirkin" <[email protected]> writes:

> On Thu, Oct 20, 2016 at 10:37:20PM -0400, Jarod Wilson wrote:
>> On Thu, Oct 20, 2016 at 11:23:54PM +0300, Michael S. Tsirkin wrote:
>> > On Thu, Oct 20, 2016 at 01:55:21PM -0400, Jarod Wilson wrote:
>> ...
>> > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
>> > > index fad84f3..720809f 100644
>> > > --- a/drivers/net/virtio_net.c
>> > > +++ b/drivers/net/virtio_net.c
>> > > @@ -1419,17 +1419,6 @@ static const struct ethtool_ops virtnet_ethtool_ops = {
>> > > .set_settings = virtnet_set_settings,
>> > > };
>> > >
>> > > -#define MIN_MTU 68
>> > > -#define MAX_MTU 65535
>> > > -
>> > > -static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
>> > > -{
>> > > - if (new_mtu < MIN_MTU || new_mtu > MAX_MTU)
>> > > - return -EINVAL;
>> > > - dev->mtu = new_mtu;
>> > > - return 0;
>> > > -}
>> > > -
>> > > static const struct net_device_ops virtnet_netdev = {
>> > > .ndo_open = virtnet_open,
>> > > .ndo_stop = virtnet_close,
>> > > @@ -1437,7 +1426,6 @@ static const struct net_device_ops virtnet_netdev = {
>> > > .ndo_validate_addr = eth_validate_addr,
>> > > .ndo_set_mac_address = virtnet_set_mac_address,
>> > > .ndo_set_rx_mode = virtnet_set_rx_mode,
>> > > - .ndo_change_mtu = virtnet_change_mtu,
>> > > .ndo_get_stats64 = virtnet_stats,
>> > > .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
>> > > .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
>> > > @@ -1748,6 +1736,9 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
>> > > return true;
>> > > }
>> > >
>> > > +#define MIN_MTU ETH_MIN_MTU
>> > > +#define MAX_MTU ETH_MAX_MTU
>> > > +
>> >
>> > Can we drop these btw?
>>
>> Bah. Yeah. Should have just used them directly. I didn't add ETH_MAX_MTU
>> until after doing the virtio_net changes, so I missed that.
>>
>> > > static int virtnet_probe(struct virtio_device *vdev)
>> > > {
>> > > int i, err;
>> > > @@ -1821,6 +1812,10 @@ static int virtnet_probe(struct virtio_device *vdev)
>> > >
>> > > dev->vlan_features = dev->features;
>> > >
>> > > + /* MTU range: 68 - 65535 */
>> > > + dev->min_mtu = MIN_MTU;
>> > > + dev->max_mtu = MAX_MTU;
>> > > +
>> > > /* Configuration may specify what MAC to use. Otherwise random. */
>> > > if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
>> > > virtio_cread_bytes(vdev,
>> > > @@ -1875,8 +1870,10 @@ static int virtnet_probe(struct virtio_device *vdev)
>> > > mtu = virtio_cread16(vdev,
>> > > offsetof(struct virtio_net_config,
>> > > mtu));
>> > > - if (virtnet_change_mtu(dev, mtu))
>> > > + if (mtu < dev->min_mtu || mtu > dev->max_mtu)
>> >
>> > In fact the > max_mtu branch does not make sense since a 16 bit
>> > value can't exceed MAX_MTU.
>>
>> Hm. mtu is declared as an int, not sure if there's any sort of type
>> promotion to be worried about (not an area I know much/anything about).
>
> Not by design, that's for sure.

If you're really worried, we could declare it as a u16. The value
returned from virtio_cread16 is type u16, and there are no type
promotion rules I'm aware of that would do the wrong thing there.

>> Certainly something that could be looked into as a minor optimization,
>> though it's only in a probe path and shouldn't hurt anything, so ... meh?
>
> Right. Aaron said he's working on a patch that essentially does
> dev->max_mtu = mtu after validation, so this part will look
> a bit silly there.

Agreed, but I can do that in my patch if you don't want the extra churn.

-Aaron

2016-10-21 16:22:37

by Sebastian Reichel

[permalink] [raw]
Subject: Re: [PATCH net-next v2 7/9] net: use core MTU range checking in misc drivers

Hi,

On Thu, Oct 20, 2016 at 01:55:22PM -0400, Jarod Wilson wrote:
> hsi/clients/ssi_protocol:
> - use core MTU range checking
> - remove now redundant ssip_pn_set_mtu

Acked-By: Sebastian Reichel <[email protected]>

-- Sebastian


Attachments:
(No filename) (228.00 B)
signature.asc (801.00 B)
Download all attachments

2016-10-22 07:25:56

by Sven Eckelmann

[permalink] [raw]
Subject: Re: [net-next,v2,7/9] net: use core MTU range checking in misc drivers

On Donnerstag, 20. Oktober 2016 13:55:22 CEST Jarod Wilson wrote:
[...]
> batman-adv:
> - set max_mtu
> - remove batadv_interface_change_mtu
> - initialization is a little async, not 100% certain that max_mtu is set
> in the optimal place, don't have hardware to test with

batman-adv is creating a virtual interface - so there are no
hardware requirements (ok, ethernet compatible hardware - even
when only virtual/emulated).

[...]
> diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
> index 49e16b6..112679d 100644
> --- a/net/batman-adv/soft-interface.c
> +++ b/net/batman-adv/soft-interface.c
> @@ -158,17 +158,6 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
> return 0;
> }
>
> -static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu)
> -{
> - /* check ranges */
> - if ((new_mtu < 68) || (new_mtu > batadv_hardif_min_mtu(dev)))
> - return -EINVAL;
> -
> - dev->mtu = new_mtu;
> -
> - return 0;
> -}
> -
> /**
> * batadv_interface_set_rx_mode - set the rx mode of a device
> * @dev: registered network device to modify
> @@ -920,7 +909,6 @@ static const struct net_device_ops batadv_netdev_ops = {
> .ndo_vlan_rx_add_vid = batadv_interface_add_vid,
> .ndo_vlan_rx_kill_vid = batadv_interface_kill_vid,
> .ndo_set_mac_address = batadv_interface_set_mac_addr,
> - .ndo_change_mtu = batadv_interface_change_mtu,
> .ndo_set_rx_mode = batadv_interface_set_rx_mode,
> .ndo_start_xmit = batadv_interface_tx,
> .ndo_validate_addr = eth_validate_addr,
> @@ -987,6 +975,7 @@ struct net_device *batadv_softif_create(struct net *net, const char *name)
> dev_net_set(soft_iface, net);
>
> soft_iface->rtnl_link_ops = &batadv_link_ops;
> + soft_iface->max_mtu = batadv_hardif_min_mtu(soft_iface);
>
> ret = register_netdevice(soft_iface);
> if (ret < 0) {

This looks bogus to me. You are now setting max_mtu during initialization of
the virtual interface. But at this time no slave interfaces were added to the
master batman-adv interface. So the batadv_hardif_min_mtu will not return the
correct value here. Especially if you don't have fragmentation enabled.

So this change looks like a bug to me

Kind regards,
Sven


Attachments:
signature.asc (801.00 B)
This is a digitally signed message part.

2016-10-22 09:36:39

by Stefan Richter

[permalink] [raw]
Subject: Re: [PATCH net-next 6/6] net: use core MTU range checking in misc drivers

On Oct 19 Jarod Wilson wrote:
> On Thu, Oct 20, 2016 at 12:38:46AM +0200, Stefan Richter wrote:
> > On Oct 19 Sabrina Dubroca wrote:
> > > 2016-10-18, 22:33:33 -0400, Jarod Wilson wrote:
> > > [...]
> > > > diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
> > > > index 309311b..b5f125c 100644
> > > > --- a/drivers/firewire/net.c
> > > > +++ b/drivers/firewire/net.c
> > > > @@ -1349,15 +1349,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
> > > > return NETDEV_TX_OK;
> > > > }
> > > >
> > > > -static int fwnet_change_mtu(struct net_device *net, int new_mtu)
> > > > -{
> > > > - if (new_mtu < 68)
> > > > - return -EINVAL;
> > > > -
> > > > - net->mtu = new_mtu;
> > > > - return 0;
> > > > -}
> > > > -
> > >
> > > This doesn't do any upper bound checking.
> >
> > I need to check more closely, but I think the RFC 2734 encapsulation spec
> > and our implementation do not impose a particular upper limit. Though I
> > guess it's bad to let userland set arbitrarily large values here.
>
> In which case, that would suggest using IP_MAX_MTU (65535) here.

Probably. I (or somebody) need to check the spec and the code once more.

[...]
> > > > @@ -1481,6 +1471,8 @@ static int fwnet_probe(struct fw_unit *unit,
> > > > max_mtu = (1 << (card->max_receive + 1))
> > > > - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> > > > net->mtu = min(1500U, max_mtu);
> > > > + net->min_mtu = ETH_MIN_MTU;
> > > > + net->max_mtu = net->mtu;
> > >
> > > But that will now prevent increasing the MTU above the initial value?
> >
> > Indeed, therefore NAK.
>
> However, there's an explicit calculation for 'max_mtu' right there that I
> glazed right over. It would seem perhaps *that* should be used for
> net->max_mtu here, no?

No. This 'max_mtu' here is not the absolute maximum. It is only an
initial MTU which has the property that link fragmentation is not
going to happen (if all other peers will at least as capable as this
node).
--
Stefan Richter
-======----- =-=- =-==-
http://arcgraph.de/sr/

2016-10-22 18:52:29

by Stefan Richter

[permalink] [raw]
Subject: Re: [PATCH net-next 6/6] net: use core MTU range checking in misc drivers

On Oct 22 Stefan Richter wrote:
> On Oct 19 Jarod Wilson wrote:
> > On Thu, Oct 20, 2016 at 12:38:46AM +0200, Stefan Richter wrote:
> > > On Oct 19 Sabrina Dubroca wrote:
> > > > 2016-10-18, 22:33:33 -0400, Jarod Wilson wrote:
[...]
> > > > > @@ -1481,6 +1471,8 @@ static int fwnet_probe(struct fw_unit *unit,
> > > > > max_mtu = (1 << (card->max_receive + 1))
> > > > > - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> > > > > net->mtu = min(1500U, max_mtu);
> > > > > + net->min_mtu = ETH_MIN_MTU;
> > > > > + net->max_mtu = net->mtu;
> > > >
> > > > But that will now prevent increasing the MTU above the initial value?
> > >
> > > Indeed, therefore NAK.
> >
> > However, there's an explicit calculation for 'max_mtu' right there that I
> > glazed right over. It would seem perhaps *that* should be used for
> > net->max_mtu here, no?
>
> No. This 'max_mtu' here is not the absolute maximum. It is only an
> initial MTU which has the property that link fragmentation is not
> going to happen (if all other peers will at least as capable as this
> node).

Besides, card->max_receive is about what the card can receive (at the IEEE
1394 link layer), not about what the card can send.
--
Stefan Richter
-======----- =-=- =-==-
http://arcgraph.de/sr/

2016-10-22 19:17:04

by Stefan Richter

[permalink] [raw]
Subject: Re: [PATCH net-next v2 7/9] net: use core MTU range checking in misc drivers

On Oct 20 Jarod Wilson wrote:
> firewire-net:
> - set min/max_mtu
> - remove fwnet_change_mtu
[...]
> --- a/drivers/firewire/net.c
> +++ b/drivers/firewire/net.c
[...]
> @@ -1478,9 +1467,10 @@ static int fwnet_probe(struct fw_unit *unit,
> * Use the RFC 2734 default 1500 octets or the maximum payload
> * as initial MTU
> */
> - max_mtu = (1 << (card->max_receive + 1))
> - - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> - net->mtu = min(1500U, max_mtu);
> + net->max_mtu = (1 << (card->max_receive + 1))
> + - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> + net->mtu = min(1500U, net->max_mtu);
> + net->min_mtu = ETH_MIN_MTU;
>
> /* Set our hardware address while we're at it */
> ha = (union fwnet_hwaddr *)net->dev_addr;

Please preserve the current behavior, i.e. do not enforce any particular
upper bound. (Especially none based on the local link layer controller's
max_receive parameter.)

BTW, after having read RFC 2734, RFC 3146, and the code, I am convinced
that net->mtu should be initialized to 1500, not less. But such a change
should be done in a separate patch.
--
Stefan Richter
-======----- =-=- =-==-
http://arcgraph.de/sr/

2016-10-22 19:28:16

by Stefan Richter

[permalink] [raw]
Subject: Re: [PATCH net-next v2 7/9] net: use core MTU range checking in misc drivers

Adding Cc: linux1394-devel, dropping several Ccs, no additional comment.

On Oct 22 Stefan Richter wrote:
> On Oct 20 Jarod Wilson wrote:
> > firewire-net:
> > - set min/max_mtu
> > - remove fwnet_change_mtu
> [...]
> > --- a/drivers/firewire/net.c
> > +++ b/drivers/firewire/net.c
> > @@ -1349,15 +1349,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff
> > *skb, struct net_device *net) return NETDEV_TX_OK;
> > }
> >
> > -static int fwnet_change_mtu(struct net_device *net, int new_mtu)
> > -{
> > - if (new_mtu < 68)
> > - return -EINVAL;
> > -
> > - net->mtu = new_mtu;
> > - return 0;
> > -}
> > -
> > static const struct ethtool_ops fwnet_ethtool_ops = {
> > .get_link = ethtool_op_get_link,
> > };
> > @@ -1366,7 +1357,6 @@ static const struct net_device_ops
> > fwnet_netdev_ops = { .ndo_open = fwnet_open,
> > .ndo_stop = fwnet_stop,
> > .ndo_start_xmit = fwnet_tx,
> > - .ndo_change_mtu = fwnet_change_mtu,
> > };
> >
> > static void fwnet_init_dev(struct net_device *net)
> > @@ -1435,7 +1425,6 @@ static int fwnet_probe(struct fw_unit *unit,
> > struct net_device *net;
> > bool allocated_netdev = false;
> > struct fwnet_device *dev;
> > - unsigned max_mtu;
> > int ret;
> > union fwnet_hwaddr *ha;
> >
> > @@ -1478,9 +1467,10 @@ static int fwnet_probe(struct fw_unit *unit,
> > * Use the RFC 2734 default 1500 octets or the maximum payload
> > * as initial MTU
> > */
> > - max_mtu = (1 << (card->max_receive + 1))
> > - - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> > - net->mtu = min(1500U, max_mtu);
> > + net->max_mtu = (1 << (card->max_receive + 1))
> > + - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> > + net->mtu = min(1500U, net->max_mtu);
> > + net->min_mtu = ETH_MIN_MTU;
> >
> > /* Set our hardware address while we're at it */
> > ha = (union fwnet_hwaddr *)net->dev_addr;
>
> Please preserve the current behavior, i.e. do not enforce any particular
> upper bound. (Especially none based on the local link layer controller's
> max_receive parameter.)
>
> BTW, after having read RFC 2734, RFC 3146, and the code, I am convinced
> that net->mtu should be initialized to 1500, not less. But such a change
> should be done in a separate patch.
--
Stefan Richter
-======----- =-=- =-==-
http://arcgraph.de/sr/

2016-10-23 01:18:46

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next v2 7/9] net: use core MTU range checking in misc drivers

On Sat, Oct 22, 2016 at 09:27:59PM +0200, Stefan Richter wrote:
> Adding Cc: linux1394-devel, dropping several Ccs, no additional comment.
>
> On Oct 22 Stefan Richter wrote:
> > On Oct 20 Jarod Wilson wrote:
> > > firewire-net:
> > > - set min/max_mtu
> > > - remove fwnet_change_mtu
> > [...]
> > > --- a/drivers/firewire/net.c
> > > +++ b/drivers/firewire/net.c
> > > @@ -1349,15 +1349,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff
> > > *skb, struct net_device *net) return NETDEV_TX_OK;
> > > }
> > >
> > > -static int fwnet_change_mtu(struct net_device *net, int new_mtu)
> > > -{
> > > - if (new_mtu < 68)
> > > - return -EINVAL;
> > > -
> > > - net->mtu = new_mtu;
> > > - return 0;
> > > -}
> > > -
> > > static const struct ethtool_ops fwnet_ethtool_ops = {
> > > .get_link = ethtool_op_get_link,
> > > };
> > > @@ -1366,7 +1357,6 @@ static const struct net_device_ops
> > > fwnet_netdev_ops = { .ndo_open = fwnet_open,
> > > .ndo_stop = fwnet_stop,
> > > .ndo_start_xmit = fwnet_tx,
> > > - .ndo_change_mtu = fwnet_change_mtu,
> > > };
> > >
> > > static void fwnet_init_dev(struct net_device *net)
> > > @@ -1435,7 +1425,6 @@ static int fwnet_probe(struct fw_unit *unit,
> > > struct net_device *net;
> > > bool allocated_netdev = false;
> > > struct fwnet_device *dev;
> > > - unsigned max_mtu;
> > > int ret;
> > > union fwnet_hwaddr *ha;
> > >
> > > @@ -1478,9 +1467,10 @@ static int fwnet_probe(struct fw_unit *unit,
> > > * Use the RFC 2734 default 1500 octets or the maximum payload
> > > * as initial MTU
> > > */
> > > - max_mtu = (1 << (card->max_receive + 1))
> > > - - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> > > - net->mtu = min(1500U, max_mtu);
> > > + net->max_mtu = (1 << (card->max_receive + 1))
> > > + - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
> > > + net->mtu = min(1500U, net->max_mtu);
> > > + net->min_mtu = ETH_MIN_MTU;
> > >
> > > /* Set our hardware address while we're at it */
> > > ha = (union fwnet_hwaddr *)net->dev_addr;
> >
> > Please preserve the current behavior, i.e. do not enforce any particular
> > upper bound. (Especially none based on the local link layer controller's
> > max_receive parameter.)
> >
> > BTW, after having read RFC 2734, RFC 3146, and the code, I am convinced
> > that net->mtu should be initialized to 1500, not less. But such a change
> > should be done in a separate patch.

Okay, since it's already merged in net-next, I can do a follow-up patch
here to set max_mtu to ETH_MAX_MTU (65535), which is the largest possible
size the kernel can handle, so far as I can tell. But as long as I'm going
to be in here, if we just want to use an initial mtu of 1500, I could
clean that up at the same time, and entirely remove the max_mtu
calculation stuff, if that's what you think is more correct here.

--
Jarod Wilson
[email protected]

2016-10-23 14:29:27

by Stefan Richter

[permalink] [raw]
Subject: [PATCH net-next 1/2] firewire: net: fix maximum possible MTU

Commit b3e3893e1253 ("net: use core MTU range checking in misc drivers")
mistakenly introduced an upper limit for firewire-net's MTU based on the
local link layer controller's reception capability. Revert this. Neither
RFC 2734 nor our implementation impose any particular upper limit.

Actually, to be on the safe side and to make the code explicit, set
ETH_MAX_MTU = 65535 as upper limit now.

(I replaced sizeof(struct rfc2734_header) by the equivalent
RFC2374_FRAG_HDR_SIZE in order to avoid distracting long/int conversions.)

Fixes: b3e3893e1253('net: use core MTU range checking in misc drivers')
CC: [email protected]
CC: [email protected]
CC: Jarod Wilson <[email protected]>
Signed-off-by: Stefan Richter <[email protected]>
---
drivers/firewire/net.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 8430222151fc..99379542b263 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -1467,10 +1467,11 @@ static int fwnet_probe(struct fw_unit *unit,
* Use the RFC 2734 default 1500 octets or the maximum payload
* as initial MTU
*/
- net->max_mtu = (1 << (card->max_receive + 1))
- - sizeof(struct rfc2734_header) - IEEE1394_GASP_HDR_SIZE;
- net->mtu = min(1500U, net->max_mtu);
+ net->mtu = min(1500U,
+ (1U << (card->max_receive + 1))
+ - RFC2374_FRAG_HDR_SIZE - IEEE1394_GASP_HDR_SIZE);
net->min_mtu = ETH_MIN_MTU;
+ net->max_mtu = ETH_MAX_MTU;

/* Set our hardware address while we're at it */
ha = (union fwnet_hwaddr *)net->dev_addr;
--
Stefan Richter
-======----- =-=- =-===
http://arcgraph.de/sr/

2016-10-23 14:31:14

by Stefan Richter

[permalink] [raw]
Subject: [PATCH net-next 2/2] firewire: net: set initial MTU = 1500 unconditionally, fix IPv6 on some CardBus cards

firewire-net, like the older eth1394 driver, reduced the initial MTU to
less than 1500 octets if the local link layer controller's asynchronous
packet reception limit was lower.

This is bogus, since this reception limit does not have anything to do
with the transmission limit. Neither did this reduction affect the TX
path positively, nor could it prevent link fragmentation at the RX path.

Many FireWire CardBus cards have a max_rec of 9, causing an initial MTU
of 1024 - 16 = 1008. RFC 2734 and RFC 3146 allow a minimum max_rec = 8,
which would result in an initial MTU of 512 - 16 = 496. On such cards,
IPv6 could only be employed if the MTU was manually increased to 1280 or
more, i.e. IPv6 would not work without intervention from userland.

We now always initialize the MTU to 1500, which is the default according
to RFC 2734 and RFC 3146.

On a VIA VT6316 based CardBus card which was affected by this, changing
the MTU from 1008 to 1500 also increases TX bandwidth by 6 %.
RX remains unaffected.

CC: [email protected]
CC: [email protected]
CC: Jarod Wilson <[email protected]>
Signed-off-by: Stefan Richter <[email protected]>
---
drivers/firewire/net.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 99379542b263..03715e7d9d92 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -1463,13 +1463,7 @@ static int fwnet_probe(struct fw_unit *unit,
goto out;
dev->local_fifo = dev->handler.offset;

- /*
- * Use the RFC 2734 default 1500 octets or the maximum payload
- * as initial MTU
- */
- net->mtu = min(1500U,
- (1U << (card->max_receive + 1))
- - RFC2374_FRAG_HDR_SIZE - IEEE1394_GASP_HDR_SIZE);
+ net->mtu = 1500U;
net->min_mtu = ETH_MIN_MTU;
net->max_mtu = ETH_MAX_MTU;

--
Stefan Richter
-======----- =-=- =-===
http://arcgraph.de/sr/

2016-10-24 01:50:20

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 2/2] firewire: net: set initial MTU = 1500 unconditionally, fix IPv6 on some CardBus cards

On Sun, Oct 23, 2016 at 04:30:56PM +0200, Stefan Richter wrote:
> firewire-net, like the older eth1394 driver, reduced the initial MTU to
> less than 1500 octets if the local link layer controller's asynchronous
> packet reception limit was lower.
>
> This is bogus, since this reception limit does not have anything to do
> with the transmission limit. Neither did this reduction affect the TX
> path positively, nor could it prevent link fragmentation at the RX path.
>
> Many FireWire CardBus cards have a max_rec of 9, causing an initial MTU
> of 1024 - 16 = 1008. RFC 2734 and RFC 3146 allow a minimum max_rec = 8,
> which would result in an initial MTU of 512 - 16 = 496. On such cards,
> IPv6 could only be employed if the MTU was manually increased to 1280 or
> more, i.e. IPv6 would not work without intervention from userland.
>
> We now always initialize the MTU to 1500, which is the default according
> to RFC 2734 and RFC 3146.
>
> On a VIA VT6316 based CardBus card which was affected by this, changing
> the MTU from 1008 to 1500 also increases TX bandwidth by 6 %.
> RX remains unaffected.
>
> CC: [email protected]
> CC: [email protected]
> CC: Jarod Wilson <[email protected]>
> Signed-off-by: Stefan Richter <[email protected]>
> ---
> drivers/firewire/net.c | 8 +-------
> 1 file changed, 1 insertion(+), 7 deletions(-)
>
> diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
> index 99379542b263..03715e7d9d92 100644
> --- a/drivers/firewire/net.c
> +++ b/drivers/firewire/net.c
> @@ -1463,13 +1463,7 @@ static int fwnet_probe(struct fw_unit *unit,
> goto out;
> dev->local_fifo = dev->handler.offset;
>
> - /*
> - * Use the RFC 2734 default 1500 octets or the maximum payload
> - * as initial MTU
> - */
> - net->mtu = min(1500U,
> - (1U << (card->max_receive + 1))
> - - RFC2374_FRAG_HDR_SIZE - IEEE1394_GASP_HDR_SIZE);
> + net->mtu = 1500U;

Should be able to do just net->mtu = ETH_DATA_LEN;

--
Jarod Wilson
[email protected]

2016-10-24 01:50:47

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 1/2] firewire: net: fix maximum possible MTU

On Sun, Oct 23, 2016 at 04:29:03PM +0200, Stefan Richter wrote:
> Commit b3e3893e1253 ("net: use core MTU range checking in misc drivers")
> mistakenly introduced an upper limit for firewire-net's MTU based on the
> local link layer controller's reception capability. Revert this. Neither
> RFC 2734 nor our implementation impose any particular upper limit.
>
> Actually, to be on the safe side and to make the code explicit, set
> ETH_MAX_MTU = 65535 as upper limit now.
>
> (I replaced sizeof(struct rfc2734_header) by the equivalent
> RFC2374_FRAG_HDR_SIZE in order to avoid distracting long/int conversions.)
>
> Fixes: b3e3893e1253('net: use core MTU range checking in misc drivers')
> CC: [email protected]
> CC: [email protected]
> CC: Jarod Wilson <[email protected]>
> Signed-off-by: Stefan Richter <[email protected]>

Acked-by: Jarod Wilson <[email protected]>

--
Jarod Wilson
[email protected]

2016-10-24 12:26:39

by Stefan Richter

[permalink] [raw]
Subject: [PATCH net-next 2/2 v2] firewire: net: set initial MTU = 1500 unconditionally, fix IPv6 on some CardBus cards

firewire-net, like the older eth1394 driver, reduced the initial MTU to
less than 1500 octets if the local link layer controller's asynchronous
packet reception limit was lower.

This is bogus, since this reception limit does not have anything to do
with the transmission limit. Neither did this reduction affect the TX
path positively, nor could it prevent link fragmentation at the RX path.

Many FireWire CardBus cards have a max_rec of 9, causing an initial MTU
of 1024 - 16 = 1008. RFC 2734 and RFC 3146 allow a minimum max_rec = 8,
which would result in an initial MTU of 512 - 16 = 496. On such cards,
IPv6 could only be employed if the MTU was manually increased to 1280 or
more, i.e. IPv6 would not work without intervention from userland.

We now always initialize the MTU to 1500, which is the default according
to RFC 2734 and RFC 3146.

On a VIA VT6316 based CardBus card which was affected by this, changing
the MTU from 1008 to 1500 also increases TX bandwidth by 6 %.
RX remains unaffected.

CC: [email protected]
CC: [email protected]
CC: Jarod Wilson <[email protected]>
Signed-off-by: Stefan Richter <[email protected]>
---
v2: use ETH_DATA_LEN, add comment

drivers/firewire/net.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 99379542b263..29dbcba38f59 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -1463,13 +1463,8 @@ static int fwnet_probe(struct fw_unit *unit,
goto out;
dev->local_fifo = dev->handler.offset;

- /*
- * Use the RFC 2734 default 1500 octets or the maximum payload
- * as initial MTU
- */
- net->mtu = min(1500U,
- (1U << (card->max_receive + 1))
- - RFC2374_FRAG_HDR_SIZE - IEEE1394_GASP_HDR_SIZE);
+ /* MTU range: 68 - 65535, RFC 2734 default: 1500 */
+ net->mtu = ETH_DATA_LEN;
net->min_mtu = ETH_MIN_MTU;
net->max_mtu = ETH_MAX_MTU;

--
2.7.3



--
Stefan Richter
-======----- =-=- ==---
http://arcgraph.de/sr/

2016-10-25 03:05:26

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net-next 2/2 v2] firewire: net: set initial MTU = 1500 unconditionally, fix IPv6 on some CardBus cards

On Mon, Oct 24, 2016 at 02:26:13PM +0200, Stefan Richter wrote:
> firewire-net, like the older eth1394 driver, reduced the initial MTU to
> less than 1500 octets if the local link layer controller's asynchronous
> packet reception limit was lower.
>
> This is bogus, since this reception limit does not have anything to do
> with the transmission limit. Neither did this reduction affect the TX
> path positively, nor could it prevent link fragmentation at the RX path.
>
> Many FireWire CardBus cards have a max_rec of 9, causing an initial MTU
> of 1024 - 16 = 1008. RFC 2734 and RFC 3146 allow a minimum max_rec = 8,
> which would result in an initial MTU of 512 - 16 = 496. On such cards,
> IPv6 could only be employed if the MTU was manually increased to 1280 or
> more, i.e. IPv6 would not work without intervention from userland.
>
> We now always initialize the MTU to 1500, which is the default according
> to RFC 2734 and RFC 3146.
>
> On a VIA VT6316 based CardBus card which was affected by this, changing
> the MTU from 1008 to 1500 also increases TX bandwidth by 6 %.
> RX remains unaffected.
>
> CC: [email protected]
> CC: [email protected]
> CC: Jarod Wilson <[email protected]>
> Signed-off-by: Stefan Richter <[email protected]>
> ---
> v2: use ETH_DATA_LEN, add comment

Acked-by: Jarod Wilson <[email protected]>

--
Jarod Wilson
[email protected]

2016-10-26 21:29:58

by David Miller

[permalink] [raw]
Subject: Re: [PATCH net-next 1/2] firewire: net: fix maximum possible MTU

From: Stefan Richter <[email protected]>
Date: Sun, 23 Oct 2016 16:29:03 +0200

> Commit b3e3893e1253 ("net: use core MTU range checking in misc drivers")
> mistakenly introduced an upper limit for firewire-net's MTU based on the
> local link layer controller's reception capability. Revert this. Neither
> RFC 2734 nor our implementation impose any particular upper limit.
>
> Actually, to be on the safe side and to make the code explicit, set
> ETH_MAX_MTU = 65535 as upper limit now.
>
> (I replaced sizeof(struct rfc2734_header) by the equivalent
> RFC2374_FRAG_HDR_SIZE in order to avoid distracting long/int conversions.)
>
> Fixes: b3e3893e1253('net: use core MTU range checking in misc drivers')
> CC: [email protected]
> CC: [email protected]
> CC: Jarod Wilson <[email protected]>
> Signed-off-by: Stefan Richter <[email protected]>

Applied.

2016-10-26 21:29:56

by David Miller

[permalink] [raw]
Subject: Re: [PATCH net-next 2/2] firewire: net: set initial MTU = 1500 unconditionally, fix IPv6 on some CardBus cards

From: Stefan Richter <[email protected]>
Date: Sun, 23 Oct 2016 16:30:56 +0200

> firewire-net, like the older eth1394 driver, reduced the initial MTU to
> less than 1500 octets if the local link layer controller's asynchronous
> packet reception limit was lower.
>
> This is bogus, since this reception limit does not have anything to do
> with the transmission limit. Neither did this reduction affect the TX
> path positively, nor could it prevent link fragmentation at the RX path.
>
> Many FireWire CardBus cards have a max_rec of 9, causing an initial MTU
> of 1024 - 16 = 1008. RFC 2734 and RFC 3146 allow a minimum max_rec = 8,
> which would result in an initial MTU of 512 - 16 = 496. On such cards,
> IPv6 could only be employed if the MTU was manually increased to 1280 or
> more, i.e. IPv6 would not work without intervention from userland.
>
> We now always initialize the MTU to 1500, which is the default according
> to RFC 2734 and RFC 3146.
>
> On a VIA VT6316 based CardBus card which was affected by this, changing
> the MTU from 1008 to 1500 also increases TX bandwidth by 6 %.
> RX remains unaffected.
>
> CC: [email protected]
> CC: [email protected]
> CC: Jarod Wilson <[email protected]>
> Signed-off-by: Stefan Richter <[email protected]>

Applied.

2016-10-29 20:17:20

by Stefan Richter

[permalink] [raw]
Subject: [PATCH net-next] firewire: net: really fix maximum possible MTU

The maximum unicast datagram size /without/ link fragmentation is
4096 - 4 = 4092 (max IEEE 1394 async payload size at >= S800 bus speed,
minus unfragmented encapssulation header). Max broadcast datagram size
without fragmentation is 8 bytes less than that (due to GASP header).

The maximum datagram size /with/ link fragmentation is 0xfff = 4095
for unicast and broadcast. This is because the RFC 2734 fragment
encapsulation header field for datagram size is only 12 bits wide.

Fixes: 5d48f00d836a('firewire: net: fix maximum possible MTU')
Signed-off-by: Stefan Richter <[email protected]>
---
drivers/firewire/net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 03715e7d9d92..363fc5ec1a4e 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -1465,7 +1465,7 @@ static int fwnet_probe(struct fw_unit *unit,

net->mtu = 1500U;
net->min_mtu = ETH_MIN_MTU;
- net->max_mtu = ETH_MAX_MTU;
+ net->max_mtu = 0xfff;

/* Set our hardware address while we're at it */
ha = (union fwnet_hwaddr *)net->dev_addr;
--
Stefan Richter
-======----- =-=- ===-=
http://arcgraph.de/sr/

2016-10-30 03:01:08

by David Miller

[permalink] [raw]
Subject: Re: [PATCH net-next] firewire: net: really fix maximum possible MTU

From: Stefan Richter <[email protected]>
Date: Sat, 29 Oct 2016 22:16:58 +0200

> The maximum unicast datagram size /without/ link fragmentation is
> 4096 - 4 = 4092 (max IEEE 1394 async payload size at >= S800 bus speed,
> minus unfragmented encapssulation header). Max broadcast datagram size
> without fragmentation is 8 bytes less than that (due to GASP header).
>
> The maximum datagram size /with/ link fragmentation is 0xfff = 4095
> for unicast and broadcast. This is because the RFC 2734 fragment
> encapsulation header field for datagram size is only 12 bits wide.
>
> Fixes: 5d48f00d836a('firewire: net: fix maximum possible MTU')
> Signed-off-by: Stefan Richter <[email protected]>

Applied, thanks.