1

Does systemd-networkd implement a DHCP server or does it work with isc-dhcp-server? I am attempt to implement a gateway/router using 18.04 LTS server. I am reading the man page regarding the systemd-networkd service.

0

2 Answers 2

2

I have a fresh experience that's related I guess - and it seems to me that the pitfalls that I have discovered are not documented well enough. Not in the form of a complete "user story", from A to Z. Hence this response of mine.

For a particular use case, my objective was, to build a small PC machine as a "data collector/logger" of sorts, with two physical Ethernet interfaces, allowing you to attach a "sensor with an Ethernet port" permanently, and optionally a notebook PC as needed. The three machines would comprise an isolated / self-sufficient network, with no uplink connectivity to the wild wild internet. Both the "sensor" and the notebook wanted to be DHCP clients, and the notebook needed to end up in the same L2 network as the "sensor", for ad-hoc maintenance (the human operator / traveling techie may want to take a look).

So I installed Debian Buster base system (I know, this is an Ubuntu forum, but I believe the principles of my gotcha apply equally) on a small PC with two physical LAN ports, and went on to configure a soft-bridge on the box, assign a static IP address to the bridge's internal interface, and run ISC dhcpd bound to that same bridge interface.

I've done similar things before, typically just stuffing all the necessary brctl and ifconfigs into /etc/rc.local. This time around, as I wanted to adhere to the current / modern / canonical way of configuring networking in the Linux OS, which uses systemd by default, I decided to go with systemd-networkd. (I don't like NetworkManager very much, and it seems to bring about X as a practical dependency...) So for systemd-networkd, I have come up with the following set of files under /etc/systemd/network/ :

br0.netdev :

[NetDev]
Name=br0
Kind=bridge
#MACAddress=00:d0:c9:cb:af:df

eth0.network :

[Match]
Name=eth0

[Network]
Bridge=br0

eth1.network :

[Match]
Name=eth1

[Network]
Bridge=br0

lan0.network :

[Match]
Name=br0

# All you need really is either DHCP=ipv4 or the Address= line. 
# The rest is optional.
[network]
#DHCP=ipv4
Address=192.168.100.1/24
#Gateway=192.168.100.100
#DNS=192.168.100.1

And yes, forgive me everybody for I have sinned: I have added net.ifnames=0 at the kernel command line.

So I did all that, and I started wondering, why my interfaces would not come up at boot. It took me some time to realize that I did not in fact have any syntax errors in my config files. Rather, while I was trying to make my config work, I had my Linux machine detached from any network = both Ethernet ports had their link down. Note that instances of the Linux soft-bridge also summarize the link status of their constituent physical ports, so in my case, the br0 netdevice was not in the "running" state either.

As it turns out, systemd-networkd only assigns an IP address to an interface that currently has link up = as it reaches the "running" state. And, as mentioned, hiding the Physical interface behind a bridge does not help as a workaround!

Which has proven to be my major pitfall - as I did want the machine to start reliably with both Ethernet ports unlinked, and come up with the br0 interface up, with an IP address assigned. The key reason being that isc-dhcp-server requires an IP address on the interface it is supposed to bind on startup, otherwise it terminates immediately with an error, complaining about this with "No subnet declaration for eth0 (no IPv4 addresses)" and then "Not configured to listen on any interfaces!". And, yes I did have INTERFACESv4="br0" in /etc/default/isc-dhcp-server . As far as ISC dhcpd is concerned, the interface is not required to be in the "running" state (link up) but it should be "administratively up" and have an IP address assigned.

No matter which way I turned the problem and my configs around, I found no way (except maybe hacking its source code) of forcing systemd-networkd to just assign the IP address at boot, regardless of link state.

Thus, after a while, I have disabled the systemd-networkd service and returned to the deprecated legacy config file, the venerable /etc/network/interfaces :

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface, and the physical netdevices.
# Cannot mention br0 right here.
auto lo eth0 eth1
iface lo inet loopback

Allow-hotplug eth0
Allow-hotplug eth1

iface eth0 inet manual

iface eth1 inet manual

#iface br0 inet dhcp
iface br0 inet static
        bridge_ports eth0 eth1
        bridge_waitport 0
        address 192.168.100.1
        netmask 255.255.255.0
        broadcast 192.168.100.255
        #gateway 192.168.100.100

# The netdevice name mentioned in the "auto" command
# may only refer to a netdevice that already exists.
# Thus, auto br0 must follow the declaration of this netdevice.
# Note that for comparison, physical devices exist since kernel boot.
auto br0

The lines saying auto <interface> make the interfaces go up at boot. Without the auto clause, the interfaces would forever wait for an "ifup", and would remain administratively down.

There was one more gotcha, related to my requirement that the machine must be able to boot (and start DHCP) with both Ethernets detached. The machine would hang during boot, with systemd waiting for the interfaces to come up. The solution is:

systemctl disable systemd-networkd-wait-online.service

Not sure if this was required while still using systemd-networkd, or even after I reverted to /etc/network/interfaces.

2
  • 2
    Maybe ConfigureWithoutCarrier=yes would have helped.
    – tambre
    Jun 29, 2021 at 10:24
  • Minor nitpit on a great answer: from my own experience, the Linux kernel bridge (kind bridge) does not "summarize the link status of their constituent physical ports". The bridge netdev is completely independent and even must be to do so.
    – TheDiveO
    Apr 12, 2023 at 9:08
1

I believe systemd-networkd has limited DHCPServer support, based on https://www.freedesktop.org/software/systemd/man/systemd.network.html#%5BDHCPServer%5D%20Section%20Options

However you are probably better off using isc-dhcp-server if you need to fine tune MULTIPLE subnets of DHCP at once or provide advanced DHCP options and such.

I have an LXD network which uses an 18.04 container that serves DHCP to all other containers on that subnet via isc-dhcp-server. It seems to work fine with systemd-networkd and netplan DHCP clients.

Note that in either case whichever you use the DHCP server should have a static IP address outside the DHCP pool; this way the server behaves consistently.

1
  • 1
    Yeah, the built in DHCP server for systemd-networkd is lacking. I was able to get the isc-dhcp-server working on the LAN network and it appears to work much better. Jul 4, 2019 at 17:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .