Raspberry Pi Zero as a router-attached ethernet gadget

Just to follow up, thanks to the Firmware Selector, it's pretty easy to install OpenWRT headless on a Pi Zero 2W. I chose the 64 bit factory image for Pi3 etc, works great.

Customize before downloading: add kmod-usb-gadget, kmod-usb-gadget-eth, and kmod-usb-dwc2.
After downloading, gunzip it and write it to a micro SD card, then on a Linux system, mount the second partition and make these changes (similar to those described in the top post):

Add your g_ether module options (explained in the top post) to /etc/modules.conf
Add a file named g_ether to /etc/modules.d/, containing just "g_ether"
Add a symlink in /etc/modules-boot.d/ to /etc/modules.d/g_ether.
Modify /etc/config/network to use "usb0" in place of "eth0". If you're not going to have a route to a DHCP server when you plug it into whatever you're using as a host, configure for a static IP address now.

Unmount the second partition and mount the first.
Add the following to config.txt

gpu_mem=16
dtoverlay=dwc2,dr_mode=peripheral

The first just reclaims as much video memory as possible since you'll be running headless, the second is needed for gadget mode.

(I also did the following for reasons related to my application, though they're far from necessary:

arm_freq=1100
arm_freq_min=800
gpu_freq=500
core_freq=500
sdram_freq=500
sdram_schmoo=0x02000020
over_voltage=2
over_voltage_sdram=2
dtparam=sd_overclock=85
dtoverlay=disable-bt
dtoverlay=disable-wifi

)

That's it for the Pi. Everything related to the host should be in the top post.

1 Like

I've encountered this problem with the Pi Zero W, even without NAT offloaded (AdGuardHome stops responding for a few minutes, sometimes recovers, sometimes requires a reboot).

But I couldn't identify the associated error in the logs.
Can you tell me more about this?

Also, would increasing the goroutine limit help?

I was thinking of trying a Docker instance of AGH (on my OpenWRT router), but if the Pi zero 2 doesn't have this problem I think it'll be easier and more robust to have ADH on separate hardware.

To see if the problem is the same one I had earlier, check if AdGuardHome has got dozens and dozens of TCP connections to your remote DNS servers. Try netstat -pant. In my case when the number of hanging connections in TIME_WAIT or CLOSE_WAIT approached the goroutines limit (300), AdGuardHome would stop working. I never did find the reason for AdguardHome to so many outstanding queries, and I never solved it. Now I run AdguardHome on the router (manual installation); . I still have a Pi02W attached to the router but I use it for other applications now; I've never seen this kind of problem with any of them, so the problem may be peculiar to AdguardHome or Go used in this arrangement. Sorry not to be more help.

Note: I don't know if this problem occurs on the 2W; I haven't tried AdguardHome on it. Another data point is that I'm running OpenWrt aarch64 on it as an operating system rather than Raspbios.

1 Like

Hi all!

Just did installation on my Zero W using latest Raspberry Pi OS Lite(32bit Debian 12 Bookworm).
There is a minor mistake in a main post where the static IP is configured for usb0 interface(Option 2), since it's only applicable for Bulllseye and Bullworm uses NetworkManager approach.

My whole install flow was something like this:
Used Raspberry Pi Imager and during installation I chose to pre-configure user and ssh settings as well ass Locale settings. That precreated firstrun.sh shell script that is executed during first boot.

To /boot/config.txt at the end of file I appended dtoverlay=dwc2 as per steps in the main post.

Added module additional modules to load to /boot/cmdline.txt file. Between rootwait and quiet I have added modules-load=dwc2,g_ether g_ether.host_addr=00:6d:eb:a8:44:7f g_ether.dev_addr=1a:0d:c4:d1:19:9b that loaded modules required modules and passed additonal options to g_ether. It's important to keep the cmdline.txt a single line file.

As for network config I utilized previously mentioned firstboot.sh file and just before line that is 3rd from the bottom(rm -f /boot/firstrun.sh). I have added creation of NetworkManager config for usb0 interface:

cat <<EOF >/etc/NetworkManager/system-connections/usb0-eth.nmconnection
[connection]
id=usb0-eth
uuid=$(uuid -v4)
type=ethernet
interface-name=usb0

[ethernet]
[ipv4]
method=manual
addresses=192.168.4.144/24;
gateway=192.168.4.1
dns=192.168.4.1;

[ipv6]
method=ignore
EOF

chmod 600 /etc/NetworkManager/system-connections/usb0-eth.nmconnection

Got the same result as per main post instructions, just only using boot partition and running latest Raspberry Pi OS Lite.

Hope this helps for someone.

1 Like

There's no need for a static IP on the device side, as DHCP works just fine, considering you're setting a static MAC through g_ether.dev_addr. Also, I'm not sure if g_ether.host_addr is really necessary.

Agree on the static IP part, had some troubles troubleshooting network setup on the pi side, completely threw away the idea of leaving it auto based. I think it's opposite, you should set the host_addr, but not necessarily dev_addr. Will tinker around more some day