Skip to content

{bp-19872} net/arp: fix cross-interface resolution and a device-lock leak - #20070

Merged
xiaoxiang781216 merged 2 commits into
apache:releases/13.0from
jerpelea:bp-19872
Sep 7, 2026
Merged

{bp-19872} net/arp: fix cross-interface resolution and a device-lock leak#20070
xiaoxiang781216 merged 2 commits into
apache:releases/13.0from
jerpelea:bp-19872

Conversation

@jerpelea

@jerpelea jerpelea commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Two independent defects in net/arp that together make a peer periodically
unreachable when two network interfaces share an IPv4 subnet. Both are needed:
fixing either one alone produces a worse result than the bug, which is why they
are submitted together as separate commits.

  1. arp_find() can answer with another interface's MAC.
    The ARP table itself is keyed by (device, address), but on a cache miss
    arp_find() falls back to netdev_foreach(arp_match, ...), and arp_match()
    compares only the IP address. Any interface holding that address wins and its
    MAC is returned, regardless of the device the frame is going out on. A frame
    transmitted on interface A can therefore be addressed to the MAC of interface B.
    Note the asymmetry with route selection, which already filters on
    IFF_IS_RUNNING (netdev_prefixlen_findby_lipv4addr()).

  2. arp_send() leaks dev->d_lock.
    The -EINPROGRESS branch does goto wait, jumping over the netdev_unlock(dev)
    further down, and arp_wait() does not release the lock either. The caller
    therefore sleeps holding d_lock, while netdev_upper_rxpoll_work() needs that
    same lock to dispatch incoming frames — so the ARP reply being waited for can
    never reach arp_input(). Because d_lock is recursive, retries re-acquire it
    and the recursion depth is never unwound, so the interface stays blocked.

Defect 2 is normally invisible: the wrong-MAC shortcut of defect 1 keeps the code
from ever reaching real ARP resolution. Remove the shortcut without fixing the
lock and a self-healing outage becomes a permanent loss of connectivity.

Impact

RELEASE

Testing

CI

The -EINPROGRESS path jumps over the netdev_unlock() below it, so the
caller waits holding d_lock.  The receive path needs that same lock to
dispatch the ARP reply, and the interface stalls for good.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
On a cache miss arp_find() returns the MAC of any interface holding the
address, ignoring the egress device.  Two interfaces on one subnet then
leave the peer unreachable until the entry is relearned.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
@github-actions github-actions Bot added Area: Networking Effects networking subsystem Size: S The size of the change in this PR is small labels Sep 7, 2026
@jerpelea

jerpelea commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

CI fix
apache/nuttx-apps#3775

@xiaoxiang781216
xiaoxiang781216 merged commit 9fbac66 into apache:releases/13.0 Sep 7, 2026
22 of 41 checks passed
@jerpelea
jerpelea deleted the bp-19872 branch September 7, 2026 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Networking Effects networking subsystem Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants