How Linux Proxy ARP Works in the Routing Stack

Proxy ARP in Linux allows a system to respond to Address Resolution Protocol (ARP) requests on behalf of other devices on distinct network segments. This article explains the internal mechanics of Proxy ARP within the Linux network stack, detailing the sysctl configuration flags, how the kernel's ARP processing routine interacts with the Forwarding Information Base (FIB), the ingress-to-egress validation rules that prevent network loops, and the complete packet lifecycle from initial ARP request to forwarded IP traffic.

Enabling Proxy ARP in the Kernel

Proxy ARP operates at Layer 2/Layer 3 boundaries and is governed by kernel runtime parameters exposed via sysctl. It is disabled by default for security and performance reasons. To activate it, administrators toggle interface-specific flags under the /proc/sys/net/ipv4/conf/ directory:

Kernel ARP Processing Pipeline

When an Ethernet frame carrying an ARP request arrives at a network interface, the network device driver passes the sk_buff (socket buffer) to the core networking layer via netif_receive_skb(). The packet dispatcher identifies protocol ETH_P_ARP and routes the buffer to arp_process() in the net/ipv4/arp.c kernel source file.

The arp_process() routine evaluates whether to generate an ARP reply. If the requested target IP does not match any local address assigned to the receiving interface, the kernel checks whether Proxy ARP should intervene.

Route Lookup and Validation Logic

Before synthesizing an ARP reply for a foreign IP address, the Linux kernel subjects the request to a strict set of routing and forwarding conditions:

  1. IP Forwarding Verification: The kernel confirms that routing is enabled on the host (net.ipv4.ip_forward = 1). A system that cannot forward IPv4 datagrams will not proxy ARP requests.
  2. Forwarding Information Base (FIB) Query: The kernel performs an internal route lookup for the requested IP address. It queries the routing tables to see if a valid route exists to the destination. If the target address is unreachable or drops into a blackhole route, the kernel discards the ARP request.
  3. Interface Separation Check (Split Horizon): Under standard proxy_arp, the kernel checks the egress interface determined by the FIB lookup. The egress interface must be different from the ingress interface where the ARP request was received. This rule prevents network broadcast storms and routing loops. If proxy_arp_pvlan is enabled, this check is relaxed to accommodate isolated hosts on the same subnet.

ARP Reply Generation

If the packet satisfies all lookup and filtering criteria, the kernel builds an ARPOP_REPLY packet:

The generated reply is transmitted directly out of the receiving interface back to the requester via dev_queue_xmit().

Subsequent Data Path Forwarding

Once the querying client receives the proxy ARP reply, it updates its local ARP cache, binding the target IP address to the Linux router's interface MAC address.

When subsequent IP datagrams leave the client, they arrive at the Linux host with the router's Layer 2 destination MAC and the final host's Layer 3 destination IP. The Linux kernel strips the Layer 2 header, inspects the Layer 3 header, recognizes the destination as non-local, decrements the TTL, and forwards the packet toward the true destination via ip_forward() and standard IP routing pathways.