Skip to content

rp2: Fix PPP/lwIP build and runtime failures when MICROPY_PY_NETWORK_PPP_LWIP is enabled#19369

Closed
jouellnyc wants to merge 1 commit into
micropython:masterfrom
jouellnyc:fix-rp2-ppp-build
Closed

rp2: Fix PPP/lwIP build and runtime failures when MICROPY_PY_NETWORK_PPP_LWIP is enabled#19369
jouellnyc wants to merge 1 commit into
micropython:masterfrom
jouellnyc:fix-rp2-ppp-build

Conversation

@jouellnyc

Copy link
Copy Markdown

Summary

Fixes three bugs that prevent PPP from building or running on rp2 when MICROPY_PY_NETWORK_PPP_LWIP is enabled. These bugs affect any custom build, including the Pico W scenario described in #16445.

Bug 1 — lwip_inc/lwipopts.h: PPP stack compiled out of lwIP

PPP_SUPPORT and PPPOS_SUPPORT both default to 0 in lwIP's ppp_opts.h and were not set in the rp2 lwipopts.h. Result at runtime:

OSError: pppos_create failed

Bug 2 — CMakeLists.txt: network_lwip.c not compiled

network_lwip.c was not added to MICROPY_SOURCE_EXTMOD when MICROPY_PY_LWIP is enabled. This file defines mp_mod_network_prefer_dns_use_ip_version which modlwip.c references at link time. Result at build time:

undefined reference to `mp_mod_network_prefer_dns_use_ip_version'

Bug 3 — mpnetworkport.c: sys_untimeout_all_with_arg undefined

Called in the lwIP netif status callback but does not exist in lwIP 2.2.1. Added a #ifndef guarded no-op stub — will be superseded automatically when lwIP is updated. Result at build time:

undefined reference to `sys_untimeout_all_with_arg'

Without these three fixes, #16445 would merge but still fail to build and run for all users.


Testing

Custom firmware built with MICROPY_PY_NETWORK=1, MICROPY_PY_LWIP=1, MICROPY_PY_NETWORK_PPP_LWIP=1 on Raspberry Pi Pico (RP2040) and Raspberry Pi Pico W (RP2040).

PPP peer: Raspberry Pi Zero 2W running pppd over UART (providing NAT/DNS etc).

Full PPP negotiation, IP assignment, DNS resolution, and end-to-end HTTP confirmed:

>>> ppp.isconnected()
True
>>> ppp.ifconfig()
('10.0.5.2', '255.255.255.255', '10.0.5.1', '192.168.0.193')
>>> socket.getaddrinfo("google.com", 80)
[(2, 1, 0, '', ('142.251.211.78', 80))]

tcpdump on the Pi Zero confirming full TCP handshake and HTTP response over ppp0:

IP 10.0.5.2 > google.com.http: Flags [S]
IP google.com.http > 10.0.5.2: Flags [S.]
IP google.com.http > 10.0.5.2: Flags [P.] length 773: HTTP/1.0 301

Also ran 10 consecutive HTTP requests on Pico W with 5 second intervals, all successful (this was not true prior).

Note on ppp.poll()
During testing, socket.recv() hangs without manually calling ppp.poll() after sending.
A poll loop is required in userspace:

idle = 0
while idle < 20:
    n = ppp.poll()
    idle = 0 if n > 0 else idle + 1
    time.sleep_ms(100)
data = s.recv(1024)

Root cause: network_ppp_stream_uart_irq_enable() is not called in the PPPERR_NONE case of the status callback, so the UART IRQ is not re-armed after handshake completes. Noted here for visibility.


Trade-offs and Alternatives

PPP_SUPPORT and PPPOS_SUPPORT add lwIP's PPP stack to the build. This only affects boards that explicitly enable MICROPY_PY_NETWORK_PPP_LWIP — no impact on default builds.


Generative AI

I used generative AI tools when creating this PR, but a human has checked the code and is responsible for the code and the description above.

Note

My original intention was to get my own Pi Pico H to use ppp behind a real Linux OS to piggy back on it's ability to use WPA2 Enterprise in that setting. In trying to get ppp on the the rp2, I tried to build but got errors. Then I pursued those errors with AI and landed here. I genuinely hope these changes are helpful as user of micropython and hobbyist.


…PPP_LWIP is enabled

Three bugs prevent PPP from building or running on rp2 even in custom
builds with MICROPY_PY_NETWORK_PPP_LWIP=1:

1. lwip_inc/lwipopts.h: PPP_SUPPORT and PPPOS_SUPPORT both default to 0
   in lwIP's ppp_opts.h and were not set for rp2, causing pppos_create()
   to fail at runtime with OSError: pppos_create failed.

2. CMakeLists.txt: network_lwip.c was not added to MICROPY_SOURCE_EXTMOD
   when MICROPY_PY_LWIP is enabled, causing a link failure on
   mp_mod_network_prefer_dns_use_ip_version.

3. mpnetworkport.c: sys_untimeout_all_with_arg() is called in the lwIP
   netif status callback but does not exist in lwIP 2.2.1. Added a
   #ifndef guarded no-op stub.

Tested on Raspberry Pi Pico and Pico W with full PPP negotiation and
HTTP connectivity confirmed over UART against a Linux pppd peer.

Fixes prerequisite build issues for micropython#16445.
@github-actions

Copy link
Copy Markdown

Code size report:

Reference:  tools/mpy_ld.py: Allow overriding the internal MPY file name. [b49f098]
Comparison: rp2: Fix PPP/lwIP build and runtime failures when MICROPY_PY_NETWORK_PPP_LWIP is enabled [merge of 0e56439]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
      esp32:    +0 +0.000% ESP32_GENERIC
     mimxrt:    +0 +0.000% TEENSY40
        rp2:  +632 +0.068% RPI_PICO_W[incl +608(bss)]
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@dpgeorge

Copy link
Copy Markdown
Member

LLM hallucinations. Please don't waste our time.

@dpgeorge dpgeorge closed this Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants