Re: [PATCH net v2] usbnet: limit max_mtu based on device's hard_mtu

From: Laurent Vivier

Date: Mon May 18 2026 - 03:44:22 EST


On 5/18/26 09:21, Matthias May wrote:
On 19/01/2026 8:55 am, Laurent Vivier wrote:
The usbnet driver initializes net->max_mtu to ETH_MAX_MTU before calling
the device's bind() callback. When the bind() callback sets
dev->hard_mtu based the device's actual capability (from CDC Ethernet's
wMaxSegmentSize descriptor), max_mtu is never updated to reflect this
hardware limitation).

This allows userspace (DHCP or IPv6 RA) to configure MTU larger than the
device can handle, leading to silent packet drops when the backend sends
packet exceeding the device's buffer size.

Fix this by limiting net->max_mtu to the device's hard_mtu after the
bind callback returns.

See https://urldefense.com/v3/__https://gitlab.com/qemu-project/qemu/-/issues/3268__;!! I9LPvj3b!H-nIZIscCCh_2FnbJInagPxXTe0XcNu58-8k3NqGYKRdDy8LBOBjWiTIc1E- cC2wnv91MtZrak2pu7K-4cU$  and
     https://urldefense.com/v3/__https://bugs.passt.top/attachment.cgi?bugid=189__;!! I9LPvj3b!H-nIZIscCCh_2FnbJInagPxXTe0XcNu58-8k3NqGYKRdDy8LBOBjWiTIc1E- cC2wnv91MtZrak2pq4lrvZI$

Fixes: f77f0aee4da4 ("net: use core MTU range checking in USB NIC drivers")
Signed-off-by: Laurent Vivier <lvivier@xxxxxxxxxx>
Link: https://urldefense.com/v3/__https://bugs.passt.top/show_bug.cgi?id=189__;!! I9LPvj3b!H-nIZIscCCh_2FnbJInagPxXTe0XcNu58-8k3NqGYKRdDy8LBOBjWiTIc1E- cC2wnv91MtZrak2p8csXaww$
Reviewed-by: Stefano Brivio <sbrivio@xxxxxxxxxx>
---
  drivers/net/usb/usbnet.c | 9 ++++++---
  1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 36742e64cff7..1093c2a412d9 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1821,9 +1821,12 @@ usbnet_probe(struct usb_interface *udev, const struct usb_device_id *prod)
          if ((dev->driver_info->flags & FLAG_NOARP) != 0)
              net->flags |= IFF_NOARP;
-        /* maybe the remote can't receive an Ethernet MTU */
-        if (net->mtu > (dev->hard_mtu - net->hard_header_len))
-            net->mtu = dev->hard_mtu - net->hard_header_len;
+        if (net->max_mtu > (dev->hard_mtu - net->hard_header_len))
+            net->max_mtu = dev->hard_mtu - net->hard_header_len;
+
+        if (net->mtu > net->max_mtu)
+            net->mtu = net->max_mtu;
+
      } else if (!info->in || !info->out)
          status = usbnet_get_endpoints(dev, udev);
      else {

Hi Laurent

Hi Matthias,


This change was backported to 6.6.* and caused a regression with wwan devices via USB when using a mux.

Tested on a Quectel EM12 running the firmware EM12GPAR01A21M4G_01.300.01.300.

Tue May  5 09:49:35.638 2026 kern.info kernel: [   10.819620] qmi_wwan 1-1.2:1.4: cdc- wdm0: USB WDM device
Tue May  5 09:49:35.638 2026 kern.info kernel: [   10.829601] qmi_wwan 1-1.2:1.4 cellular0: register 'qmi_wwan' at usb-fsl-ehci.0-1.2, WWAN/QMI device, 6a:c3:49:88:47:b1
Tue May  5 09:49:35.638 2026 kern.info kernel: [   10.840579] usbcore: registered new interface driver qmi_wwan

The parent interface (we renamed it "cellular0") requires an MTU of 1504 (4 bytes overhead from the muxer).
The actual wwan0, wwan1 interfaces have an MTU of 1500.

With this change it's no longer possible to set an MTU of 1504 on cellular0.

This should be fixed by

55f854dd5bdd ("qmi_wwan: allow max_mtu above hard_mtu to control rx_urb_size") which is in v7.0.

Could you have a try?

Thanks,
Laurent