Joachim Breitner's Homepage
Switching to systemd-networkd
Ever since I read about systemd-networkd being in the making I was looking forward to try it out. I kept watching for the package to appear in Debian, or at least ITP bugs. A few days ago, by accident, I noticed that I already have systemd-networkd on my machine: It is simply shipped with the systemd package!
My previous setup was a combination of ifplugd
to detect when I plug or unplug the ethernet cable with a plain DHCP entry in /etc/network/interface
. A while ago I was using guessnet
to do a static setup depending on where I am, but I don’t need this flexibility any more, so the very simple approach with systemd-networkd
is just fine with me. So after stopping ifplugd
and
$ cat > /etc/systemd/network/eth.network <<__END__
[Match]
Name=eth0
[Network]
DHCP=yes
__END__
$ systemctl enable systemd-networkd
$ systemctl start systemd-networkd
I was ready to go. Indeed, systemd-networkd
, probably due to the integrated dhcp client, felt quite a bit faster than the old setup. And what’s more important (and my main motivation for the switch): It did the right thing when I put it to sleep in my office, unplug it there, go home, plug it in and wake it up. ifplugd
failed to detect this change and I often had to manually run ifdown eth0 && ifup eth0
; this now works.
But then I was bitten by what I guess some people call the viral nature of systemd
: systemd-networkd
would not update /etc/resolv.conf
, but rather relies on systemd-resolved
. And that requires me to change /etc/resolv.conf
to be a symlink to /run/systemd/resolve/resolv.conf
. But of course I also use my wireless adapter, which, at that point, was still managed using ifupdown
, which would use dhclient
which updates /etc/resolv.conf
directly.
So I investigated if I can use systemd-networkd
also for my wireless account. I am not using NetworkManager or the like, but rather keep wpa_supplicant
running in roaming mode, controlled from ifupdown
(not sure how that exactly works and what controls what, but it worked). I found out that this setup works just fine with systemd-networkd
: I start wpa_supplicant
with this service file (which I found in the wpa_supplicant repo, but not yet in the Debian package)(which comes with the Debian package since version 2.5-1):
[Unit]
Description=WPA supplicant daemon (interface-specific version)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
[Service]
Type=simple
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I
[Install]
Alias=multi-user.target.wants/wpa_supplicant@%i.service
After enabling this with systemctl enable wpa_supplicant@wlan0.service
, systemd starts wpa_supplicant
and wpa_supplicant
will get the interface up and down as it goes, while systemd-networkd
, equipped with
[Match]
Name=wlan0
[Network]
DHCP=yes
does the rest.
So suddenly I have a system without /etc/init.d/networking
and without ifup
. Feels a bit strange, but also makes sense. I still need to migrate how I manage my UMTS modem device to that model.
The only thing that I’m missing so far is a way to trigger actions when the network configuration has changes, like I could with /etc/network/if-up.d/
etc. I want to run things like killall -ALRM tincd
and exim -qf
. If you know how to do that, please tell me, or answer over at Stack Exchange.
Comments
It looks like networkd has no support for hooks. However, the systemd-networkd code contains some interesting comments:
/* Always create the directories people can create inotify
* watches in. */
r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid);
if (r < 0)
log_error("Could not create runtime directory: %s",
strerror(-r));
r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid);
if (r < 0)
log_error("Could not create runtime directory 'links': %s",
strerror(-r));
r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid);
if (r < 0)
log_error("Could not create runtime directory 'leases': %s",
strerror(-r));
In particular, there is /run/systemd/netif/state
, which contains something like:
# This is private data. Do not parse.
OPER_STATE=routable
Now, you can always ignore the warning about parsing and add a small hack by setting up an inotify watch (or a path-activated unit) and trigger actions whenever your network transitions to routable.
The intention is to expose the network state per link via the files in /run
that you found. However, the official API will be a C library (sd-network
), rather than the files themselves (which allows us some liberty in changing the implementation later on).
The library has not been exposed yet (still need to go through another round of review I think), but you can find the headers in src/systemd/sd-network.h
if you want to have a look. It exposes change events (internally over inotify) and introspection of the files.
This is a very late comment, but /etc/resolv.conf
was constantly misspelled in the blog post. But I guess that wasn’t part of the problem?
No, I do not think it was. But thanks for the notice, I fixed the blog post :-)
You can use your modem in combination with systemd-networkd like that:
# First, mask NetworkManager (if not done already)
systemctl mask NetworkManager
# Unmask, enable and start ModemManager
systemctl unmask ModemManager
systemctl enable ModemManager
systemctl start ModemManager
# Add a .network file for your modem network interface:
cat /etc/systemd/network/wwp0s20u6c2i12.network:
[Match]
Name=wwp0s20u6c2i12
[Network]
DHCP=both
# restart systemd-networkd:
systemctl restart systemd-networkd
# Scripts to enable and disable the modem and the corresponding network
# interface:
cat /usr/local/bin/modem-connect:
#!/bin/sh
mmcli -m 0 --simple-connect="apn=APN_HERE"
# also enter ,pin= if needed
ifconfig wwp0s20u6c2i12 up
cat /usr/local/bin/modem-disconnect:
#!/bin/sh
ifconfig wwp0s20u6c2i12 down
mmcli -m 0 --simple-disconnect
It would also make sense to adjust the RouteMetric parameter in the [DHCP]
section of the .network
file so that the modem connection is not used when other default routes are present. However, this didn’t work for me yet.
I was following that blog and discovered that wpa_supplicant service file is now present in Debian wpa_supplicant package (wpa_supplicant@.service
). Maybe worth mentioning in the blog.
Have something to say? You can post a comment by sending an e-Mail to me at <mail@joachim-breitner.de>, and I will include it here.
The fact that hooks are missing from this design is scary and it spells the end of system administration as we know it. I have also been trying to find ways to do stuff on my system e.g. when I press certain keys or close the lid, and unless systemd provides the behaviour you want, you are out of luck.
And it confirms my theory: systemd sends Unix down the line of Windows: we know the best way to do things, and you don’t need any hooks.