major.io

Words of wisdom from a Linux engineer focused on information security

major.io

Words of wisdom from a systems engineer

  • Who am I?
  • icanhazip FAQ
  • Résumé
  • Keybase
  • RSS
Creative Commons License

Creating a bridge for virtual machines using systemd-networkd

March 26, 2015 By Major Hayden 9 Comments

There are plenty of guides out there for making ethernet bridges in Linux to support virtual machines using built-in network scripts or NetworkManager. I decided to try my hand with creating a bridge using only systemd-networkd and it was surprisingly easy.

First off, you’ll need a version of systemd with networkd support. Fedora 20 and 21 will work just fine. RHEL/CentOS 7 and Arch Linux should also work. Much of the networkd support has been in systemd for quite a while, but if you’re looking for fancier network settings, like bonding, you’ll want at least systemd 216.

Getting our daemons in order

Before we get started, ensure that systemd-networkd will run on a reboot and NetworkManager is disabled. We also need to make a config file director for systemd-networkd if it doesn’t exist already. In addition, let’s enable the caching resolver and make a symlink to systemd’s resolv.conf:

XHTML
1
2
3
4
5
systemctl enable systemd-networkd
systemctl disable NetworkManager
systemctl enable systemd-resolved
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
mkdir /etc/systemd/network

Configure the physical network adapter

In my case, the network adapter connected to my external network is enp4s0 but yours will vary. Run ip addr to get a list of your network cards. Let’s create /etc/systemd/network/uplink.network and put the following in it:

XHTML
1
2
3
4
5
[Match]
Name=enp4s0
 
[Network]
Bridge=br0

I’m telling systemd to look for a device called enp4s0 and then add it to a bridge called br0 that we haven’t configured yet. Be sure to change enp4s0 to match your ethernet card.

Make the bridge

We need to tell systemd about our new bridge network device and we also need to specify the IP configuration for it. We start by creating /etc/systemd/network/br0.netdev to specify the device:

XHTML
1
2
3
[NetDev]
Name=br0
Kind=bridge

This file is fairly self-explanatory. We’re telling systemd that we want a device called br0 that functions as an ethernet bridge. Now create /etc/systemd/network/br0.network to specify the IP configuration for the br0 interface:

XHTML
1
2
3
4
5
6
7
[Match]
Name=br0
 
[Network]
DNS=192.168.250.1
Address=192.168.250.33/24
Gateway=192.168.250.1

This file tells systemd that we want to apply a simple static network configuration to br0 with a single IPv4 address. If you want to add additional DNS servers or IPv4/IPv6 addresses, just add more DNS= and Address lines right below the ones you see above. Yes, it’s just that easy.

Let’s do this

Some folks are brave enough to stop NetworkManager and start all of the systemd services here but I prefer to reboot so that everything comes up cleanly. That will also allow you to verify that future reboots will cause the server to come back online with the right configuration. After the reboot, run networkctl and you’ll get something like this (with color):

networkctl screenshot

Here’s what’s in the screenshot:

XHTML
1
2
3
4
5
6
7
8
9
10
IDX LINK             TYPE               OPERATIONAL SETUP    
  1 lo               loopback           carrier     unmanaged
  2 enp2s0           ether              off         unmanaged
  3 enp3s0           ether              off         unmanaged
  4 enp4s0           ether              degraded    configured
  5 enp5s0           ether              off         unmanaged
  6 br0              ether              routable    configured
  7 virbr0           ether              no-carrier  unmanaged
 
7 links listed.

My ethernet card has four ports and only enp4s0 is in use. It has a degraded status because there is no IP address assigned to enp4s0. You can ignore that for now but it would be nice to see this made more clear in a future systemd release.

Look at br0 and you’ll notice that it’s configured and routable. That’s the best status you can get for an interface. You’ll also see that my other ethernet devices are in the unmanaged state. I could easily add more .network files to /etc/systemd/network to configure those interfaces later.

Further reading

As usual, the Arch Linux wiki page on systemd-networkd is a phenomenal resource. There’s a detailed overview of all of the available systemd-networkd configuration file options over at systemd’s documentation site.

Share this post:

  • Twitter
  • Google
  • LinkedIn
  • Reddit
  • Email
  • Print

Tagged With: centos, fedora, network, red hat, systemd

Comments

  1. James says

    March 26, 2015 at 9:53 pm

    Small nitpick, but there’s no: unconfigured state as you mentioned in your article It’s “unmanaged” in your case.

    HTH,
    Cheers!

    James

    Reply
  2. Major Hayden says

    March 27, 2015 at 8:34 am

    Good catch, James! I just fixed that and another typo that I found.

    Reply
  3. Cristian Ciupitu says

    March 28, 2015 at 11:04 am

    I think systemd-networkd is not available on Fedora 20.

    Reply
  4. Sampson Fung says

    May 23, 2015 at 4:42 pm

    The host side configuration using systemd-networkd works great. I am using Fedora 22 RC3.

    For the Guest Part, I am using virt-manager.

    When I want to change my Guests to using the “br0” in host in bridge mode, however, it is not available to choose from (it only show two of my physical ethernet interfaces).

    What I need to do so that virt-manager can use the br0 created by systemd-networkd as bridge for guests?

    Reply
    • Major Hayden says

      May 25, 2015 at 9:01 am

      You’ll have to choose “Specify a network device by name” and put br0 in the box. There’s a way to get it to appear in virt-manager as a drop-down option but I can’t remember how to enable that.

      Reply
  5. coder4coffee says

    January 26, 2016 at 3:36 pm

    Great read! On my system(arch) I also had to set MACAddress to NetDev using actual hardware MAC address of eth(enp*). Or else bridge would use virtual device mac. Which in my case was wrong because I have DHCP issuing static IP by MAC address. Might help someone googling around with similar problem:)

    Reply
  6. Dr Romeo Chair says

    November 22, 2016 at 10:57 am

    Thanks Major for such a useful guide. My first try at this failed due to a file permission problem — creating the files as root gave the files a ‘600’ so systemd-networkd.service was failing to start. Running ‘journalctl -xe’ helped me figure out the permission problem and changing permission to ‘644’ made it work. Hope that might help someone else.

    Reply
  7. clsv says

    February 5, 2017 at 2:41 am

    Thanks for this manual

    Reply
  8. Jonas says

    April 7, 2017 at 12:09 am

    Good work, still useful today! Great for ArchLinux.

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.