Open xbipin opened 7 years ago
it does on a windows machine but not on a freebsd machine even though its recognized as a RNDIS gadget
When I had a similar issue I needed to add g_ether.use_eem=0 so the other (Linux in my case) end used cdc_ether rather than cdc_eem where IIRC the protocol doesn't support passing a MAC address - might be worth a try.
i tried but its still same, below is what appears in freebsd
ugen0.2: <Linux 4.9.37+ with 20980000.usb> at usbus0
cdce0:
i added that inline in the cmdline.txt, correct me if im wrong
is there a way to set a vendor and product id so freebsd can recognize it as a know device so it can read the mac id which the rndis gadget supplies?
Hi,
I am starting using usb gadget, and if I understand well, there are 2 ways to configure gadget mode.
First is yours (in first post), the other is by using libcomposite
. I followed this tutorial for gadget configuration, and it seams that you can easily replace each bits...
This issue will be closed within 30 days unless further interactions are posted. If you wish this issue to remain open, please add a comment. A closed issue may be reopened if requested.
I can confirm that this bug still exists on Raspberry Pi Zero. The g_ether module will randomly not respect the host_addr option given to it, regardless if using the kernel command line, an option file in modprobe.d or simply "modprobe g_ether host_addr=00:11:22:33:44:55". All three approaches work only intermittently. More often than not, the host will have a randomly generated MAC regardless of what was specified.
Interestingly, the syslog output of the module seems to reflect that soemthing is wrong with the MAC generation internally:
Jul 23 08:50:59 raspberrypi kernel: [ 82.963954] using random self ethernet address
Jul 23 08:50:59 raspberrypi kernel: [ 82.963978] using random host ethernet address
Jul 23 08:50:59 raspberrypi kernel: [ 82.963994] using host ethernet address: 00:22:82:ff:ff:20 **## This is the one I manually specified, so should be correct**
Jul 23 08:50:59 raspberrypi kernel: [ 82.964000] using self ethernet address: 16:78:91:65:a2:e9
Jul 23 08:50:59 raspberrypi kernel: [ 82.965526] usb0: HOST MAC 00:22:82:ff:ff:20
Jul 23 08:50:59 raspberrypi kernel: [ 82.966796] usb0: MAC 16:78:91:65:a2:e9
Jul 23 08:50:59 raspberrypi kernel: [ 82.966870] using random self ethernet address
Jul 23 08:50:59 raspberrypi kernel: [ 82.966885] using random host ethernet address **## contradictory**
Jul 23 08:50:59 raspberrypi kernel: [ 82.966992] g_ether gadget: Ethernet Gadget, version: Memorial Day 2008
Jul 23 08:50:59 raspberrypi kernel: [ 82.967005] g_ether gadget: g_ether ready
Jul 23 08:50:59 raspberrypi kernel: [ 82.967025] dwc2 20980000.usb: bound driver g_ether
After this output usb0 had a random MAC on the host side. This makes it very hard to have a predictable DHCP setup. I would kindly ask that you reopen this issue.
Also having this issue w/most current pi zero build. host_addr is ignored.
Worked around it by manually greping dmesg after boot, mapping the port to the connected device and then configuring manually. This is not ideal and defeats the purpose of hotplugging.
Please reopen.
this needs to be reopened
I did some more looking into this; I had the specified host_addr appear once after unplugging and plugging in the pi; it isn't consistent, though suggesting some sort of race maybe. It never worked from a cold boot, e.g. booting the host system and the pi at the same time.
It would be really sweet if this worked properly, using pi zeros as camera peripherals.
It appears this issue has existed for some time?
Alright - I'll take a look.
Much appreciated and happy to help debug.
I can confirm that Windows see the specified MAC address while Linux (at least running on a host Pi) doesn't.
No - it does work. On the client side:
pi@raspberrypi:~$ ifconfig usb0
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
...
ether 8e:7a:7e:37:6f:bb txqueuelen 1000 (Ethernet)
and on the host side:
pi@raspberrypi:~$ ifconfig usb0
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
...
ether 8e:7a:7e:37:6f:aa txqueuelen 1000 (Ethernet)
But I'm not losing my grip (or rather, this isn't evidence of it) - scrolling back through the terminal window there is this from the host:
pi@raspberrypi:~$ ifconfig usb0
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
...
ether 92:82:a7:22:9f:8b txqueuelen 1000 (Ethernet)
This suggests there is some unreset state or a race condition - more testing required.
For me the problem cropped up seemingly randomly. Like maybe 60% of client-side boots?
I see the same variability using a Ubuntu guest OS in VirtualBox on Windows 10. After a clean boot the gadget appears as:
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 9e:e2:45:3d:87:ef txqueuelen 1000 (Ethernet)
And after assigning the USB device to Windows then back to VB:
enx8e7a7e376faa: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 8e:7a:7e:37:6f:aa txqueuelen 1000 (Ethernet)
Comparing the lsusb -v dumps in both cases shows no difference apart from the device ID:
2c2
< Bus 001 Device 003: ID 0525:a4a2 Netchip Technology, Inc. Linux-USB Ethernet/RNDIS Gadget
---
> Bus 001 Device 004: ID 0525:a4a2 Netchip Technology, Inc. Linux-USB Ethernet/RNDIS Gadget
In both cases the MAC address is set correctly:
iMacAddress 9 8e7a7e376faa
All of this is without rebooting the device.
This suggests that the problem is with the host. not the gadget.
Seems to be correct, I just cross-checked by connecting my setup to a Win 10 laptop and rebooting the Pi a few times. No random MACs yet.
So I guess this might actually be a bug in the cdc_ether
Linux kernel module?
Something in that area. I think it might be a race between cdc_ether
and cdc_subset
. The first connection after rebooting the host usually fails:
[ 47.208348] usb 1-2: new full-speed USB device number 3 using ohci-pci
[ 47.513114] usb 1-2: config 2 interface 1 altsetting 0 endpoint 0x81 has invalid maxpacket 512, setting to 64
[ 47.513120] usb 1-2: config 2 interface 1 altsetting 0 endpoint 0x1 has invalid maxpacket 512, setting to 64
[ 47.524942] usb 1-2: config 1 interface 1 altsetting 1 endpoint 0x81 has invalid maxpacket 512, setting to 64
[ 47.524948] usb 1-2: config 1 interface 1 altsetting 1 endpoint 0x1 has invalid maxpacket 512, setting to 64
[ 47.544437] usb 1-2: New USB device found, idVendor=0525, idProduct=a4a2, bcdDevice= 5.04
[ 47.544443] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 47.544447] usb 1-2: Product: RNDIS/Ethernet Gadget
[ 47.544450] usb 1-2: Manufacturer: Linux 5.4.69-v7l+ with fe980000.usb
[ 47.587024] cdc_subset: probe of 1-2:1.0 failed with error -22
[ 47.597021] cdc_subset 1-2:1.1 usb0: register 'cdc_subset' at usb-0000:00:06.0-2, Linux Device, 9e:c2:ca:91:86:42
[ 47.597160] cdc_ether: probe of 1-2:1.0 failed with error -16
[ 47.597261] usbcore: registered new interface driver cdc_ether
[ 47.597696] usbcore: registered new interface driver cdc_subset
Subsequent attempts after disconnecting and reconnecting the device succeed:
[ 147.137283] usb 1-2: new full-speed USB device number 4 using ohci-pci
[ 147.434651] usb 1-2: config 2 interface 1 altsetting 0 endpoint 0x81 has invalid maxpacket 512, setting to 64
[ 147.434653] usb 1-2: config 2 interface 1 altsetting 0 endpoint 0x1 has invalid maxpacket 512, setting to 64
[ 147.444380] usb 1-2: config 1 interface 1 altsetting 1 endpoint 0x81 has invalid maxpacket 512, setting to 64
[ 147.444381] usb 1-2: config 1 interface 1 altsetting 1 endpoint 0x1 has invalid maxpacket 512, setting to 64
[ 147.464957] usb 1-2: New USB device found, idVendor=0525, idProduct=a4a2, bcdDevice= 5.04
[ 147.464959] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 147.464961] usb 1-2: Product: RNDIS/Ethernet Gadget
[ 147.464962] usb 1-2: Manufacturer: Linux 5.4.69-v7l+ with fe980000.usb
[ 147.476850] cdc_subset: probe of 1-2:1.0 failed with error -22
[ 147.496033] cdc_ether 1-2:1.0 usb0: register 'cdc_ether' at usb-0000:00:06.0-2, CDC Ethernet Device, 8e:7a:7e:37:6f:aa
[ 147.512149] cdc_ether 1-2:1.0 enx8e7a7e376faa: renamed from usb0
The probe by cdc_subset of 1-2:1.0 always fails with -22 (-EINVAL), but on that first attempt, it succeeds in probing 1-2:1.1. which I think is what causes cdc_ether to get -16 (-EBUSY). After then, 1-2:1.1 isn't heard of again, and cdc_ether probes successfully.
It's hard to see how the device can know that a particular connect is after a reboot, which again points the finger at the host.
i had filed a bug request on freebsd which can be found here https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=220852
i had filed a bug request on freebsd which can be found here https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=220852
The workaround at the end involves manually unloading the cdc ethernet module for a urndis
driver to work. I am doubtful this is applicable to Linux. I guess we need to test against a current upstream host kernel and then file a report to https://bugzilla.kernel.org if the problem is still there.
cdc_ether
seems to have had some recent development (https://github.com/torvalds/linux/blob/master/drivers/net/usb/cdc_ether.c). The last host Kernel version I can definitely confirm this bug on is 5.4.0. When I have time I can install a VM with current upstream Kernel and check.
I can confirm this is happening on Debian 10. (4.19.0-11-amd64)
I noticed there are different cdc drivers appearing, although the device works in all cases; just has a random mac.
I can't come up with a replicable process for the mac address appearing. The assigned mac appeared maybe 3/20 times I've been working on it. It does appear to be a race condition of some type.
This issue is affecting me too, on latest Raspberry Pi OS.
I stand by my comment above (https://github.com/raspberrypi/firmware/issues/843#issuecomment-705493047): I think the problem is a generic Linux problem with the host, and the Pi is doing nothing wrong.
Well in this instance my host is Openwrt 19.07, running kernel 4.14.156, still Linux I know but older than your confirmed cases. Seems odd to me that the host is causing the devices host side MAC to be randomised.
Ok, on my Ubuntu box kernel 5.4.0-56-generic. I'm trying the same SD image with a different Pi Zero (W this time previous one was plain Zero) and it's reliably setting the host MAC every boot (replug).
The logs seem to look identical to previous ones posted.
Dec 3 09:03:23 pihole kernel: [ 7.624136] random: systemd: uninitialized urandom read (16 bytes read)
Dec 3 09:03:23 pihole kernel: [ 9.615557] dwc2 20980000.usb: 20980000.usb supply vusb_d not found, using dummy regulator
Dec 3 09:03:23 pihole kernel: [ 9.624512] dwc2 20980000.usb: 20980000.usb supply vusb_a not found, using dummy regulator
Dec 3 09:03:23 pihole kernel: [ 9.854236] dwc2 20980000.usb: EPs: 8, dedicated fifos, 4080 entries in SPRAM
Dec 3 09:03:23 pihole kernel: [ 9.857502] dwc2 20980000.usb: DWC OTG Controller
Dec 3 09:03:23 pihole kernel: [ 9.859392] dwc2 20980000.usb: new USB bus registered, assigned bus number 1
Dec 3 09:03:23 pihole kernel: [ 9.861271] dwc2 20980000.usb: irq 33, io mem 0x20980000
Dec 3 09:03:23 pihole kernel: [ 9.914783] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.04
Dec 3 09:03:23 pihole kernel: [ 9.918471] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
Dec 3 09:03:23 pihole kernel: [ 9.920390] usb usb1: Product: DWC OTG Controller
Dec 3 09:03:23 pihole kernel: [ 9.922293] usb usb1: Manufacturer: Linux 5.4.72+ dwc2_hsotg
Dec 3 09:03:23 pihole kernel: [ 9.924323] usb usb1: SerialNumber: 20980000.usb
Dec 3 09:03:23 pihole kernel: [ 9.975944] hub 1-0:1.0: USB hub found
Dec 3 09:03:23 pihole kernel: [ 9.984057] hub 1-0:1.0: 1 port detected
Dec 3 09:03:23 pihole kernel: [ 10.702167] using random self ethernet address
Dec 3 09:03:23 pihole kernel: [ 10.704229] using random host ethernet address
Dec 3 09:03:23 pihole kernel: [ 10.705987] using host ethernet address: 46:7a:67:a8:3f:1b
Dec 3 09:03:23 pihole kernel: [ 10.726007] usb0: HOST MAC 46:7a:67:a8:3f:1b
Dec 3 09:03:23 pihole kernel: [ 10.744347] usb0: MAC 0a:c0:8b:c6:b7:c7
Dec 3 09:03:23 pihole kernel: [ 10.746126] using random self ethernet address
Dec 3 09:03:23 pihole kernel: [ 10.747703] using random host ethernet address
Dec 3 09:03:23 pihole kernel: [ 10.749330] g_ether gadget: Ethernet Gadget, version: Memorial Day 2008
Dec 3 09:03:23 pihole kernel: [ 10.750906] g_ether gadget: g_ether ready
Dec 3 09:03:23 pihole kernel: [ 10.752398] dwc2 20980000.usb: bound driver g_ether
Dec 3 09:03:23 pihole kernel: [ 11.878106] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
Dec 3 09:03:23 pihole kernel: [ 17.185194] vc_sm_cma: module is from the staging directory, the quality is unknown, you have been warned.
Dec 3 09:03:23 pihole kernel: [ 17.188144] bcm2835_vc_sm_cma_probe: Videocore shared memory driver
Ok, so this is truly bizarre. I plugged the Zero I was having issues with into my laptop a few times, and the MAC appeared stable. Now plugging it back into my Openwrt box and its stable there too. The logs look identical to how they did above. I'll keep an eye on it and see if it starts happening again.
I'm experiencing the same problem, using a Raspberry Pi 4 Model B as host and four Raspberry Pi Zero devices as USB Ethernet gadgets.
I'm using the Pi4 as a base station to collect sensor data over I2C over distances of several meters. The Pi0s collect the I2C sensor data and the Pi4 in turn polls it from the Pi0s. Providing power and data connection with the same cable reduces complexity of setup and thus seemed like a win.
On the Pi0s, I use the g_ether options to set a persistent MAC address for each device. On the Pi4, I use udev rules to attribute network interface names based on the persistent MAC addresses, and the DHCP client configuration to attribute the correct point-to-point network to each Pi0. In theory, this would allow dynamic adding/removing of sensor endpoints (Pi0s) by simply plugging/unplugging, with some extra tooling.
When I unplug/replug the Pi4, the problem discussed here is reproduced with high probability. Most of the time, the first device (first udev rule, lowest network numbers) will load as usb0
instead of the custom interface name. When that happen, the MAC address on the host is random, rather than the pre-configured one.
Unplugging/replugging the Pi0 solves the problem most of the time. As there are two additional problems (unreliable booting of the Pi0, possibly due to low voltage or SD card unreliability, as well as unreachable Pi0, even if booted with correct MAC/IP) that could be solved in the same manner, I started looking into simulating unplugging/replugging through software.
Unfortunately, the Pi4 USB hubs do not support per-port power supply (PPPS), meaning that toggling power off and on again (uhubctl
tool does an excellent job here) is equivalent to a reboot of all 4 Pi0 devices. I'm currently waiting for 4 external USB hubs that should support PPPS to test whether I can reliably work around the MAC address and other issues by switching the power on the respective USB ports off and on again.
If this turns out successful, I will write a tool to automatically do so until all devices are successfully connected. However, in order to reduce startup time of the system, it would be great if the problem were solved at its source. What are the next steps here? How can this be moved forward?
Another datapoint. I thought I was going nuts. I am nowhere as knowledgeable as the others here. Running Linux Mint 20.1 and hardcoding the MAC addresses in cmdline.txt as done by xbipin When plugging in a Zero, half of the time, it will show as usb0 and half of the time, it will have the MAC address. Unplugging and replugging will solve the problem.
I came across this issue after a lot of searching. Looking at the latest tree ref. It's late where I am so this analysis might suck, but let's see how this fits.
Here's where we get these debug messages in the kernel from u_ether.c
:
if (get_ether_addr(dev_addr, net->dev_addr))
dev_warn(&g->dev,
"using random %s ethernet address\n", "self");
if (get_ether_addr(host_addr, dev->host_mac))
dev_warn(&g->dev,
"using random %s ethernet address\n", "host");
The function is expecting a return true value from the call to get_ether_addr()
. Tracing that down we find:
// u_ether.c
static int get_ether_addr(const char *str, u8 *dev_addr)
{
if (str) {
unsigned i;
for (i = 0; i < 6; i++) {
unsigned char num;
if ((*str == '.') || (*str == ':'))
str++;
num = hex_to_bin(*str++) << 4;
num |= hex_to_bin(*str++);
dev_addr [i] = num;
}
if (is_valid_ether_addr(dev_addr)) // <--- this function returns 'true' if it is valid
return 0; // which means, we return 'false' to avoid the print, so we're falling through?
}
eth_random_addr(dev_addr);
return 1;
}
So ... some how we're falling through. As indicated by others, it feels very random, so if you trace the is_valid_ether_addr()
function, you'll find this comment:
/**
* is_valid_ether_addr - Determine if the given Ethernet address is valid
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
* a multicast address, and is not FF:FF:FF:FF:FF:FF.
*
* Return true if the address is valid.
*
* Please note: addr must be aligned to u16. //<< ----- ummmm ... i don't think that's promised by u_ether.c?
*/
static inline bool is_valid_ether_addr(const u8 *addr)
{
/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
* explicitly check for it here. */
return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
}
So then we look at the is_multicast_ether_addr()
and we see that indeed, we need to make sure that's aligned because ....
/**
* is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Return true if the address is a multicast address.
* By definition the broadcast address is also a multicast address.
*/
static inline bool is_multicast_ether_addr(const u8 *addr)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
u32 a = *(const u32 *)addr;
#else
u16 a = *(const u16 *)addr;
#endif
#ifdef __BIG_ENDIAN
return 0x01 & (a >> ((sizeof(a) * 8) - 8));
#else
return 0x01 & a;
#endif
}
So I think there's two issues at play, one for the people like me not paying attention ... and then one more difficult:
c1:12:f5:d4:a9:b4
which resulted in failure. I then updated to c4:12:f5:d4:a9:b4
and it assigned correctly because of course, it is now not really a multicast address after I remember the LSB is a 0x01 and causing the check to fail. Same with some of the other MACs that I'm seeing above because they're technically multicast.struct eth_dev
: https://elixir.bootlin.com/linux/v5.11.10/source/drivers/usb/gadget/function/u_ether.c#L83 ... but that would be a super unlucky day I think.Additionally, there is a possible oddness here that results in no checks in the gether_setup_name_default()
for the dev_addr
and host_addr
. This functions should probably be updated to matche the gether_setup_name()
that's above it.
Hope that helps.
Now that I've had more time to look at the code, there's a lot of duplicated stuff in the u_ether.c
which is probably what's really driving the heart of the issue. I think there's probably 3 separate updates that need to be made, but i'm not familiar enough with the gadget interface to be confident that I can make these changes without breaking the world.
Suggested updates:
g_ether
usb gadget will accept a multicast mac as a parameter, but silently fail and then generate a random one. It would be easy enough to put a dmesg that stops 90% of people from picking bad addresses at the expense of an extra set of calls during setup because it's really not that expensive. __attribute__ ((aligned (16)))
to the arrays at the end of the struct eth_dev
will probably stop any of these issues from arising.gether_setup_name_default
should probably go away and be replaced with an updated call to gether_setup_name
like the other functions in the u_ether.h
header so that there's only 1 code path for setting up a gadget.I'd be happy to make these patches, but again - I'm not super familiar with the rest of the gadget interface so I don't know if there are going to be unintended consequences of my recommendations. Any feedback would be appreciated.
Be aware that this code is generic, unmodified upstream code. Any changes should be submitted there. Before you dive too deeply into this update you might want to find out who maintains the driver and send them an email with your thoughts.
Be aware that this code is generic, unmodified upstream code. Any changes should be submitted there. Before you dive too deeply into this update you might want to find out who maintains the driver and send them an email with your thoughts.
Yea, I noticed this as I was digging through it. Sadly, this is the only place I've found this issue on the internet other than some extremely old gentoo post. The maintainers is where I'm headed next.
i have the below in my cmdline.txt file modules-load=dwc2,g_ether g_ether.dev_addr=8e:7a:7e:37:6f:bb g_ether.host_addr=8e:7a:7e:37:6f:aa
the problem is it applies the dev_addr mac id to usb0 but the host_addr doesnt apply at all so the PC sees a random mac id always.
im on the latest kernel 4.9.37
You have U/L bit set. See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local_(U/L_bit)
rndis_host
on the host side will ignore such address, by design, due to flaws in ZTE modems. Even if g_ether will apply it.
Fix for that is pending inclusion in v5.19 kernel. See here: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=caf968b483351d8825e68b06d77de5eb618aeb64
You might want to backport it yourself or ask backporting to stable kernels once it lands in Linus' tree.
Or just ensure that U/L bit is cleared. and I/G bit as well.
It seems like this issue might be describing a few different bugs, but I'm using Linux kernel 5.15 (aka Ubuntu 22.04 LTS) on Raspberry Pi 4Bs (both for the host and the peripheral) and my case is exactly the same as https://github.com/raspberrypi/firmware/issues/843#issuecomment-705536933: g_ether
on my Raspberry Pi 4B seems to be working fine; it looks like the issue is with the cdc_subset
driver on the host side.
On boot, dmesg
on the host shows cdc_subset: probe of 1-2:1.0 failed with error -22
, then that seems to cause a race-condition with cdc_ether: probe of 1-2:1.0 failed with error -16
.
I've found that adding blacklist cdc_subset
in my /etc/modprobe.d/blacklist.conf
on my host forces my host to use cdc_ether
, and now my host MAC addresses are consistent!
I also found Pi Zero Gadget not detected by Pi4b only on cold boot | Raspberry Pi Forums and they had the same issue on Raspbian Buster, and blacklist cdc_subset
fixed it for them too.
I will note that at least on my set up (not on a Raspbery Pi) /lib/systemd/network/99-default.link
was the culprit for the MAC address not being what I wanted. Changing MACAddressPolicy=persistent
to MACAddressPolicy=none
(or just removing the whole file). Seems to fix the issues.
i have the below in my cmdline.txt file modules-load=dwc2,g_ether g_ether.dev_addr=8e:7a:7e:37:6f:bb g_ether.host_addr=8e:7a:7e:37:6f:aa
the problem is it applies the dev_addr mac id to usb0 but the host_addr doesnt apply at all so the PC sees a random mac id always.
im on the latest kernel 4.9.37