]> git.ipfire.org Git - network.git/commitdiff
networkd: Move zone list into an own object
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 2 Feb 2023 00:38:13 +0000 (00:38 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 2 Feb 2023 00:38:13 +0000 (00:38 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/networkd/daemon.c
src/networkd/daemon.h
src/networkd/zones.c [new file with mode: 0644]
src/networkd/zones.h [new file with mode: 0644]

index 2046fef2a31a682af179d4ab6867a6028a7c5c4d..ae4cb85ba8f48f068f20f8a0ff87a9830d6d7007 100644 (file)
@@ -317,6 +317,8 @@ dist_networkd_SOURCES = \
        src/networkd/logging.h \
        src/networkd/main.c \
        src/networkd/string.h \
+       src/networkd/zones.c \
+       src/networkd/zones.h \
        src/networkd/zone.c \
        src/networkd/zone.h \
        src/networkd/zone-bus.c \
index a478e6015fb86280900ecc3300fab756500778c5..588aa4e1e186bad7a839838fecbaf638eb5b0f6e 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 "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;
-};
+#include "zones.h"
 
 struct nw_daemon {
        int nrefs;
@@ -53,7 +44,7 @@ struct nw_daemon {
        sd_bus* bus;
 
        // Zones
-       STAILQ_HEAD(zones, nw_daemon_zone) zones;
+       struct nw_zones* zones;
 };
 
 static int __nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si,
@@ -119,84 +110,6 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) {
        return 0;
 }
 
-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;
 
@@ -206,7 +119,7 @@ static int nw_daemon_load_config(struct nw_daemon* daemon) {
                return r;
 
        // Load zones
-       r = nw_daemon_load_zones(daemon);
+       r = nw_zones_load(&daemon->zones);
        if (r)
                return r;
 
@@ -244,9 +157,6 @@ 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)
@@ -263,26 +173,9 @@ 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->zones)
+               nw_zones_unref(daemon->zones);
        if (daemon->config)
                nw_config_unref(daemon->config);
        if (daemon->bus)
@@ -342,3 +235,7 @@ int nw_daemon_reload(struct nw_daemon* daemon) {
 
        return 0;
 }
+
+struct nw_zones* nw_daemon_zones(struct nw_daemon* daemon) {
+       return nw_zones_ref(daemon->zones);
+}
index 5b14ef3dff6770291823c98c7ad84ac5a7fa2874..bc69795eef5af1da63d4fdc6858e086c43beeead 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef NETWORKD_DAEMON_H
 #define NETWORKD_DAEMON_H
 
+#include "zone.h"
+
 struct nw_daemon;
 
 int nw_daemon_create(struct nw_daemon** daemon);
@@ -32,4 +34,6 @@ int nw_daemon_run(struct nw_daemon* daemon);
 
 int nw_daemon_reload(struct nw_daemon* daemon);
 
+struct nw_zones* nw_daemon_zones(struct nw_daemon* daemon);
+
 #endif /* NETWORKD_DAEMON_H */
diff --git a/src/networkd/zones.c b/src/networkd/zones.c
new file mode 100644 (file)
index 0000000..7d04267
--- /dev/null
@@ -0,0 +1,213 @@
+/*#############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2023 IPFire Network Development Team                          #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <dirent.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/queue.h>
+
+#include "logging.h"
+#include "zone.h"
+#include "zones.h"
+
+struct nw_zones_entry {
+       struct nw_zone* zone;
+
+       // Link to the other entries
+       STAILQ_ENTRY(nw_zones_entry) nodes;
+};
+
+struct nw_zones {
+       int nrefs;
+
+       STAILQ_HEAD(entries, nw_zones_entry) entries;
+};
+
+static int nw_zones_create(struct nw_zones** zones) {
+       struct nw_zones* z = calloc(1, sizeof(*z));
+       if (!z)
+               return 1;
+
+       // Initialize the reference counter
+       z->nrefs = 1;
+
+       // Initialize entries
+       STAILQ_INIT(&z->entries);
+
+       // Reference the pointer
+       *zones = z;
+
+       return 0;
+}
+
+static void nw_zones_free(struct nw_zones* zones) {
+       struct nw_zones_entry* entry = NULL;
+
+       while (!STAILQ_EMPTY(&zones->entries)) {
+               entry = STAILQ_FIRST(&zones->entries);
+
+               // Dereference the zone
+               nw_zone_unref(entry->zone);
+
+               // Remove the entry from the list
+               STAILQ_REMOVE_HEAD(&zones->entries, nodes);
+
+               // Free the entry
+               free(entry);
+       }
+}
+
+struct nw_zones* nw_zones_ref(struct nw_zones* zones) {
+       zones->nrefs++;
+
+       return zones;
+}
+
+struct nw_zones* nw_zones_unref(struct nw_zones* zones) {
+       if (--zones->nrefs > 0)
+               return zones;
+
+       nw_zones_free(zones);
+       return NULL;
+}
+
+static int nw_zones_add_zone(struct nw_zones* zones, struct nw_zone* zone) {
+       // Allocate a new entry
+       struct nw_zones_entry* 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(&zones->entries, entry, nodes);
+
+       return 0;
+}
+
+static int nw_zones_load_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_zones_load(struct nw_zones* zones) {
+       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_zones_load_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_zones_add_zone(zones, 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;
+}
+
+int nw_zones_load(struct nw_zones** zones) {
+       int r;
+
+       // Create a new zones object
+       r = nw_zones_create(zones);
+       if (r)
+               return r;
+
+       // Load all zones
+       r = __nw_zones_load(*zones);
+       if (r)
+               goto ERROR;
+
+       return 0;
+
+ERROR:
+       nw_zones_unref(*zones);
+       return r;
+}
+
+size_t nw_zones_num(struct nw_zones* zones) {
+       struct nw_zones_entry* entry = NULL;
+       size_t length = 0;
+
+       // Count all zones
+       STAILQ_FOREACH(entry, &zones->entries, nodes)
+               length++;
+
+       return length;
+}
+
+struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name) {
+       struct nw_zones_entry* entry = NULL;
+
+       STAILQ_FOREACH(entry, &zones->entries, nodes) {
+               const char* __name = nw_zone_name(entry->zone);
+
+               // If the name matches, return a reference to the zone
+               if (strcmp(name, __name) == 0)
+                       return nw_zone_ref(entry->zone);
+       }
+
+       // No match found
+       return NULL;
+}
diff --git a/src/networkd/zones.h b/src/networkd/zones.h
new file mode 100644 (file)
index 0000000..0d34c3e
--- /dev/null
@@ -0,0 +1,35 @@
+/*#############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2023 IPFire Network Development Team                          #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifndef NETWORKD_ZONES_H
+#define NETWORKD_ZONES_H
+
+struct nw_zones;
+
+struct nw_zones* nw_zones_ref(struct nw_zones* zones);
+struct nw_zones* nw_zones_unref(struct nw_zones* zones);
+
+int nw_zones_load(struct nw_zones** zones);
+
+size_t nw_zones_num(struct nw_zones* zones);
+
+struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name);
+
+#endif /* NETWORKD_ZONES_H */