Dnsmasq does not wait for interface

Hello,

I want dnsmasq to come up after the two defined interfaces are up. Unfortunately, it starts the service after one interface is up.

Here is my config,

services.dnsmasq.enable = true;
services.dnsmasq.settings = {
interface=["vlan80br" "vlan90br"];
except-interface="lo";
bind-interfaces= true;
dhcp-range=["192.168.11.3,192.168.11.5,12h" "192.168.12.3,192.168.12.5,12h"];
};
systemd.services.dnsmasq.requires = ["sys-subsystem-net-devices-vlan80br.device" "sys-subsystem-net-devices-vlan90br.device"];

The systemd.services.dnsmasq.requires should wait for the interfaces. Unfortunately, it doesnt

Jan 19 22:55:14 systemd[1]: Failed to start Dnsmasq Daemon.
Jan 19 22:55:14 systemd[1]: dnsmasq.service: Scheduled restart job, restart counter is at 4.
Jan 19 22:55:14 systemd[1]: Starting Dnsmasq Daemon...
Jan 19 22:55:14 dnsmasq-pre-start[3188]: dnsmasq: syntax check OK.
Jan 19 22:55:14 dnsmasq[3190]: dnsmasq: unknown interface vlan90br
Jan 19 22:55:14 dnsmasq[3190]: unknown interface vlan90br
Jan 19 22:55:14 dnsmasq[3190]: FAILED to start up
Jan 19 22:55:14 systemd[1]: dnsmasq.service: Main process exited, code=exited, status=2/INVALIDARGUMENT

The device is present,

# systemctl list-units --type=device|grep vlan90br
  sys-devices-virtual-net-vlan90br.device                                                                                                                  loaded active plugged /sys/devices/virtual/net/vlan90br
  sys-subsystem-net-devices-vlan90br.device                                                                                                                loaded active plugged /sys/subsystem/net/devices/vlan90br

How do i fix this?

Requires does not imply ordering - that’s why Requires (or Wants) and After are often paired together. See In systemd, what's the difference between After= and Requires=? - Server Fault

Try also setting systemd.services.dnsmasq.after = ["sys-subsystem-net-devices-vlan80br.device" "sys-subsystem-net-devices-vlan90br.device"];

Thanks. I set it up like you mentioned

services.dnsmasq.enable = true;
services.dnsmasq.settings = {
interface=["vlan80br" "vlan90br"];
except-interface="lo";
bind-interfaces= true;
dhcp-range=["192.168.11.3,192.168.11.5,12h" "192.168.12.3,192.168.12.5,12h"];
};
systemd.services.dnsmasq.requires = ["sys-subsystem-net-devices-vlan80br.device" "sys-subsystem-net-devices-vlan90br.device"];
systemd.services.dnsmasq.after = ["sys-subsystem-net-devices-vlan80br.device" "sys-subsystem-net-devices-vlan90br.device"];

which produced,

# cat /etc/systemd/system/dnsmasq.service 
[Unit]
After=network.target systemd-resolved.service sys-subsystem-net-devices-vlan80br.device sys-subsystem-net-devices-vlan90br.device
Description=Dnsmasq Daemon
Requires=sys-subsystem-net-devices-vlan80br.device sys-subsystem-net-devices-vlan90br.device
X-Restart-Triggers=/nix/store/lkhclfil7nr9sj0ijg7iydvwzdlvkj8q-X-Restart-Triggers-dnsmasq

[Service]
Environment="LOCALE_ARCHIVE=/nix/store/yr4m7nrg1p1qbl7fr2n5h04qh3pnzbzh-glibc-locales-2.40-36/lib/locale/locale-archive"
Environment="PATH=/nix/store/84vw00nz5jaxk8zv7asashc3b8y2lfc1-dnsmasq-2.90/bin:/nix/store/6wgd8c9vq93mqxzc7jhkl86mv6qbc360-coreutils-9.5/bin:/nix/store/r99d2m4swgmrv9jvm4l9di40hvanq1aq-findutils-4.10.0/bin:/nix/store/vniy1y5n8g28c55y7788npwc4h09fh7c-gnugrep-3.11/bin:/nix/store/yq39xdwm4z0fhx7dsm8mlpgvcz3vbfg3-gnused-4.9/bin:/nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/bin:/nix/store/84vw00nz5jaxk8zv7asashc3b8y2lfc1-dnsmasq-2.90/sbin:/nix/store/6wgd8c9vq93mqxzc7jhkl86mv6qbc360-coreutils-9.5/sbin:/nix/store/r99d2m4swgmrv9jvm4l9di40hvanq1aq-findutils-4.10.0/sbin:/nix/store/vniy1y5n8g28c55y7788npwc4h09fh7c-gnugrep-3.11/sbin:/nix/store/yq39xdwm4z0fhx7dsm8mlpgvcz3vbfg3-gnused-4.9/sbin:/nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/sbin"
Environment="TZDIR=/nix/store/78mhfhbhfhvx95hjv9hkjx8m0vadynjv-tzdata-2024b/share/zoneinfo"
BusName=uk.org.thekelleys.dnsmasq
ExecReload=/nix/store/6wgd8c9vq93mqxzc7jhkl86mv6qbc360-coreutils-9.5/bin/kill -HUP $MAINPID
ExecStart=/nix/store/84vw00nz5jaxk8zv7asashc3b8y2lfc1-dnsmasq-2.90/bin/dnsmasq -k --enable-dbus --user=dnsmasq -C /nix/store/807302lyblv2s331qljm5148amrpmn08-dnsmasq.conf
ExecStartPre=/nix/store/ihkx94syhx89scpc6l073namgj7m33k9-unit-script-dnsmasq-pre-start/bin/dnsmasq-pre-start
PrivateTmp=true
ProtectHome=true
ProtectSystem=true
Restart=on-failure
Type=dbus

[Install]
WantedBy=multi-user.target

However after a reboot i still see an error,

Jan 20 09:02:41 systemd[1]: dnsmasq.service: Failed with result 'exit-code'.
Jan 20 09:02:41 systemd[1]: Failed to start Dnsmasq Daemon.
Jan 20 09:02:41 systemd[1]: dnsmasq.service: Scheduled restart job, restart counter is at 2.
Jan 20 09:02:41 systemd[1]: Starting Dnsmasq Daemon...
Jan 20 09:02:41 dnsmasq-pre-start[3418]: dnsmasq: syntax check OK.
Jan 20 09:02:41 dnsmasq[3419]: dnsmasq: unknown interface vlan90br
Jan 20 09:02:41 dnsmasq[3419]: unknown interface vlan90br
Jan 20 09:02:41 dnsmasq[3419]: FAILED to start up

Hmm. Instead of making the service wait for a period after boot, is it possible to just prioritize establishing the vlans first?
Im pretty sure that could be set as a boot parameter given this looks like its for a router config right?

I ended up using the following,

systemd.services.dnsmasq.requires = ["network-online.target"];
systemd.services.dnsmasq.after = ["network-online.target"];

With this the service comes up after both the interfaces are up.

Cool, glad i could maybe help?
Either way it sounds like its working as intended now so thats good.