Re: [PATCH net v2] usbnet: limit max_mtu based on device's hard_mtu
From: Matthias May
Date: Mon May 18 2026 - 07:36:28 EST
On 18/05/2026 9:36 am, Laurent Vivier wrote:
On 5/18/26 09:21, Matthias May wrote:Hi Laurent
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
Thank you for the pointer to your patch.
The commit is missing on the 6.6 branch.
It applies cleanly on 6.6.140 and seems to work well for my case.
BR
Matthias