netlink: enumerate existing interfaces at startup

The netlink plugin only receives RTM_NEWLINK events for interfaces that
appear after the plugin starts.  Interfaces that already exist at boot
(e.g., virtio-net in QEMU) never generate events, so their conditions
like net/eth0/exist were never set.

Moving enumeration to PLUGIN_INIT doesn't work because it runs before
cond_init(), so the condition filesystem isn't ready yet.

Fix by registering an HOOK_SVC_PLUGIN callback that queries existing
interfaces and routes.  This hook runs during conf_init(), after the
condition system is initialized.
This commit is contained in:
Aaron Andersen committed 2026-01-14 15:58:22 -05:00
1 parent bbe588ac16
commit 29029bb78f
1 file changed
+21 -1
+21 -1
View File
@@ -406,9 +406,29 @@ static void nl_reconf(void *arg)
cond_reassert("net/");
}
/*
* Initial enumeration of existing interfaces and routes. Called from
* HOOK_SVC_PLUGIN which runs after the condition system is initialized.
* Interfaces that exist before finit starts (e.g., virtio-net in QEMU)
* won't generate RTM_NEWLINK events, so we must query for them.
*/
static void nl_enumerate(void *arg)
{
int sd;
sd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
if (sd < 0)
return;
nl_resync_ifaces(sd, 0);
nl_resync_routes(sd, 1);
close(sd);
}
static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_SVC_RECONF] = { .cb = nl_reconf },
.hook[HOOK_SVC_RECONF] = { .cb = nl_reconf },
.hook[HOOK_SVC_PLUGIN] = { .cb = nl_enumerate },
.io = {
.cb = nl_callback,
.flags = PLUGIN_IO_READ,