5 of 6
Improved error handling
Ingo
  • 36081
  • 13
  • 56
  • 154

I will show a solution in two steps using systemd-networkd. First I create an access point (wlan0) and bridge it with the wired connection (eth0). Then I configure routing between the bridge (br0) and the up-link (eth1).

For reference I use Raspbian Stretch Lite 2019-04-08 updated with sudo apt update && sudo apt full-upgrade && sudo reboot on 2019-05-13.

Example for this setup:
to be compatible with other examples from me I'm using different ip addresses. But it should not be a problem to replace them with yours.

          (dhcp)         bridge
           ╱    wifi    ┌───────┐
mobile-phone <~.~.~.~.> │(wlan0)│            wired           wan
                        │    br0│RPi(eth1) <───────> router <───> INTERNET
      laptop <────────> |(eth0) │╲      ╲            ╱
           ╲    wired   └───────┘╱     (dhcp)   192.168.50.1
         (dhcp)            192.168.4.1

♦ Setting up an access point (wlan0) and bridge it with wired ethernet (eth0)

Follow the instructions given in section **"General setup"** of [Setting up a Raspberry Pi as an access point - the easy way](https://raspberrypi.stackexchange.com/a/88234/79866).

Then create the following four files to configure interfaces.

rpi ~# cat > /etc/systemd/network/02-br0.netdev <<EOF
[NetDev]
Name=br0
Kind=bridge
EOF

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

rpi ~# cat > /etc/systemd/network/12-br0_add-eth0.network <<EOF
[Match]
Name=eth0
[Network]
Bridge=br0
EOF

rpi ~# cat > /etc/systemd/network/16-br0_up.network <<EOF
[Match]
Name=br0
[Network]
Address=192.168.4.1/24
DHCPServer=yes
[DHCPServer]
DNS=84.200.69.80 84.200.70.40
EOF

Now we have to tell wpa_supplicant to use a bridge. We do it by modifying its service with:

rpi ~# systemctl edit wpa_supplicant@wlan0.service

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

[Service]
ExecStartPre=/sbin/iw dev %i set type __ap
ExecStartPre=/bin/ip link set %i master br0

ExecStart=
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dnl80211,wext -i%I -bbr0

ExecStopPost=-/bin/ip link set %i nomaster
ExecStopPost=-/sbin/iw dev %i set type managed

Reboot and check if the bridge works. The mobile phone and the laptop should have an ip address from subnet 192.168.4.0/24 and you should be able to ping the mobile phone from the laptop and vice versa.


♦ Configure routing between up-link eth1 and the bridge br0

Plug in the USB/ethernet dongle if not already done. You should have then an interface **eth1**. Now create this file to configure **eth1**:
rpi ~$ sudo -Es
rpi ~# cat > /etc/systemd/network/04-eth1.network <<EOF
[Match]
Name=eth1
[Network]
DHCP=yes
IPForward=yes
EOF

Because the internet router only serves one device we have to use NAT (network address translation). To configure NAT you have to extend the wpa_supplicant service with:

rpi ~# systemctl edit wpa_supplicant@wlan0.service

In the editor with the entries we have done before add these statements to the [Service] section, save them and quit the editor. You can sort them to the other entries for good looking but the order doesn't matter.

ExecStartPre=/sbin/iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
ExecStopPost=-/sbin/iptables -t nat -D POSTROUTING -o eth1 -j MASQUERADE

Reboot.
That's it.

Ingo
  • 36081
  • 13
  • 56
  • 154