USB-NCM DHCP-Server shared with WiFi-AP DHCP-Server -> local link IP on AP · Issue #19685 · micropython/micropython · GitHub
Skip to content

USB-NCM DHCP-Server shared with WiFi-AP DHCP-Server -> local link IP on AP #19685

Description

@SciLor

Port, board and/or hardware

pico2w

MicroPython version

v1.29.0

Reproduction

Build with USB-NCM enabled and run this on a Pico W/Pico 2 W:

import network

# Brings up the SoftAP - own DHCP server on 192.168.4.0/24.
ap = network.WLAN(network.AP_IF)
ap.config(ssid="repro-ap", password="testtest", security=network.WLAN.SEC_WPA_WPA2)
ap.active(True)
print("AP up:", ap.ifconfig())  # ('192.168.4.1', '255.255.255.0', ...)

# Brings up USB-NCM - its own separate DHCP server on a MAC-derived
# 169.254.x.0/16 pool, active unconditionally regardless of WiFi mode.
nic = network.USBD_NCM()
nic.active(True)
print("USB-NCM up:", nic.ifconfig())  # ('169.254.X.1', '255.255.0.0', ...)

Then connect any WiFi client (phone/laptop) to repro-ap. Expected: the client gets a 192.168.4.x lease. Actual: the client gets a 169.254.X.y lease (confirm via the client's own reported gateway/DNS, which will read back as the USB-NCM interface's own 169.254.X.1 address) and cannot reach 192.168.4.1.

Expected behaviour

Get an IP-Address in the 192.168.0.0/16 range

Observed behaviour

Getting a local link 169.254 IP via the WiFi AP DHCP, which is identical to the one on the USB-NCM

Additional Information

Suggested fix

Scope each DHCP server's UDP PCB to its own interface with the existing udp_bind_netif() API, so lwIP's first-line netif check in udp_input_local_match() (if (pcb->netif_idx != NETIF_NO_INDEX && pcb->netif_idx != netif_get_index(current_input_netif)) return 0;) rejects it outright for any broadcast arriving on a different interface:

Add a struct netif *netif parameter to dhcp_server_init() (shared/netutils/dhcpserver.h/.c).
In dhcp_server_init(), after dhcp_socket_bind()'s udp_bind() call, add udp_bind_netif(d->udp, netif);.
Update both call sites to pass their own netif:
extmod/network_cyw43.c's AP-mode cyw43_cb_tcpip_init() path (in lib/cyw43-driver/src/cyw43_lwip.c) — pass n (the netif it just created).
extmod/network_usbd_ncm.c's ncm_init() — pass &ncm_obj.netif.
This keeps both DHCP servers fully functional and correctly isolated to their own interface, rather than requiring either one to be disabled to avoid the collision.

Code of Conduct

Yes, I agree

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions