Skip to content

Network: Fix issues with large UDP packets#5185

Open
bkerler wants to merge 1 commit intoprusa3d:masterfrom
bkerler:mtu_fix
Open

Network: Fix issues with large UDP packets#5185
bkerler wants to merge 1 commit intoprusa3d:masterfrom
bkerler:mtu_fix

Conversation

@bkerler
Copy link
Copy Markdown

@bkerler bkerler commented Mar 22, 2026

This resolves issue #5115.

Each full-size Ethernet fragment (1500 bytes) uses ~1524 bytes in the pool. The pool can hold ~33 full-size frames simultaneously, thus the current MTU size is chosen being too small.

The 4 fragments of one 5128-byte UDP datagram need ~6100 bytes combined. With broadcasts arriving continuously from multiple devices and lwIP's reassembly timeout being several seconds, the pool routinely holds fragments from multiple concurrent datagrams — easily exhausting the 11 KB pool.

When the pool is exhausted, pbuf_alloc_rx returns nullptr (pbuf_rx.cpp:38), and the driver drops the incoming frame entirely before lwIP ever sees it. lwIP has some fragments of a datagram but never receives the others. lwIP sends ICMP "Reassembly Time Exceeded". When the reassembly timer fires on an incomplete datagram, lwIP frees the partial fragments it does hold and sends an ICMP Type 11 Code 1 ("Fragment Reassembly Time Exceeded") back to the sender. This is exactly what the reporter observed: ICMP ip reassembly time exceeded messages being sent by the printer to every OpenWrt device, even ones the printer never contacted.

For the mk4_release_boot build:

RAM: 149,704 / 196,608 bytes used, 46,904 bytes free, about 45.8 KiB
CCMRAM: 61,180 / 65,536 bytes used, 4,356 bytes free, about 4.3 KiB
FLASH: 1,804,204 / 1,965,056 bytes used, 160,852 bytes free, about 157.1 KiB
The actual RX pool symbol in the built firmware: rx_allocator_buffer is 51,920 bytes. From the old constants it was 10,980 bytes, so this PR adds 40,940 bytes of static main RAM on XBUDDY/XLBUDDY. Even with that increase, the final linked MK4 image still has 46,904 bytes of normal RAM headroom, and the buffer lives in regular RAM, not CCMRAM.

The only caution is that CCMRAM is generally fairly full at 93.35%

If ram usage increase is generally inacceptable (which might be the case), I wrote a PR #5208 for filtering UDP packets instead.

Network: Guard large RX pool behind Ethernet-capable boards

Keep mtu_cnt=32 / buffer_tail=2000 on XBUDDY / XLBUDDY (192 KB, have
Ethernet). On BOARD_IS_BUDDY() restore mtu_cnt=10 / buffer_tail=500
the original counts, which are sufficient for WiFi-only operation.

mtu_size=1536 is applied to all boards: the old value of 1024 was
smaller than a real Ethernet or WiFi frame (up to 1518 / 1500 bytes),
leaving every ring-allocator slot undersized regardless of platform.
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.

1 participant