*Proxy arp* is a way to build a pseudo bridge that is working on OSI layer 3 but it behaves like a real layer 2 bridge. So it is a good way to workaround the lack of **WDS** support on Raspberry Pi. Here is a way to set it up. In general I followed the tutorial <sup>[**(2)**](https://wiki.debian.orgj/BridgeNetworkConnectionsProxyArp)</sup>. Have a look at it for the background.

Example Setup

 ┌─proxy arp─┐ UPLINK
 wired V V wifi wan
 laptop <─────────> (eth0)RPi(wlan0) <~.~.~.~.> hotspot <---> INTERNET
 \ \
 (dhcp from hotspot) (dhcp from hotspot)

I will present two setups. One that is only static but simpler. It is configured one time on startup and does not respect changes on its interfaces. You have to reboot then. It is good for static use cases, for example to connect a printer. The other setup is a bit more complex but it will monitor connection changes on its interfaces. It is usable on mobile RasPis that will connect to different WiFi networks and wired connections on the fly.

For reference I use [Raspbian Stretch Lite 2019-04-08](https://www.raspberrypi.org/downloads/raspbian/) updated with `sudo apt update && sudo apt full-upgrade && sudo reboot` on 2019-04-16.

--------------------------------------------------
<h2>&diams; Static configuration of proxy arp</h2>
First do **&diams; General Setup**.

Then follow this setup. *parprouted* runs as a daemon but has no *systemd* unit installed. So we will make it and enable also promiscous mode:

 rpi ~# systemctl edit --full --force parprouted.service

In the empty editor insert these statements, save them and quit the editor:

 [Unit]
 Description=proxy arp routing service
 Documentation=https://raspberrypi.stackexchange.com/q/88954/79866

 [Service]
 Type=forking
 # Restart until wlan0 gained carrier
 Restart=on-failure
 RestartSec=5
 TimeoutStartSec=30
 ExecStartPre=/lib/systemd/systemd-networkd-wait-online --interface=wlan0 --timeout=6 --quiet
 ExecStartPre=/bin/echo 'systemd-networkd-wait-online: wlan0 is online'
 # clone the dhcp-allocated IP to eth0 so dhcp-helper will relay for the correct subnet
 ExecStartPre=/bin/bash -c '/sbin/ip addr add $(/sbin/ip -4 -br addr show wlan0 | /bin/grep -Po "\\d+\\.\\d+\\.\\d+\\.\\d+")/32 dev eth0'
 ExecStartPre=/sbin/ip link set dev eth0 up
 ExecStartPre=/sbin/ip link set wlan0 promisc on

 # v minus sign
 ExecStart=-/usr/sbin/parprouted eth0 wlan0

 ExecStopPost=/sbin/ip link set wlan0 promisc off
 ExecStopPost=/sbin/ip link set dev eth0 down
 ExecStopPost=/bin/bash -c '/sbin/ip addr del $(/sbin/ip -4 -br addr show eth0 | /bin/grep -Po "\\d+\\.\\d+\\.\\d+\\.\\d+")/32 dev eth0'

 [Install]
 [email protected]

Enable the service:

 rpi ~# systemctl enable parprouted.service

Reboot. 
That's it.

--------------------------------------------------
<h2>&diams; Dynamic configuration of proxy arp with monitoring interfaces</h2>
Because we will monitor the state of the inerfaces wlan0 and eth0 we have to use a program that will report changes. For this I have made the **ifplug.service**.

So first [Make ifplugd available again since Raspbian Stretch](https://raspberrypi.stackexchange.com/a/96605/79866).

If you have tested the **ifplug.service** and it works,

then do **&diams; General Setup**.

After that configure the **eth0** interface with this file:

 rpi ~# cat > /etc/systemd/network/04-eth.network <<EOF
 [Match]
 Name=eth0
 EOF

As action file for the **ifplug.service** use this `/etc/ifplugs/ifplugs.action` script:

 #!/bin/bash
 # redirect all output into a logfile for debug
 #exec 1>> /tmp/ifplug-debug.log 2>&1

 INTERFACE="$1"
 EVENT="$2"
 IPADDR=''

 get_ipaddr () {
 if [ "$EVENT" = "down" ]; then
 IPADDR=$(/sbin/ip -4 -br addr show $INTERFACE | /bin/grep -Po "\d+\.\d+\.\d+\.\d+")
 return 0
 fi
 # check 10 times with 1 sec delay if ip address is available
 for ((i=10; i>0; i--)); do
 IPADDR=$(/sbin/ip -4 -br addr show $INTERFACE | /bin/grep -Po "\d+\.\d+\.\d+\.\d+")
 [ $? -eq 0 ] && break
 /bin/sleep 1
 done
 }

 case "$INTERFACE" in
 eth0)
 case "$EVENT" in
 up)
 # clone ip address from wlan0 and start parprouted
 IPADDR=$(/sbin/ip -4 -br addr show wlan0 | /bin/grep -Po "\d+\.\d+\.\d+\.\d+")
 if [ -n "$IPADDR" ]; then
 /sbin/ip addr add $IPADDR/32 dev eth0
 /usr/sbin/parprouted eth0 wlan0
 fi
 ;;
 down)
 # stop parprouted
 /usr/bin/killall -q parprouted
 /sbin/ip -4 addr flush dev eth0
 ;;
 *)
 >&2 echo empty or undefined event for "$INTERFACE": \""$EVENT"\"
 exit 1
 ;;
 esac
 ;;

 wlan0)
 case "$EVENT" in
 up)
 # clone ip address from wlan0 and start parprouted
 get_ipaddr
 if [ -n "$IPADDR" ]; then
 /sbin/ip addr add $IPADDR/32 dev eth0
 /sbin/ip link set wlan0 promisc on
 /usr/sbin/parprouted eth0 wlan0
 fi
 ;;
 down)
 # stop parprouted
 /usr/bin/killall -q parprouted
 /sbin/ip link set wlan0 promisc off
 /sbin/ip -4 addr flush dev eth0
 ;;
 *)
 >&2 echo empty or undefined event for "$INTERFACE": \""$EVENT"\"
 exit 1
 ;;
 esac
 ;;

 *)
 >&2 echo empty or unknown interface: \""$INTERFACE"\"
 exit 1
 ;;
 esac

