Linux ARP Reply Issue: Wired Interface Responding with Wireless MAC Address


3 views

I recently encountered a puzzling networking issue on a Linux-based robot system. The device has both wired (eth0) and wireless (ra0) interfaces configured on the same subnet (192.168.0.0/24). While the interfaces appear to be properly configured according to ifconfig and route commands, ARP resolution behaves unexpectedly:

# ARP request for wired IP (192.168.0.110)
$ arp -a
? (192.168.0.110) at 24:3c:20:06:3e:6d [ether] on ra0

Notice how the wired IP (eth0) is responding with the wireless interface's MAC address.

Here's the relevant network configuration from the system:

# ifconfig output
eth0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.0.110  netmask 255.255.255.0  broadcast 192.168.0.255
        ether 00:01:c0:04:bd:f7  txqueuelen 1000

ra0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.101  netmask 255.255.255.0  broadcast 192.168.0.255
        ether 24:3c:20:06:3e:6d  txqueuelen 1000

# route -n
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 ra0
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

After researching and testing several possibilities, here are the key findings:

  1. ARP Filter Settings:
    The Linux kernel has several ARP-related parameters that might affect this behavior. Try checking these sysctl settings:

    # Check current ARP settings
    cat /proc/sys/net/ipv4/conf/all/arp_filter
    cat /proc/sys/net/ipv4/conf/all/arp_ignore
    cat /proc/sys/net/ipv4/conf/all/arp_announce
    
    # Temporary solution (if supported on your minimal system)
    echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
    echo 2 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 1 > /proc/sys/net/ipv4/conf/all/arp_announce
    
  2. Route Preference:
    The routing table shows both interfaces have equal priority (metric 0). The wireless interface might be preferred because it's in RUNNING state while eth0 is MULTICAST only.

    # Try bringing down the wireless temporarily for testing
    ifconfig ra0 down
    

For a permanent fix on systems with limited tools, consider these approaches:

1. Interface Priority Adjustment:
Modify the interface metric to prefer one interface over another:

# Add metric to the wired interface
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth0 metric 100

2. ARP Filter Script:
Create a startup script to configure ARP behavior:

#!/bin/sh
# Force ARP replies to come from the correct interface
echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_announce

3. Network Manager Configuration:
If using NetworkManager (unlikely in minimal systems), add these to interface config:

[connection]
arp-verify=true
arp-ignore=2
arp-announce=1

After implementing changes, verify with these commands:

# Check ARP cache
arp -n

# Capture ARP traffic
tcpdump -i any arp -nnvv

# Verify interface states
ip -d link show

The expected result should show ARP replies for 192.168.0.110 coming from 00:01:c0:04:bd:f7 (eth0's MAC) rather than the wireless MAC.


When working with a Linux system containing both wired (eth0) and wireless (ra0) interfaces on the same subnet, we're observing an unusual ARP behavior where:

  • ARP requests for eth0's IP (192.168.0.110) receive replies containing ra0's MAC (24:3C:20:06:3E:6D)
  • Ping responses still work even when eth0 is physically disconnected
  • Both interfaces show proper IP configuration and routing tables

This behavior stems from Linux's weak host model implementation where:

# Kernel's ARP handling logic (simplified)
if (arp_request.target_ip == any_local_interface_ip) {
    reply_with(any_working_interface_mac);
}

The system prioritizes reachability over strict interface binding when multiple NICs share the same subnet, a common pitfall in embedded Linux deployments.

To confirm the issue and gather diagnostics:

# Check current ARP behavior
arping -I eth0 192.168.0.110
tcpdump -i ra0 arp and host 192.168.0.110

# Verify interface states
ip -d link show dev eth0
ip -d link show dev ra0

Since standard tools aren't available in this cut-down Linux, we need kernel-level parameter tweaks:

# Temporary solution (doesn't persist across reboots)
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_filter
echo 1 > /proc/sys/net/ipv4/conf/ra0/arp_filter
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_ignore

For permanent solution in embedded systems, add to startup scripts:

#!/bin/sh
# In /etc/init.d/network-tweaks
[ -e /proc/sys/net/ipv4/conf/eth0/arp_filter ] && echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_filter
[ -e /proc/sys/net/ipv4/conf/ra0/arp_filter ] && echo 1 > /proc/sys/net/ipv4/conf/ra0/arp_filter

If procfs isn't available, consider these workarounds:

  1. Put interfaces on different subnets (192.168.0.x/24 and 192.168.1.x/24)
  2. Implement static ARP entries on all communicating devices
  3. Use network namespaces to logically separate interfaces

When facing network stack issues in constrained environments:

  • Capture raw packets using tcpdump or wireshark
  • Check kernel messages with dmesg
  • Verify interface flags (PROMISC, NOARP)
  • Test with minimal network configuration

The behavior changed between OpenEmbedded versions due to:

Version ARP Handling
Older Strict interface binding
Newer Weak host model default