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 \
# #
#############################################################################*/
-#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;
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,
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;
return r;
// Load zones
- r = nw_daemon_load_zones(daemon);
+ r = nw_zones_load(&daemon->zones);
if (r)
return r;
// Initialize reference counter
d->nrefs = 1;
- // Initialize zones
- STAILQ_INIT(&d->zones);
-
// Setup the daemon
r = nw_daemon_setup(d);
if (r)
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)
return 0;
}
+
+struct nw_zones* nw_daemon_zones(struct nw_daemon* daemon) {
+ return nw_zones_ref(daemon->zones);
+}
#ifndef NETWORKD_DAEMON_H
#define NETWORKD_DAEMON_H
+#include "zone.h"
+
struct nw_daemon;
int nw_daemon_create(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 */
--- /dev/null
+/*#############################################################################
+# #
+# 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;
+}
--- /dev/null
+/*#############################################################################
+# #
+# 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 */