WendyOS Docs

Networking Troubleshooting

This guide covers common WendyOS USB networking problems, their symptoms, and how to diagnose and fix them.

Networking Troubleshooting

This guide covers common WendyOS USB networking problems, their symptoms, and how to diagnose and fix them.

Connectivity Checklist

Run through this before diving into specific scenarios:

[ ] USB-C data cable connected (not a charge-only cable)
[ ] Board booted — serial console available: screen /dev/ttyACM0
[ ] Host sees gadget interface:       ip link show | grep enx
[ ] Host sharing / link-local active: ip addr show enxXXXXXXXXXXXX
[ ] Device has address on usb0:       ip addr show usb0   (run on device)
[ ] Gadget service healthy:           systemctl status gadget-setup
[ ] ARP resolved:                     ip neigh show dev usb0  (on device)
[ ] Ping host from device:            ping -c 3 10.42.0.1
[ ] Ping device from host:            ping -c 3 <device-ip>
[ ] mDNS visible from host:           avahi-browse -t -p _wendyos._udp

Scenario 1 — Host does not see the gadget interface (enx interface missing)

Symptom: ip link show | grep enx produces no output after plugging in.

Step 1 — check if the USB device is enumerated at all:

# On host
lsusb | grep "1d6b:0104"
# Expected: Bus 00X Device 00Y: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget

If the device is not listed:

  • Try a different cable (data cable, not charge-only)
  • Try a different USB port
  • Check if the device has booted — connect via a USB-C power supply and watch the serial console

Step 2 — if lsusb shows the device but no network interface:

# On host
dmesg | grep -i "cdc_ncm\|cdc_ether\|usb"

Look for driver binding messages. If you see cdc_ncm being loaded, the interface should appear. If not, the module may not be available or another driver grabbed the device.

Step 3 — check gadget-setup status on the device (via serial console):

# On device (/dev/ttyACM0)
systemctl status gadget-setup
journalctl -u gadget-setup --no-pager

Common gadget-setup failures:

  • "UDC timeout after 60 s" — the UDC module has not loaded; check lsmod | grep -E "tegra_xudc|dwc2|dwc3"
  • "Neither NCM nor ECM is available" — gadget function modules failed to load; check dmesg | grep usb_f_ncm

Scenario 2 — Device gets no IPv4 address

Symptom: ip addr show usb0 shows only an IPv6 link-local address, no IPv4.

Step 1 — verify the host is providing DHCP:

# On host
ip addr show enxXXXXXXXXXXXX    # should show 10.42.0.1/24 if NM sharing is active
nmcli connection show | grep -i usb

If the host is not set up for sharing, run:

sudo ./scripts/setup-host-usb-link-local.sh install
# Or for full internet sharing (NM):
nmcli connection add type ethernet ifname enxXXXXXXXXXXXX con-name usb-gadget-sharing ipv4.method shared
nmcli connection up usb-gadget-sharing

Step 2 — check NetworkManager on the device:

# On device
journalctl -u NetworkManager | grep -i "usb0\|dhcp"
nmcli connection show usb-gadget | grep -E "ipv4|IP4|STATE"

Step 3 — force a new DHCP attempt:

# On device
nmcli connection down usb-gadget && nmcli connection up usb-gadget

Step 4 — capture DHCP traffic:

# On host
sudo tcpdump -i enxXXXXXXXXXXXX port 67 or port 68 -vn

Expected: DISCOVER → OFFER ← REQUEST → ACK ←

If you see repeated DISCOVERs with no OFFER: the host DHCP server is not active or bound to a different interface. If you see OFFER but no REQUEST: the device is not receiving the OFFER — this is often a receive-path problem (see Scenario 3).


Scenario 3 — IP assigned but packets lost (usb0 has address, ping fails)

Symptom: usb0 has an IP address but ping 10.42.0.1 gets 100% packet loss.

Step 1 — check RX/TX counters:

# On device
ip -s link show usb0

If TX is in the hundreds but RX is near zero, the USB receive path is broken. This is characteristic of the DWC2 DMA stall bug on RPi5 (see below).

Step 2 — check ARP resolution:

# On device
ip neigh show dev usb0
# REACHABLE = ARP is working
# INCOMPLETE = ARP is stuck; the device sent a request but got no reply back

# On host — watch ARP
sudo tcpdump -i enxXXXXXXXXXXXX arp -n

If the host sends ARP Replies but the device still shows INCOMPLETE, packets are being dropped between the USB layer and the network stack.

Step 3 — check packet filters:

# On device
nft list ruleset
iptables -L -n -v
sysctl net.ipv4.conf.usb0.rp_filter

A non-zero rp_filter can drop packets if the route is asymmetric.

Step 4 — inspect the USB endpoint (RPi5/DWC2 specific):

# On device
cat /sys/kernel/debug/usb/udc/1000480000.usb/ep1out

Healthy output has NAKSts=0 and requests completing with non-zero total_data.

Broken output (DMA stall):

NAKSts=1                          # hardware is NAKing all OUT tokens from host
DOEPDMA=0xXXXXXXXX               # DMA address programmed but never completing
req: ... EINPROGRESS total_data=0 # all requests stuck

Root cause (RPi5, kernel 6.6, BCM2712): BCM2712 reports arch=2 (DMA capable) but DMA completion interrupts never fire for OUT transfers in peripheral mode. Fix: g_dma=false in dwc2_set_bcm_params() — this patch is applied in meta-rpi-extensions/. Do not write "" to the UDC sysfs file on an unpatched board — this triggers ep_stop_xfr timeouts and leaves Global OUT NAK permanently asserted. Reboot instead.


Scenario 4 — mDNS device not visible on host

Symptom: avahi-browse -t -p _wendyos._udp returns no results.

Step 1 — check Avahi is running on the device:

# On device
systemctl status avahi-daemon
journalctl -u avahi-daemon --no-pager | tail -30

Step 2 — check that the service file was populated:

# On device
cat /etc/avahi/services/wendyos-mdns.service

The file should contain the actual UUID, not the placeholder string WENDY_DEVICE_ID. If placeholders are present, update-mdns-uuid.sh did not run or failed:

journalctl -t wendyos-identity --no-pager
ls /etc/wendyos/device-uuid /etc/wendyos/device-name

Step 3 — check UUID and hostname services:

# On device
systemctl status wendyos-hostname.service
systemctl status wendyos-uuid-generate.service    # if it exists on this build

Step 4 — check mDNS multicast is reaching the host:

# On host
sudo tcpdump -i enxXXXXXXXXXXXX udp port 5353 -vn

You should see mDNS queries and responses. If you see nothing, multicast may be blocked on the link.

Step 5 — test with avahi-browse on the device itself:

# On device
avahi-browse -t _wendyos._udp

If the device sees its own service, the problem is on the host side. Check that avahi-daemon or dns-sd is running on the host and that the NCM interface is not isolated from multicast.


Scenario 5 — NM stale connection profile on host

Symptom:

Warning: There is another connection with the name 'usb-gadget-sharing'.
Error: Connection activation failed: No suitable device found for this
connection (device docker0 not available ...)

A previous NetworkManager profile is left over and matches the wrong interface.

Fix:

# Delete all stale profiles with that name
nmcli -g UUID,NAME connection show | grep ':usb-gadget-sharing$' | \
    cut -d: -f1 | xargs -I{} sudo nmcli connection delete {}

# Then re-enable
sudo nmcli connection add type ethernet ifname enxXXXXXXXXXXXX \
    con-name usb-gadget-sharing ipv4.method shared
sudo nmcli connection up usb-gadget-sharing

Scenario 6 — gadget-setup fails on Jetson (UDC not found / stays in default state)

Symptom: journalctl -u gadget-setup shows the UDC was found but the gadget does not appear on the host, or the role-switch warning is logged.

Jetson relies on the FUSB301 CC chip and the tegra_xudc driver. If the padctl role-switch notifier chain has not fired before gadget-setup.sh runs, the UDC stays in "default" state and never enters device mode.

The script attempts to force device mode:

echo "device" > /sys/class/usb_role/usb2-0-role-switch/role

Check whether this succeeded:

# On device
journalctl -u gadget-setup | grep -i "role"
cat /sys/class/usb_role/usb2-0-role-switch/role    # should show "device"

# Check UDC state
cat /sys/kernel/config/usb_gadget/wendyos_device/UDC

If the UDC path differs (AGX-style topology):

ls /sys/class/usb_role/
# Look for usb2-*-role-switch

Reference — All Diagnostic Commands

On the device

# Gadget setup
systemctl status gadget-setup
journalctl -u gadget-setup --no-pager

# Network interface
ip addr show usb0
ip -s link show usb0
ip neigh show dev usb0
ip neigh flush dev usb0

# NetworkManager
systemctl status NetworkManager
journalctl -u NetworkManager | grep -i usb0
nmcli connection show usb-gadget
nmcli connection down usb-gadget && nmcli connection up usb-gadget

# Avahi / mDNS
systemctl status avahi-daemon
cat /etc/avahi/services/wendyos-mdns.service
avahi-browse -t _wendyos._udp
avahi-daemon --check

# radvd
systemctl status radvd
ip -6 addr show usb0

# USB hardware (RPi5/DWC2)
cat /sys/kernel/debug/usb/udc/1000480000.usb/ep1out
ls /sys/class/udc/
cat /sys/kernel/config/usb_gadget/wendyos_device/UDC
ls /sys/kernel/config/usb_gadget/wendyos_device/functions/
dmesg | grep dwc2
dmesg | grep -iE "usb|dwc|ncm|udc" | tail -40

# USB hardware (Jetson)
cat /sys/class/usb_role/usb2-0-role-switch/role
ls /sys/class/usb_role/

# Packet filters
nft list ruleset
iptables -L -n -v
sysctl net.ipv4.conf.usb0.rp_filter

On the host

# Gadget detection
lsusb | grep "1d6b:0104"
ip link show | grep enx
dmesg | grep -i "cdc_ncm\|ncm\|ether"

# Interface state
ip addr show enxXXXXXXXXXXXX
ip -s link show enxXXXXXXXXXXXX
ip -6 addr show enxXXXXXXXXXXXX

# ARP
ip neigh show dev enxXXXXXXXXXXXX
sudo tcpdump -i enxXXXXXXXXXXXX arp -n

# DHCP
sudo tcpdump -i enxXXXXXXXXXXXX port 67 or port 68 -vn

# mDNS
avahi-browse -t -p _wendyos._udp      # Linux
dns-sd -B _wendyos._udp local.        # macOS
sudo tcpdump -i enxXXXXXXXXXXXX udp port 5353 -vn

# NetworkManager
nmcli connection show | grep -i usb
nmcli -g UUID,NAME connection show | grep usb-gadget-sharing

# Serial console (fallback)
screen /dev/ttyACM0
picocom /dev/ttyACM0

# SSH
ssh root@<device-ip>
ssh root@wendyos-<name>.local

On this page