From 19e74c9b5d7e9372a3ea9d27579ba8608626459d Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Wed, 1 Feb 2023 22:40:04 +0000 Subject: [PATCH] networkd: Read all zones from configuration Signed-off-by: Michael Tremer --- src/networkd/daemon.c | 131 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 1 deletion(-) diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c index 5b097c29..86731d15 100644 --- a/src/networkd/daemon.c +++ b/src/networkd/daemon.c @@ -18,9 +18,11 @@ # # #############################################################################*/ +#include #include #include #include +#include #include #include @@ -30,6 +32,14 @@ #include "config.h" #include "daemon.h" #include "logging.h" +#include "zone.h" + +struct nw_daemon_zone { + struct nw_zone* zone; + + // Link to the other zones + STAILQ_ENTRY(nw_daemon_zone) nodes; +}; struct nw_daemon { int nrefs; @@ -41,6 +51,9 @@ struct nw_daemon { // DBus Connection sd_bus* bus; + + // Zones + STAILQ_HEAD(zones, nw_daemon_zone) zones; }; static int __nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si, @@ -106,7 +119,85 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) { return 0; } -static int nw_daemon_setup(struct nw_daemon* daemon) { +static int nw_daemon_load_zone_filter(const struct dirent* path) { + const char* fn = path->d_name; + + // Ignore everything starting with '.' + if (*fn == '.') + return 0; + + // Ignore anything that isn't a directory + if (path->d_type != DT_DIR) + return 0; + + return 1; +} + +static int nw_daemon_add_zone(struct nw_daemon* daemon, struct nw_zone* zone) { + // Allocate a new entry + struct nw_daemon_zone* entry = calloc(1, sizeof(*entry)); + if (!entry) + return 1; + + // Reference the zone + entry->zone = nw_zone_ref(zone); + + // Add it to the list + STAILQ_INSERT_TAIL(&daemon->zones, entry, nodes); + + return 0; +} + +static int nw_daemon_load_zones(struct nw_daemon* daemon) { + struct dirent** paths = NULL; + int n; + int r = 0; + + struct nw_zone* zone = NULL; + + // Scan the zones directory + n = scandir(CONFIG_DIR "/zones", &paths, nw_daemon_load_zone_filter, alphasort); + if (n < 0) { + ERROR("Could not load zones: %m\n"); + return 1; + } + + DEBUG("Found %d zone(s)\n", n); + + // Load all zones + for (int i = 0; i < n; i++) { + const char* name = paths[i]->d_name; + + DEBUG("Loading zone '%s'...\n", name); + + // Create a new zone object + r = nw_zone_create(&zone, name); + if (r) + goto ERROR; + + // Store the zone + r = nw_daemon_add_zone(daemon, zone); + if (r) { + nw_zone_unref(zone); + goto ERROR; + } + + nw_zone_unref(zone); + } + +ERROR: + // Free paths + if (paths) { + for (int i = 0; i < n; i++) { + free(paths[i]); + } + free(paths); + } + + return r; +} + +static int nw_daemon_load_config(struct nw_daemon* daemon) { int r; // Read configuration file @@ -114,6 +205,22 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { if (r) return r; + // Load zones + r = nw_daemon_load_zones(daemon); + if (r) + return r; + + return r; +} + +static int nw_daemon_setup(struct nw_daemon* daemon) { + int r; + + // Read the configuration + r = nw_daemon_load_config(daemon); + if (r) + return r; + // Setup the event loop r = nw_daemon_setup_loop(daemon); if (r) @@ -137,6 +244,9 @@ int nw_daemon_create(struct nw_daemon** daemon) { // Initialize reference counter d->nrefs = 1; + // Initialize zones + STAILQ_INIT(&d->zones); + // Setup the daemon r = nw_daemon_setup(d); if (r) @@ -153,7 +263,26 @@ ERROR: return r; } +static void nw_daemon_free_zones(struct nw_daemon* daemon) { + struct nw_daemon_zone* entry = NULL; + + while (!STAILQ_EMPTY(&daemon->zones)) { + entry = STAILQ_FIRST(&daemon->zones); + + // Dereference the zone + nw_zone_unref(entry->zone); + + // Remove the entry from the list + STAILQ_REMOVE_HEAD(&daemon->zones, nodes); + + // Free the entry + free(entry); + } +} + static void nw_daemon_free(struct nw_daemon* daemon) { + nw_daemon_free_zones(daemon); + if (daemon->config) nw_config_unref(daemon->config); if (daemon->bus) -- 2.47.3