Setting Up systemd-networkd with Bonding

This article will guide your through the process of getting systemd-networkd up and running, and then setting up bonding in active-backup mode.

If you already have systemd-networkd setup, feel free to skip to Setting Up the Bond.

# Migrating to systemd-networkd

# Enable systemd-networkd

Let's get systemd-networkd enabled first.

systemctl enable systemd-networkd

If you want to obtain DNS configuration from the DHCP server, you will need to enable systemd-resolved and symlink /run/systemd/resolve/resolv.conf to /etc/resolv.conf.

I recommend doing these steps as we will still be able to configure our DNS servers statically in a later step.

systemctl enable systemd-resolved
mv /etc/resolv.conf /etc/resolv.conf.bak # Create a backup
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

# Disable NetworkManager

Assuming that you are using NetworkManager to manage your network, this is a good time to disable it.

systemctl disable NetworkManager

# systemd-networkd-wait-online.service

If you have NetworkManager-wait-online.service enabled, you will have to disable that and enable systemd-networkd-wait-online.service.

systemctl disable NetworkManager-wait-online
systemctl enable systemd-networkd-wait-online

# Setting up a fallback connection

I like to setup my networks manually, but just to be on the safe side, let's setup a network configuration using DHCP first. This will serve as a fallback when everything else fails.

/etc/systemd/network/99-dhcp.network
[Match]
Name=enp3*

[Network]
DHCP=yes

Here I used a wildcard in my [Match] section to match any network interfaces with name beginning with enp3. Change it according to your network interfaces if needed.

To list all your network interfaces, execute the following command.

ip link

# Wired connection

Next, let's configure our ethernet connection manually with static IP and DNS.

/etc/systemd/network/20-enp3s0.network
[Match]
Name=enp3s0

[Network]
Address=192.168.1.123/24
Gateway=192.168.1.1
DNS=8.8.8.8
DNS=8.8.4.4

I used enp3s0 as my match here, but you might have need to change it according to what you have.

# Wireless connection

systemd-networkd does not provide us with any facilities to configure a wireless adapter, so we will have to use another service such as wpa_supplicant for that.

Create a file at /etc/wpa_supplicant/wpa_supplicant-wlp4s0.conf containing the following configurations.

(Of course, replace wlp4s0 with the name of your wireless adapter's interface.)

/etc/wpa_supplicant/wpa_supplicant-wlp4s0.conf
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=wheel
update_config=1
fast_reauth=1
ap_scan=1

Then, issue the following command to append your network's SSID and passphrase to the file you just created above.

(Replace ssid and passphrase accordingly.)

 wpa_passphrase ssid passphrase >> /etc/wpa_supplicant/wpa_supplicant-wlp4s0.conf

For security purposes, I recommend prepending a space ' ' to the command above. In most shells, this will prevent it from being stored in the history.

The command above will append the network's SSID, passphrase in plain text (commented out), and a calculated WPA PSK to the designated file.

Again for security purposes, I recommend deleting the line containing the passphrase in plain text.

Next, we need to enable the corresponding service.

systemctl enable wpa_supplicant@wlp4s0

Finally, we need to create a configuration file for systemd-networkd.

/etc/systemd/network/30-wlp4s0.network
[Match]
Name=wlp4s0

[Network]
Address=192.168.1.123/24
Gateway=192.168.1.1
DNS=8.8.8.8
DNS=8.8.4.4

Don't forget to replace wlp4s0 accordingly.

# Reboot

Finally, we can reboot and test our connection now.

reboot

After the reboot, run the following command to see if everything is working.

networkctl

In my case, it looks like this.

IDX LINK             TYPE               OPERATIONAL SETUP
  1 lo               loopback           carrier     unmanaged
  2 enp3s0           ether              carrier     configured
  3 eno1             ether              off         unmanaged
  4 wlp4s0           wlan               carrier     configuring
  5 bond1            ether              routable    configured

5 links listed.

Yours will look a bit different because I already have bonding setup here.

# Setting Up the Bond

With systemd-networkd setup and running, let's setup bonding now.

# Create virtual network device

First, we have to create a new virtual network device for our bond connection.

To do so, create a file at /etc/systemd/network/10-bond1.netdev with the following contents.

/etc/systemd/network/10-bond1.netdev
[NetDev]
Name=bond1
Kind=bond

[Bond]
Mode=active-backup
PrimaryReselectPolicy=always
MIIMonitorSec=1s

# Configure the bond

Next, create a file at /etc/systemd/network/10-bond1.network with the following configurations.

I'm setting it up with static IP and DNS here again, but you can use DHCP as well.

/etc/systemd/network/10-bond1.network
[Match]
Name=bond1

[Network]
Address=192.168.1.123/24
Gateway=192.168.1.1
DNS=8.8.8.8
DNS=8.8.4.4

# Change adapter configurations

Now, we have to change our physical network interfaces to point to our newly-created bond interface.

Here I specified enp3s0 to be the primary slave.

Thanks to @forumache for notifying me that PrimarySlave should be defined in the slave network configuration instead of the bond device configuration. After trying to track down when the change had occurred, I found that it was actually just a mistake in the systemd man page that was corrected a couple of months after I posted this article.

/etc/systemd/network/20-enp3s0.network
[Match]
Name=enp3s0

[Network]
Bond=bond1
PrimarySlave=true
/etc/systemd/network/30-wlp4s0.network
[Match]
Name=wlp4s0

[Network]
Bond=bond1

# Done

Let's reboot and test our new bond interface!

reboot
networkctl

This gives me the following.

IDX LINK             TYPE               OPERATIONAL SETUP
  1 lo               loopback           carrier     unmanaged
  2 enp3s0           ether              carrier     configured
  3 eno1             ether              off         unmanaged
  4 wlp4s0           wlan               carrier     configuring
  5 bond1            ether              routable    configured

5 links listed.

Let's check the status of our bond interface.

cat /proc/net/bonding/bond1

Here's what I got:

(I censored my Permanent HW addr here, but you should get something more sensible instead of ff:ff:ff:ff:ff:ff)

Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

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

Slave Interface: wlp4s0
MII Status: up
Speed: Unknown
Duplex: Unknown
Link Failure Count: 0
Permanent HW addr: ff:ff:ff:ff:ff:ff
Slave queue ID: 0

Slave Interface: enp3s0
MII Status: up
Speed: 100 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: ff:ff:ff:ff:ff:ff
Slave queue ID: 0

Here, we can see that our Bonding Mode is correctly set to active-backup.

We can also see that our Primary Slave is set to enp3s0 with primary_reselect set to always as expected.

# Conclusion

That concludes this article.

I hope you find the information here useful.