Systemd's systemd-networking can be used to replace the existing networking system on Raspbian.

How does it work with Raspbian on a Raspberry Pi 3 and its two interfaces for ethernet and wlan? Can I also realize dynamic failover for them?


Using systemd-networkd instead of default dhcpcd is of course possible. But it is not meaningful in all cases.

networkd is a small and lean service to configure network interfaces, designed mostly for server use cases in a world with hotplugged and virtualized networking. Its configuration is similar in spirit and abstraction level to ifupdown, but you don't need any extra packages to configure bridges, bonds, vlan etc. It is not very suitable for managing WLANs yet; NetworkManager is still much more appropriate for such Desktop use cases. [1]

But for a raspi laying near by a TV or amplifier and doing its work 24/7 for streaming audio or video or for a camera etc., systemd-networkd is a good choice. But you have to do a complete switch. There is no way to mix up with networking and/or dhcpcd.

♦ Step 1: Preparation

For reference I use a fresh flashed SD Card from Raspbian Stretch Lite 2019-04-08, updated with sudo apt update && sudo apt full-upgrade && sudo reboot on 2019-04-22. This comes with systemd 232.

I will have attention to a headless installation only with ssh. If you are using this, double check typos or so otherwise you are lost with a broken connection. If you want a headless installation then look at SSH (Secure Shell) and follow section 3. Enable SSH on a headless Raspberry Pi (add file to SD card on another machine).

For troubleshooting on shutdown or to check messages from previous boots you can enable persistent logging in journald for messages from systemd [1]. Because it produces big log files and storage place may be an issue I suggest to enable it only if needed. systemd-networkd does not need it and logging of the current session is always available.

pi@raspberrypi: ~$ sudo mkdir -p /var/log/journal
pi@raspberrypi: ~$ sudo systemd-tmpfiles --create --prefix /var/log/journal

Disable the old stuff. Don't stop any service, only disable them! So it will take effect only on next boot.

pi@raspberrypi: ~$ sudo -Es

In /etc/resolvconf.conf insert these lines.

# Set to NO to disable resolvconf from running any subscribers. Defaults to YES.

Then disable this. We mask it so its completely disabled and cannot be started by other services.

root@raspberrypi: ~# systemctl mask networking.service
root@raspberrypi: ~# systemctl mask dhcpcd.service
root@raspberrypi: ~# mv /etc/network/interfaces /etc/network/interfaces~

And enable systemd-networkd:

root@raspberrypi: ~# systemctl enable systemd-networkd.service
root@raspberrypi: ~# systemctl enable systemd-resolved.service
root@raspberrypi: ~# ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

♦ Step 2: Setup the wired ethernet interface (eth0)

Create this file with your settings. You can just copy and paste this in one block to your command line beginning with cat and including both EOF (delimiter EOF will not get part of the file):

root@raspberrypi: ~# cat >/etc/systemd/network/04-eth.network <<EOF
# to use static IP (with your settings) toggle commenting the next 6 lines.

root@raspberrypi: ~# exit
pi@raspberrypi: ~$

Reboot, but only if you have an ethernet cord attached ;-)

It is possible that the RasPi gets a new ip address so you may have to look at it for the next connection with ssh.

♦ Step 3: Setup wlan interface (wlan0)

Create this file with your settings:

pi@raspberrypi:~ $ sudo -Es
root@raspberrypi:~ # cat >/etc/systemd/network/08-wifi.network <<EOF
# to use static IP (with your settings) toggle commenting the next 5 lines.

root@raspberrypi:~ #

Setup wpa_supplicant with this file and your settings for ssid= and psk= and enable it:

root@raspberrypi:~ # cat >/etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev


root@raspberrypi:~ # chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
root@raspberrypi:~ # systemctl disable wpa_supplicant.service
root@raspberrypi:~ # systemctl enable wpa_supplicant@wlan0.service
root@raspberrypi:~ # exit
root@raspberrypi:~ $

Reboot if you have a wifi connection. Most of you will have. Good luck ...

It is possible that the RasPi gets a new ip address so you may have to look at it for the next connection with ssh.

♦ Step 4: Bonding wired and wifi interface for failover

You should have both interfaces setup and running as described above. It is no problem when both interfaces are up. The kernel will use the interface with the lowest RouteMetric first. Here the ethernet interface will be used first. But this has a great disadvantage. As you can see with ~$ ip addr each interface has it's own ip-address. If the kernel switches the interface because one is gone down it also uses its new source ip-address. This will break any established communication, e.g. ssh, streaming and so on. You have to reboot to take effect. But that isn't really what we want.

