All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net v2] usbnet: limit max_mtu based on device's hard_mtu
@ 2026-01-19  7:55 Laurent Vivier
  2026-01-21  3:10 ` patchwork-bot+netdevbpf
  2026-05-18  7:21 ` Matthias May
  0 siblings, 2 replies; 5+ messages in thread
From: Laurent Vivier @ 2026-01-19  7:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-usb, Oliver Neukum, Jakub Kicinski, netdev, Laurent Vivier,
	Stefano Brivio

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://gitlab.com/qemu-project/qemu/-/issues/3268 and
    https://bugs.passt.top/attachment.cgi?bugid=189

Fixes: f77f0aee4da4 ("net: use core MTU range checking in USB NIC drivers")
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Link: https://bugs.passt.top/show_bug.cgi?id=189
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
---
 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 {
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net v2] usbnet: limit max_mtu based on device's hard_mtu
  2026-01-19  7:55 [PATCH net v2] usbnet: limit max_mtu based on device's hard_mtu Laurent Vivier
@ 2026-01-21  3:10 ` patchwork-bot+netdevbpf
  2026-05-18  7:21 ` Matthias May
  1 sibling, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-01-21  3:10 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: linux-kernel, linux-usb, oneukum, kuba, netdev, sbrivio

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Mon, 19 Jan 2026 08:55:18 +0100 you 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.
> 
> [...]

Here is the summary with links:
  - [net,v2] usbnet: limit max_mtu based on device's hard_mtu
    https://git.kernel.org/netdev/net/c/c7159e960f14

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net v2] usbnet: limit max_mtu based on device's hard_mtu
  2026-01-19  7:55 [PATCH net v2] usbnet: limit max_mtu based on device's hard_mtu Laurent Vivier
  2026-01-21  3:10 ` patchwork-bot+netdevbpf
@ 2026-05-18  7:21 ` Matthias May
  2026-05-18  7:36   ` Laurent Vivier
  1 sibling, 1 reply; 5+ messages in thread
From: Matthias May @ 2026-05-18  7:21 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: linux-usb, Oliver Neukum, Jakub Kicinski, netdev, Stefano Brivio,
	linux-kernel

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@redhat.com>
> 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@redhat.com>
> ---
>   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

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.

BR
Matthias



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net v2] usbnet: limit max_mtu based on device's hard_mtu
  2026-05-18  7:21 ` Matthias May
@ 2026-05-18  7:36   ` Laurent Vivier
  2026-05-18 11:26     ` Matthias May
  0 siblings, 1 reply; 5+ messages in thread
From: Laurent Vivier @ 2026-05-18  7:36 UTC (permalink / raw)
  To: Matthias May
  Cc: linux-usb, Oliver Neukum, Jakub Kicinski, netdev, Stefano Brivio,
	linux-kernel, stable

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@redhat.com>
>> 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@redhat.com>
>> ---
>>   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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net v2] usbnet: limit max_mtu based on device's hard_mtu
  2026-05-18  7:36   ` Laurent Vivier
@ 2026-05-18 11:26     ` Matthias May
  0 siblings, 0 replies; 5+ messages in thread
From: Matthias May @ 2026-05-18 11:26 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: linux-usb, Oliver Neukum, Jakub Kicinski, netdev, Stefano Brivio,
	linux-kernel, stable

On 18/05/2026 9:36 am, Laurent Vivier wrote:

> 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@redhat.com>
>>> 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@redhat.com>
>>> ---
>>>   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
>
Hi 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


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-05-18 11:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-19  7:55 [PATCH net v2] usbnet: limit max_mtu based on device's hard_mtu Laurent Vivier
2026-01-21  3:10 ` patchwork-bot+netdevbpf
2026-05-18  7:21 ` Matthias May
2026-05-18  7:36   ` Laurent Vivier
2026-05-18 11:26     ` Matthias May

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.