Translation(s): English


Bridging Network Connections with Proxy ARP

Introduction

This document describes a means to bridge IP traffic between two interfaces using Proxy ARP, /32 host routes and standard Linux routing/forwarding. For a Layer 2 solution - an ethernet bridge - refer to BridgeNetworkConnections.

The benefit of using an IP / Layer 3 solution is that it will work when the outward-facing interface is a wireless ethernet client, without using WDS and without resorting to NAT. Simple Layer 2 bridging does not work in this case due to the vagaries of wireless AP client behaviour; WDS may help but AP support can be patchy.

Using Proxy ARP permits the bridged clients to be part of the existing network and supports bidirectional traffic, e.g. for a server or printer. DHCP and mDNS will also work using the appropriate helpers.

One scenario is connecting a wired network to a wireless LAN using a host that has both wifi (wlan0) and ethernet (eth0) interfaces. A specific example is using a Raspberry Pi with a USB wifi adapter to connect a wired-ethernet printer to the WLAN. No static configuration is required other than the wifi SSID and authentication for the Pi - the Pi and printer acquire DHCP addresses from the existing DHCP server, and the printer continues to be reachable via mDNS and otherwise operates as if it were patched to a wired port on the main network.

The term 'bridge' in this document refers to the host doing the proxy-arp and routing between the two networks, though keep in mind there is no layer 2 bridging involved. The 'outside' network is the existing network that hosts the DHCP server, gateway router, etc. The 'inside' network is the one with the hosts that need to be bridged and made to appear to be on the outside network.

Summary

Proxy ARP is a technique by which a device on a given network answers the ARP queries for a network address that is not on that network, that is to make the hosts on one network appear to be logically part of a different physical network.

The bridge host will proxy ARP requests from the inside network to the outside, and respond to ARPs from the outside network on behalf of inside hosts. Linux will only do this for hosts that are known via the routing table, so a /32 host route must be created pointing to the inside host (one for each inside host). The route is also required for IP forwarding to work, i.e. when IP traffic arrives after the ARP process has completed.

As an example, to manually configure and test this out where the primary LAN has a network address of 10.42.0.0/24:

  1. configure an inside client with a static IP of 10.42.0.11/24
  2. on the bridge:
    bridge# echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp
    bridge# echo 1 > /proc/sys/net/ipv4/ip_forward
    bridge# ip ro add 10.42.0.11/32 dev eth0
  3. ping from the inside host to an outside host, and examine the ARP table:
    insidehost$ ping -c 1 10.42.0.2
    PING 10.42.0.2 (10.42.0.2) 56(84) bytes of data.
    64 bytes from 10.42.0.2: icmp_req=1 ttl=64 time=14.7 ms
    
    insidehost$ arp -n 10.42.0.2
    Address                  HWtype  HWaddress           Flags Mask            Iface
    10.42.0.2              ether   b8:27:eb:6b:52:b9   C                     eth0
    # b8:27:eb:6b:52:b9 is the MAC of eth0 - the inside interface - on the bridge
    bridge$ arp -n 10.42.0.2
    Address                  HWtype  HWaddress           Flags Mask            Iface
    10.42.0.2              ether   00:08:9b:be:f8:a2   C                     wlan0
    # 00:08:9b:be:f8:a2 is the MAC of eth0 on the outside host
    
    bridge$ arp -n 10.42.0.11
    Address                  HWtype  HWaddress           Flags Mask            Iface
    10.42.0.11             ether   00:1b:a9:be:16:73   C                     eth0
    10.42.0.11                     (incomplete)                              wlan0
    # 00:1b:a9:be:16:73 is the MAC of the inside host; the outside wlan0 entry if present should always be incomplete
    outsidehost$ # arp -n 10.84.42.11
    Address                  HWtype  HWaddress           Flags Mask            Iface
    10.84.42.11             ether   00:e0:4c:10:3c:75   C                     eth0
    # 00:e0:4c:10:3c:75 is the MAC of wlan0 on the bridge

Note that no IP address is required on the bridge's inside ethernet interface for proxy ARP to work (though see below re. DHCP relay).

If you run tcpdump on the bridge's ethernet and wlan interfaces, you'll see the ARP request from the inside host being proxied to the outside interface, with the ARP source being the bridge's outside-facing interface's MAC address. The ARP table on the inside hosts will show the bridge's inside interface MAC for all outside hosts, and similarly for outside hosts the MAC for all inside hosts will be the bridge's outside interface MAC.

DHCP Relay

DHCP is a Layer 2 protocol and can't traverse the Layer 3 'bridge' so we use the dhcp-helper utility to listen for DHCP requests from the inside network and relay them to the DHCP server on the outside network. The relayed DHCP request will contain the IP address of the bridge's inside interface in order for the DHCP server to know which network to allocate an IP address for the new client from. We want the DHCP allocation to be from the same network as the outside LAN, the simplest implementation is to reflect the outside interface's IP address on to the inside interface. i.e. the bridge's inside and outside interfaces will have the same IP address; though the inside interface's network will be a host /32 netmask so as not to upset routing.

An alternative utility to dhcp-helper is dhcrelay.

Or instead, the bridge inside interface can be assigned a static IP from the outside network, in which case the post-up step in /etc/network/interfaces configuration below can be omitted.

Automating the Process

parprouted is designed to monitor the ARP table and both proxy ARP requests and install matching /32 host routes. Running parprouted with the inside and outside interfaces handles the ARP and routing completely automatically. Note that the kernel's proxy ARP mechanism (/proc/sys/net/ipv4/conf/all/proxy_arp) is not required.

parprouted does not handle packet forwarding nor DHCP or mDNS, so these features need to be enabled separately.

Installing the software

The following assumes wlan0 is the already-configured outside interface, eth0 the unconfigured inside interface. Tested on Debian Wheezy 7.8 on 2015-08-02, on armv6l (Raspberry Pi v1).

bridge$ sudo apt-get install parprouted dhcp-helper avahi-daemon

Edit /etc/network/interfaces to configure the interfaces:

auto lo
iface lo inet loopback

auto eth0
allow-hotplug eth0
iface eth0 inet manual

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
  post-up /usr/sbin/parprouted eth0 wlan0
  post-down /usr/bin/killall /usr/sbin/parprouted
  # clone the dhcp-allocated IP to eth0 so dhcp-helper will relay for the correct subnet
  post-up /sbin/ip addr add $(/sbin/ip addr show wlan0 | perl -wne 'm|^\s+inet (.*)/| && print $1')/32 dev eth0
  post-down /sbin/ifdown eth0

Edit /etc/sysctl.d/local.conf to enable IP forwarding:

net.ipv4.ip_forward=1

Enable DHCP relay: /etc/default/dhcp-helper

# relay dhcp requests as broadcast to wlan0
DHCPHELPER_OPTS="-b wlan0"

Edit /etc/avahi/avahi-daemon.conf to enable mDNS relaying:

[reflector]
enable-reflector=yes

Reboot, and hosts connected to the bridge's ethernet should acquire a DHCP address and have full IP connectivity!

Known Issue with RTL8188CUS USB Wifi Adapter

Description of issue: When using an RTL8188CUS based wifi device, bridge connectivity is very unreliable and most ARP requests to the bridge's wlan address fail. This issue has minimal impact on a host that is configured as a normal client and primarily sending traffic but has a significant impact when the host is acting as a bridge.

Resolution: Edit /etc/modprobe.d/8192cu.conf

# disable power management and USB suspend
options 8192cu rtw_power_mgnt=0 rtw_enusbss=0


CategoryNetwork