From 0c8e7342a7da002e877ed445d0223453acd4b93d Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 2 Feb 2023 00:38:13 +0000 Subject: [PATCH] networkd: Move zone list into an own object Signed-off-by: Michael Tremer --- Makefile.am | 2 + src/networkd/daemon.c | 121 ++---------------------- src/networkd/daemon.h | 4 + src/networkd/zones.c | 213 ++++++++++++++++++++++++++++++++++++++++++ src/networkd/zones.h | 35 +++++++ 5 files changed, 263 insertions(+), 112 deletions(-) create mode 100644 src/networkd/zones.c create mode 100644 src/networkd/zones.h diff --git a/Makefile.am b/Makefile.am index 2046fef2..ae4cb85b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c index a478e601..588aa4e1 100644 --- a/src/networkd/daemon.c +++ b/src/networkd/daemon.c @@ -18,11 +18,8 @@ # # #############################################################################*/ -#include #include #include -#include -#include #include #include @@ -33,13 +30,7 @@ #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); +} diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h index 5b14ef3d..bc69795e 100644 --- a/src/networkd/daemon.h +++ b/src/networkd/daemon.h @@ -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 index 00000000..7d04267f --- /dev/null +++ b/src/networkd/zones.c @@ -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 . # +# # +#############################################################################*/ + +#include +#include +#include +#include + +#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 index 00000000..0d34c3ea --- /dev/null +++ b/src/networkd/zones.h @@ -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 . # +# # +#############################################################################*/ + +#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 */ -- 2.47.3