]> git.ipfire.org Git - network.git/commitdiff
networkd: Read all zones from configuration
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 1 Feb 2023 22:40:04 +0000 (22:40 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 1 Feb 2023 22:40:04 +0000 (22:40 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/networkd/daemon.c

index 5b097c291dd28b8956936a9f68ff8ea458a34ca8..86731d157f57ac3e1766d2687d53ad1c7aed2c7b 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <dirent.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/queue.h>
 
 #include <systemd/sd-bus.h>
 #include <systemd/sd-daemon.h>
 #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)