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:
- 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
- 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:
- Put interfaces on different subnets (192.168.0.x/24 and 192.168.1.x/24)
- Implement static ARP entries on all communicating devices
- 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 |