Reboot. 
That's it.

You can follow actions with:

 rpi ~$ journalctl --follow | grep "ifplugd\|parprouted"

------------------------------------------
<h2>&diams; General Setup</h2>
<h3>Install helpers and setup systemd-networkd</h3>
I will use *systemd-networkd* for reasons so first we have to switch over to it.
For detailed information look at [<sup>**(1)**</sup>](https://raspberrypi.stackexchange.com/a/78788/79866). Here only in short. Execute these commands:

 # install helpers
 rpi ~$ sudo -Es
 rpi ~# apt install parprouted dhcp-helper
 rpi ~# systemctl stop dhcp-helper
 rpi ~# systemctl enable dhcp-helper

 # disable classic networking
 rpi ~# systemctl mask networking.service
 rpi ~# systemctl mask dhcpcd.service
 rpi ~# sudo mv /etc/network/interfaces /etc/network/interfaces~
 rpi ~# sed -i '1i resolvconf=NO' /etc/resolvconf.conf

 # enable systemd-networkd
 rpi ~# systemctl enable systemd-networkd.service
 rpi ~# systemctl enable systemd-resolved.service
 rpi ~# ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

<h3>Configure wpa_supplicant</h3>
To configure *wpa_supplicant* create this file with your settings for `country=`, `ssid=` and `psk=`. You can just copy and paste this in one block to your command line beginning with `cat` and including EOF (delimiter EOF will not get part of the file):

 rpi ~# cat > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF
 ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
 update_config=1
 country=DE

 network={
 ssid="TestNet"
 psk="verySecretPassword"
 }
 EOF

 rpi ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
 rpi ~# systemctl disable wpa_supplicant.service
 rpi ~# systemctl enable [email protected]

To configure the **wlan0** interface create this file:

 rpi ~# cat > /etc/systemd/network/08-wlan0.network <<EOF
 [Match]
 Name=wlan0
 [Network]
 DHCP=yes
 IPForward=yes
 EOF

<h3>Setup helpers</h3>
We have installed *dhcp-helper*, a proxy to get ip addresses from the wifi network, and *parprouted* that manages **proxy arp**.

Enable DHCP relay in `/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

Raspberry Pi seems to be a bit buggy because proxy arp with it only works if promiscous mode is enabled on its wifi interface. Normaly it is not needed and has no theoretical background and is nowhere else documented. I have verified proxy arp on my laptop without promiscous mode. Maybe they will fix it in the future.

End of General Setup. Go back.

<br/>**references:** 
[1] [Howto migrate from networking to systemd-networkd with dynamic failover](https://raspberrypi.stackexchange.com/a/78788/79866) 
[2] [Bridging Network Connections with Proxy ARP](https://wiki.debian.org/BridgeNetworkConnectionsProxyArp)