This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit cd4712a2f01f00a219a29fbe03c401f583381118
Author: Felipe Moura <[email protected]>
AuthorDate: Sun Aug 16 17:28:55 2026 -0300

    net/arp: do not resolve an address to another interface's MAC
    
    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 <[email protected]>
---
 net/arp/arp_table.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/net/arp/arp_table.c b/net/arp/arp_table.c
index a1728989e77..3e2938b7993 100644
--- a/net/arp/arp_table.c
+++ b/net/arp/arp_table.c
@@ -81,8 +81,9 @@
 
 struct arp_table_info_s
 {
-  in_addr_t    ai_ipaddr;   /* IP address for lookup */
-  FAR uint8_t *ai_ethaddr;  /* Location to return the MAC address */
+  in_addr_t    ai_ipaddr;           /* IP address for lookup */
+  FAR uint8_t *ai_ethaddr;          /* Location to return the MAC address */
+  FAR struct net_driver_s *ai_dev;  /* The device the frame will be sent on */
 };
 
 /****************************************************************************
@@ -117,6 +118,16 @@ static int arp_match(FAR struct net_driver_s *dev, FAR 
void *arg)
 {
   FAR struct arp_table_info_s *info = arg;
 
+  /* Only the egress device may answer for its own address.  Otherwise a
+   * frame sent on one interface takes the MAC of another that happens to
+   * hold the address, which breaks setups sharing a subnet.
+   */
+
+  if (info->ai_dev != NULL && dev != info->ai_dev)
+    {
+      return 0;
+    }
+
   /* Make sure that this is an Ethernet device (or an IEEE 802.11 device
    * which is also Ethernet)
    */
@@ -529,6 +540,7 @@ int arp_find(in_addr_t ipaddr, FAR uint8_t *ethaddr,
 
   info.ai_ipaddr  = ipaddr;
   info.ai_ethaddr = ethaddr;
+  info.ai_dev     = dev;
 
   if (netdev_foreach(arp_match, &info) != 0)
     {

Reply via email to