kernel: usbnet: Restore usb%d naming for cdc-ethernet devices with local MAC
authorAhmed Naseef <naseefkm@gmail.com>
Tue, 28 Jan 2025 07:28:31 +0000 (11:28 +0400)
committerRobert Marko <robimarko@gmail.com>
Thu, 6 Mar 2025 14:49:45 +0000 (15:49 +0100)
Prior to commit https://github.com/torvalds/linux/commit/8a7d12d674ac6f2147c18f36d1e15f1a48060edf,
cdc-ethernet USB LTE modems (e.g. Quectel EC200A) were consistently named
usb0. After 8a7d12d67, devices began renaming to eth1 due to an assumption
that local MAC addresses originate exclusively from the kernel. Some
devices provide driver-assigned local MACs, causing point-to-point
interfaces with driver-set MACs to adopt eth%d names instead of usb%d.

Restore the naming exception for point-to-point devices: interfaces
without driver MACs or with driver-provided local MACs will retain the
usb%d convention. This addresses issues reported in [1] and fixed in [2].

[1] https://lore.kernel.org/all/Z00udyMgW6XnAw6h@atmark-techno.com/
[2] https://lore.kernel.org/all/20241203130457.904325-1-asmadeus@codewreck.org/

Tested-by: Ahmed Naseef <naseefkm@gmail.com>
Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/17757
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/generic/pending-6.6/155-usbnet-restore-usb%d-name-exception-for-local-mac-addresses.patch [new file with mode: 0644]

diff --git a/target/linux/generic/pending-6.6/155-usbnet-restore-usb%d-name-exception-for-local-mac-addresses.patch b/target/linux/generic/pending-6.6/155-usbnet-restore-usb%d-name-exception-for-local-mac-addresses.patch
new file mode 100644 (file)
index 0000000..0d32800
--- /dev/null
@@ -0,0 +1,63 @@
+From linux-netdev  Tue Dec 03 13:04:55 2024
+From: Dominique Martinet <asmadeus () codewreck ! org>
+Date: Tue, 03 Dec 2024 13:04:55 +0000
+To: linux-netdev
+Subject: [PATCH] net: usb: usbnet: restore usb%d name exception for local mac addresses
+Message-Id: <20241203130457.904325-1-asmadeus () codewreck ! org>
+X-MARC-Message: https://marc.info/?l=linux-netdev&m=173323431631309
+
+From: Dominique Martinet <dominique.martinet@atmark-techno.com>
+
+The previous commit assumed that local addresses always came from the
+kernel, but some devices hand out local mac addresses so we ended up
+with point-to-point devices with a mac set by the driver, renaming to
+eth%d when they used to be named usb%d.
+
+Userspace should not rely on device name, but for the sake of stability
+restore the local mac address check portion of the naming exception:
+point to point devices which either have no mac set by the driver or
+have a local mac handed out by the driver will keep the usb%d name.
+
+Fixes: 8a7d12d674ac ("net: usb: usbnet: fix name regression")
+Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
+---
+ drivers/net/usb/usbnet.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -178,6 +178,17 @@ int usbnet_get_ethernet_addr(struct usbn
+ }
+ EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr);
++static bool usbnet_needs_usb_name_format(struct usbnet *dev, struct net_device *net)
++{
++      /* Point to point devices which don't have a real MAC address
++       * (or report a fake local one) have historically used the usb%d
++       * naming. Preserve this..
++       */
++      return (dev->driver_info->flags & FLAG_POINTTOPOINT) != 0 &&
++              (is_zero_ether_addr(net->dev_addr) ||
++               is_local_ether_addr(net->dev_addr));
++}
++
+ static void intr_complete (struct urb *urb)
+ {
+       struct usbnet   *dev = urb->context;
+@@ -1766,13 +1777,10 @@ usbnet_probe (struct usb_interface *udev
+               if (status < 0)
+                       goto out1;
+-              // heuristic:  "usb%d" for links we know are two-host,
+-              // else "eth%d" when there's reasonable doubt.  userspace
+-              // can rename the link if it knows better.
++              /* heuristic: rename to "eth%d" if we are not sure this link
++               * is two-host (these links keep "usb%d") */
+               if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
+-                  ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
+-                   /* somebody touched it*/
+-                   !is_zero_ether_addr(net->dev_addr)))
++                  !usbnet_needs_usb_name_format(dev, net))
+                       strscpy(net->name, "eth%d", sizeof(net->name));
+               /* WLAN devices should always be named "wlan%d" */
+               if ((dev->driver_info->flags & FLAG_WLAN) != 0)