The solution of this problem is bonding. We create an interim interface bond0 that does not change its settings. Ethernet and wifi will switch to bond0.

First disable the single ethernet and wifi network files:

pi@raspberrypi:~ $ sudo -Es
root@raspberrypi:~ # cd /etc/systemd/network/
root@raspberrypi:~ # mv 04-eth.network 04-eth.network~
root@raspberrypi:~ # mv 08-wifi.network 08-wifi.network~

Then setup bonding with this five files:

root@raspberrypi:~ # cat >/etc/systemd/network/12-bond0.netdev <<EOF
# status: cat /proc/net/bonding/bond0

root@raspberrypi:~ # cat >/etc/systemd/network/16-bond0-add-eth.network <<EOF

root@raspberrypi:~ # cat >/etc/systemd/network/20-bond0-add-wifi.network <<EOF

root@raspberrypi:~ # cat >/etc/systemd/network/24-bond0-up.network <<EOF
# to use static IP uncomment these (use your settings) instead of DHCP

root@raspberrypi:~ # cat >/etc/modprobe.d/bonding.conf <<EOF
options bonding mode=active-backup
options bonding primary=eth0
options bonding miimon=500
options bonding updelay=1000
options bonding downdelay=1000
options bonding min_links=1

root@raspberrypi:~ # exit
pi@raspberrypi:~ $

It should be said that there are also options for bonding in systemd-networkd [2] but they are buggy in systemd 232. They are working since systemd 234. So we setup the bonding driver direct with modprobe. It's parameter can you get with ~$ modinfo bonding.

Now it's time to reboot.

It is possible that the RasPi gets a new ip address so you may have to look at it for the next connection with ssh.

Then you can check the bonding status:

pi@raspberrypi:~ $ cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: eth0 (primary_reselect always)
Currently Active Slave: eth0
MII Status: up
MII Polling Interval (ms): 500
Up Delay (ms): 1000
Down Delay (ms): 1000

Slave Interface: eth0
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: b8:27:eb:53:bd:de
Slave queue ID: 0

Slave Interface: wlan0
MII Status: up
Speed: Unknown
Duplex: Unknown
Link Failure Count: 0
Permanent HW addr: b8:27:eb:06:e8:8b
Slave queue ID: 0

Test bonding: with the bonding status above you will see that the Currently Active Slave: will change and the MII Status: is down.

If your are headless, don't down both interfaces together ;-)

pi@raspberrypi:~ $ ip addr
pi@raspberrypi:~ $ sudo ip link set eth0 down
pi@raspberrypi:~ $ sudo ip link set eth0 up
pi@raspberrypi:~ $ sudo ip link set wlan0 down
pi@raspberrypi:~ $ sudo ip link set wlan0 up

♦ Step 5: Clean up

Purge the old stuff:

pi@raspberrypi:~ $ sudo apt install deborphan
pi@raspberrypi:~ $ sudo apt --autoremove purge openresolv
pi@raspberrypi:~ $ sudo apt --autoremove purge ifupdown
pi@raspberrypi:~ $ sudo apt --autoremove purge dhcpcd5
pi@raspberrypi:~ $ sudo apt --autoremove purge isc-dhcp-client isc-dhcp-common
pi@raspberrypi:~ $ sudo apt --autoremove purge $(deborphan)
pi@raspberrypi:~ $ sudo apt --autoremove purge $(deborphan) #two times

[1] /usr/share/doc/systemd/README.Debian.gz
[2] man systemd.netdev
[3] man systemd.network
[4] https://wiki.debian.org/Bonding
[5] https://www.kernel.org/doc/Documentation/networking/bonding.txt

  • Note with regard to the first quote up top: Raspbian never used NetworkManager. It is more an artifact of Fedora and derived systems (which was the first place that systemd, a Redhat supported project, was deployed). – goldilocks Feb 10 '18 at 12:49
  • Also applicable to other Debian based systems not necessarily running on ARM :) Thank you for the concise explanation. – TCB13 Jun 29 at 16:29
  • This worked for my on stretch but on buster I encountered the problem, that my device cant resolve any domain. Any ideas what could be the cause? – user5950 2 days ago
  • @user5950 Maybe there has something changed with buster? I will look at it. Just a moment please. – Ingo 2 days ago
  • @Ingo Thank you for the fast replay. I could resolve the problem by adding the line DNS= to /etc/systemd/network/04-eth.network. (I am using an setup with static IP)… – user5950 yesterday

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.