router/dhcp: make Kea wait for its VLAN sockets

kea-dhcp4-server orders after network-online.target, which under networkd
only waits for the WAN carrier: the vlan-* links are RequiredForOnline=no.
On stellio Kea started before networkd had addressed vlan-lan/vlan-mgmt,
failed both binds and, per its default, kept running with no socket at
all (ss -ulnp showed nothing on :67). Wireless and wired clients'
DISCOVERs reached vlan-lan and were never answered.

Set service-sockets-require-all with a bounded retry so Kea keeps trying
while networkd catches up, and Restart=on-failure on the unit for the
case it still gives up.

Verified with checks.x86_64-linux.router.
This commit is contained in:
2026-09-18 10:06:01 +00:00
parent f98226bc6e
commit 9ea058bfb8
+18 -1
View File
@@ -12,7 +12,19 @@ in
services.kea.dhcp4 = {
enable = true;
settings = {
interfaces-config.interfaces = lib.mapAttrsToList (name: _: "vlan-${name}") dhcpVlans;
interfaces-config = {
interfaces = lib.mapAttrsToList (name: _: "vlan-${name}") dhcpVlans;
# The unit orders after network-online.target, which under networkd
# only waits for the WAN carrier (the vlan-* links are
# RequiredForOnline=no), so Kea can start before vlan-* have their
# addresses. By default it then logs the failed bind and runs with no
# socket at all: clients' DISCOVERs reach vlan-lan and nobody answers.
# Insist on every socket and keep retrying while networkd catches up;
# if it still cannot bind, exit and let systemd restart the unit.
service-sockets-require-all = true;
service-sockets-max-retries = 60;
service-sockets-retry-wait-time = 1000;
};
lease-database = {
type = "memfile";
persist = true;
@@ -44,6 +56,11 @@ in
};
};
systemd.services.kea-dhcp4-server.serviceConfig = {
Restart = "on-failure";
RestartSec = 5;
};
services.blocky = {
enable = true;
settings = {