[components][net][lwip-nat] Fix translated port allocation and adapt … - #11831
2027636040 wants to merge 1 commit into
Conversation
…to lwIP 2.1 Allocate the translated port from the free slot index instead of the scan counter: the loop counter equals the table size once the allocation path is taken, so every new mapping got the same port (base + table size) and concurrent UDP/TCP sessions collided, return traffic could be matched to the wrong entry. Adapt the file to lwIP 2.1 as well: lwip/tcp_impl.h is lwip/prot/tcp.h and lwip/timers.h is lwip/timeouts.h now. Two behaviour changes come with it: NAT is applied only when both the source and the destination network match the rule, and the oldest ICMP entry (LRU) is evicted instead of dropping new echo requests when the ICMP table is full. Signed-off-by: zelong_666 <2027636040@qq.com>
|
|
|
👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread! 为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。 🛠 操作步骤 | Steps
完成后,提交将自动更新至 如有问题欢迎联系我们,再次感谢您的贡献!💐 |
📌 Code Review Assignment🏷️ Tag: componentsReviewers: @Maihuanyi Changed Files (Click to expand)
📊 Current Review Status (Last Updated: 2026-09-24 14:15 CST)
📝 Review Instructions
|
Fix the translated source port allocation in the lwIP NAT component and make
the file build against lwIP 2.1.
Why to submit this PR (why to submit this PR)
Every newly created NAT mapping was assigned the same translated port:
ip_nat_udp_lookup_outgoing() / ip_nat_tcp_lookup_outgoing() store the free
slot index in "last_free" but compute the port from the loop counter "i".
When the allocation path is taken the loop has run to completion, so
i == LWIP_NAT_DEFAULT_STATE_TABLES_UDP/TCP and every new entry got
LWIP_NAT_DEFAULT_*_SOURCE_PORT + 32. Concurrent flows therefore shared one
translated port, and the incoming lookup could match the return traffic to
the wrong (first matching) entry, which breaks NAT as soon as more than one
session is active.
What is your solution
nport = htons(LWIP_NAT_DEFAULT_UDP_SOURCE_PORT + last_free) (same for TCP).
The port is then unique per table slot, consistent with the incoming
lookup which matches on nport.
lwip/timers.h is lwip/timeouts.h there. Without this the component does
not compile at all when it is built with lwIP 2.1.
source and the destination network match the configured rule
(ip_nat_shallnat), and when the ICMP table is full the oldest entry (LRU)
is evicted and reused instead of dropping the new echo request.
Verified bsp and config
(USB RNDIS host from a phone with USB tethering on one side, BT PAN on the
other, lwIP 2.1.2, NAT in ip4_forward path). Concurrency was the failing
case before the fix (several sessions from the PAN side at the same time).
(+ RT_LWIP_IP_FORWARD=y for the forwarding path).
already in use in our product tree.
Note on the extra behaviour changes: they are part of what we carry downstream
today, but they are not required for the port fix above. If you prefer to take
only the port allocation fix (and/or the lwIP 2.1 headers) I'm happy to split
this PR - just say which part you want.