Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: netdev@vger.kernel.org
CC: Woojung Huh <woojung.huh@microchip.com>
CC: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
CC: Hayes Wang <hayeswang@realtek.com>
CC: Oliver Neukum <oneukum@suse.com>
CC: Steve Glendinning <steve.glendinning@shawell.net>
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jarod Wilson and committed by
David S. Miller
f77f0aee d894be57

+25 -44
+1 -3
drivers/net/usb/asix_devices.c
··· 1026 1026 1027 1027 netdev_dbg(dev->net, "ax88178_change_mtu() new_mtu=%d\n", new_mtu); 1028 1028 1029 - if (new_mtu <= 0 || ll_mtu > 16384) 1030 - return -EINVAL; 1031 - 1032 1029 if ((ll_mtu % dev->maxpacket) == 0) 1033 1030 return -EDOM; 1034 1031 ··· 1078 1081 1079 1082 dev->net->netdev_ops = &ax88178_netdev_ops; 1080 1083 dev->net->ethtool_ops = &ax88178_ethtool_ops; 1084 + dev->net->max_mtu = 16384 - (dev->net->hard_header_len + 4); 1081 1085 1082 1086 /* Blink LEDS so users know driver saw dongle */ 1083 1087 asix_sw_reset(dev, 0, 0);
+1 -3
drivers/net/usb/ax88179_178a.c
··· 907 907 struct usbnet *dev = netdev_priv(net); 908 908 u16 tmp16; 909 909 910 - if (new_mtu <= 0 || new_mtu > 4088) 911 - return -EINVAL; 912 - 913 910 net->mtu = new_mtu; 914 911 dev->hard_mtu = net->mtu + net->hard_header_len; 915 912 ··· 1263 1266 dev->net->netdev_ops = &ax88179_netdev_ops; 1264 1267 dev->net->ethtool_ops = &ax88179_ethtool_ops; 1265 1268 dev->net->needed_headroom = 8; 1269 + dev->net->max_mtu = 4088; 1266 1270 1267 1271 /* Initialize MII structure */ 1268 1272 dev->mii.dev = dev->net;
+2 -10
drivers/net/usb/cdc-phonet.c
··· 276 276 return -ENOIOCTLCMD; 277 277 } 278 278 279 - static int usbpn_set_mtu(struct net_device *dev, int new_mtu) 280 - { 281 - if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU)) 282 - return -EINVAL; 283 - 284 - dev->mtu = new_mtu; 285 - return 0; 286 - } 287 - 288 279 static const struct net_device_ops usbpn_ops = { 289 280 .ndo_open = usbpn_open, 290 281 .ndo_stop = usbpn_close, 291 282 .ndo_start_xmit = usbpn_xmit, 292 283 .ndo_do_ioctl = usbpn_ioctl, 293 - .ndo_change_mtu = usbpn_set_mtu, 294 284 }; 295 285 296 286 static void usbpn_setup(struct net_device *dev) ··· 291 301 dev->type = ARPHRD_PHONET; 292 302 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 293 303 dev->mtu = PHONET_MAX_MTU; 304 + dev->min_mtu = PHONET_MIN_MTU; 305 + dev->max_mtu = PHONET_MAX_MTU; 294 306 dev->hard_header_len = 1; 295 307 dev->dev_addr[0] = PN_MEDIA_USB; 296 308 dev->addr_len = 1;
+1 -4
drivers/net/usb/cdc_ncm.c
··· 740 740 int cdc_ncm_change_mtu(struct net_device *net, int new_mtu) 741 741 { 742 742 struct usbnet *dev = netdev_priv(net); 743 - int maxmtu = cdc_ncm_max_dgram_size(dev) - cdc_ncm_eth_hlen(dev); 744 - 745 - if (new_mtu <= 0 || new_mtu > maxmtu) 746 - return -EINVAL; 747 743 748 744 net->mtu = new_mtu; 749 745 cdc_ncm_set_dgram_size(dev, new_mtu + cdc_ncm_eth_hlen(dev)); ··· 905 909 906 910 /* must handle MTU changes */ 907 911 dev->net->netdev_ops = &cdc_ncm_netdev_ops; 912 + dev->net->max_mtu = cdc_ncm_max_dgram_size(dev) - cdc_ncm_eth_hlen(dev); 908 913 909 914 return 0; 910 915
+3 -5
drivers/net/usb/lan78xx.c
··· 1980 1980 int old_rx_urb_size = dev->rx_urb_size; 1981 1981 int ret; 1982 1982 1983 - if (new_mtu > MAX_SINGLE_PACKET_SIZE) 1984 - return -EINVAL; 1985 - 1986 - if (new_mtu <= 0) 1987 - return -EINVAL; 1988 1983 /* no second zero-length packet read wanted after mtu-sized packets */ 1989 1984 if ((ll_mtu % dev->maxpacket) == 0) 1990 1985 return -EDOM; ··· 3382 3387 3383 3388 if (netdev->mtu > (dev->hard_mtu - netdev->hard_header_len)) 3384 3389 netdev->mtu = dev->hard_mtu - netdev->hard_header_len; 3390 + 3391 + /* MTU range: 68 - 9000 */ 3392 + netdev->max_mtu = MAX_SINGLE_PACKET_SIZE; 3385 3393 3386 3394 dev->ep_blkin = (intf->cur_altsetting)->endpoint + 0; 3387 3395 dev->ep_blkout = (intf->cur_altsetting)->endpoint + 1;
+12 -3
drivers/net/usb/r8152.c
··· 4119 4119 break; 4120 4120 } 4121 4121 4122 - if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU) 4123 - return -EINVAL; 4124 - 4125 4122 ret = usb_autopm_get_interface(tp->intf); 4126 4123 if (ret < 0) 4127 4124 return ret; ··· 4307 4310 4308 4311 netdev->ethtool_ops = &ops; 4309 4312 netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE); 4313 + 4314 + /* MTU range: 68 - 1500 or 9194 */ 4315 + netdev->min_mtu = ETH_MIN_MTU; 4316 + switch (tp->version) { 4317 + case RTL_VER_01: 4318 + case RTL_VER_02: 4319 + netdev->max_mtu = ETH_DATA_LEN; 4320 + break; 4321 + default: 4322 + netdev->max_mtu = RTL8153_MAX_MTU; 4323 + break; 4324 + } 4310 4325 4311 4326 tp->mii.dev = netdev; 4312 4327 tp->mii.mdio_read = read_mii_word;
+2 -11
drivers/net/usb/sierra_net.c
··· 165 165 166 166 /* Forward definitions */ 167 167 static void sierra_sync_timer(unsigned long syncdata); 168 - static int sierra_net_change_mtu(struct net_device *net, int new_mtu); 169 168 170 169 /* Our own net device operations structure */ 171 170 static const struct net_device_ops sierra_net_device_ops = { ··· 172 173 .ndo_stop = usbnet_stop, 173 174 .ndo_start_xmit = usbnet_start_xmit, 174 175 .ndo_tx_timeout = usbnet_tx_timeout, 175 - .ndo_change_mtu = sierra_net_change_mtu, 176 + .ndo_change_mtu = usbnet_change_mtu, 176 177 .ndo_set_mac_address = eth_mac_addr, 177 178 .ndo_validate_addr = eth_validate_addr, 178 179 }; ··· 621 622 .nway_reset = usbnet_nway_reset, 622 623 }; 623 624 624 - /* MTU can not be more than 1500 bytes, enforce it. */ 625 - static int sierra_net_change_mtu(struct net_device *net, int new_mtu) 626 - { 627 - if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU) 628 - return -EINVAL; 629 - 630 - return usbnet_change_mtu(net, new_mtu); 631 - } 632 - 633 625 static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) 634 626 { 635 627 int result = 0; ··· 710 720 711 721 dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN; 712 722 dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; 723 + dev->net->max_mtu = SIERRA_NET_MAX_SUPPORTED_MTU; 713 724 714 725 /* Set up the netdev */ 715 726 dev->net->flags |= IFF_NOARP;
+1 -3
drivers/net/usb/smsc75xx.c
··· 925 925 struct usbnet *dev = netdev_priv(netdev); 926 926 int ret; 927 927 928 - if (new_mtu > MAX_SINGLE_PACKET_SIZE) 929 - return -EINVAL; 930 - 931 928 ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN); 932 929 if (ret < 0) { 933 930 netdev_warn(dev->net, "Failed to set mac rx frame length\n"); ··· 1445 1448 dev->net->flags |= IFF_MULTICAST; 1446 1449 dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; 1447 1450 dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; 1451 + dev->net->max_mtu = MAX_SINGLE_PACKET_SIZE; 1448 1452 return 0; 1449 1453 } 1450 1454
+2 -2
drivers/net/usb/usbnet.c
··· 384 384 int old_hard_mtu = dev->hard_mtu; 385 385 int old_rx_urb_size = dev->rx_urb_size; 386 386 387 - if (new_mtu <= 0) 388 - return -EINVAL; 389 387 // no second zero-length packet read wanted after mtu-sized packets 390 388 if ((ll_mtu % dev->maxpacket) == 0) 391 389 return -EDOM; ··· 1667 1669 * bind() should set rx_urb_size in that case. 1668 1670 */ 1669 1671 dev->hard_mtu = net->mtu + net->hard_header_len; 1672 + net->min_mtu = 0; 1673 + net->max_mtu = ETH_MAX_MTU; 1670 1674 1671 1675 net->netdev_ops = &usbnet_netdev_ops; 1672 1676 net->watchdog_timeo = TX_TIMEOUT_JIFFIES;