I want to bridge the wifi interface with the ethernet interface on a Raspberry Pi so any device on the ethernet port becomes a member of the wifi network. Usually this is done by a bridge (OSI layer 2) but on wifi you need WDS (wireless distribution system) with 4addr to do it. Unfortunately WDS isn't supported by the wifi on board chip of a Raspberry Pi so we have to workaround it with proxy arp. Bridging Network Connections with Proxy ARP shows how to do it on a Debian system. But it uses old style networking that isn't supported out of the box by Raspbian.

How can I make proxy arp available on a Raspberry Pi with Raspbian?


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 (2). 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 updated with sudo apt update && sudo apt full-upgrade && sudo reboot on 2019-04-16.

♦ Static configuration of proxy arp

First do ♦ 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:

Description=proxy arp routing service

# Restart until wlan0 gained carrier
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'


Enable the service:

rpi ~# systemctl enable parprouted.service

That's it.

♦ Dynamic configuration of proxy arp with monitoring interfaces

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.

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

then do ♦ General Setup.

After that configure the eth0 interface with this file:

rpi ~# cat > /etc/systemd/network/04-eth.network <<EOF

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

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


get_ipaddr () {
    if [ "$EVENT" = "down" ]; then
        IPADDR=$(/sbin/ip -4 -br addr show $INTERFACE | /bin/grep -Po "\d+\.\d+\.\d+\.\d+")
        return 0
    # 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

case "$INTERFACE" in
    case "$EVENT" in
        # 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
        # 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

    case "$EVENT" in
        # clone ip address from wlan0 and start parprouted
        if [ -n "$IPADDR" ]; then
            /sbin/ip addr add $IPADDR/32 dev eth0
            /sbin/ip link set wlan0 promisc on
            /usr/sbin/parprouted eth0 wlan0
        # 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

    >&2 echo empty or unknown interface: \""$INTERFACE"\"
    exit 1

That's it.

You can follow actions with:

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

♦ General Setup

Install helpers and setup systemd-networkd

I will use systemd-networkd for reasons so first we have to switch over to it. For detailed information look at (1). 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

Configure wpa_supplicant

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


rpi ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
rpi ~# systemctl disable wpa_supplicant.service
rpi ~# systemctl enable wpa_supplicant@wlan0.service

To configure the wlan0 interface create this file:

rpi ~# cat > /etc/systemd/network/08-wlan0.network <<EOF

Setup helpers

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

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


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.

[1] Howto migrate from networking to systemd-networkd with dynamic failover
[2] Bridging Network Connections with Proxy ARP

  • I have followed your tutorial, but I get this error in syslog when inserting a network cable "parprouted[426]: error: ioctl SIOCGIFADDR for eth0: Cannot assign requested address". What can be wrong? – The87Boy Sep 11 '18 at 8:40
  • @The87Boy I guess it is the first error message on startup I have pointed to in the last sentence of my answer. If you look with journalctl -b -e you should also find the message "systemd[1]: Started proxy arp routing service" after your error message. Distinguish it from Starting .... Your error message should not occur more than one or two times. – Ingo Sep 11 '18 at 9:08
  • It starts occuring, when I insert the network cable and continues, until I remove it again – The87Boy Sep 11 '18 at 9:32
  • Ah, ok. Haven't tested autoplug. I will look at it. Just a moment please. Try to use it first with cable plugged in. – Ingo Sep 11 '18 at 10:03
  • If I start the Raspberry Pi with network cable attached, it gets the IP address, and on the network the IP address is 192.168.0.*, and I copied everything from this guide. What can be wrong? – The87Boy Sep 11 '18 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.