]> git.ipfire.org Git - network.git/commitdiff
networkd: Implement enumerating zones on the bus
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 2 Feb 2023 00:53:21 +0000 (00:53 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 2 Feb 2023 00:53:21 +0000 (00:53 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/networkd/bus.c
src/networkd/bus.h
src/networkd/zone-bus.c
src/networkd/zone.c
src/networkd/zone.h
src/networkd/zones.c
src/networkd/zones.h

index e854f7ba95dc6f6f53609ab3de71ba56c01b53b5..26876fa888162db0eef871fa06e224e5e216280c 100644 (file)
@@ -27,6 +27,7 @@
 #include "bus.h"
 #include "daemon.h"
 #include "logging.h"
+#include "zone-bus.h"
 
 static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* error) {
        struct nw_daemon* daemon = (struct nw_daemon*)data;
@@ -49,6 +50,7 @@ const struct nw_bus_implementation daemon_implementation = {
        .path = "/org/ipfire/network1",
        .interface = "org.ipfire.network1",
        .vtables = BUS_VTABLES(daemon_vtable),
+       .children = BUS_IMPLEMENTATIONS(&zone_bus_impl),
 };
 
 static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) {
@@ -169,5 +171,21 @@ int nw_bus_register_implementation(sd_bus* bus,
                }
        }
 
+       // Register the node enumerator
+       if (impl->node_enumerator) {
+               r = sd_bus_add_node_enumerator(bus, NULL, impl->path, impl->node_enumerator, data);
+               if (r < 0) {
+                       ERROR("Could not add the node enumerator for %s: %m\n", impl->path);
+                       return 1;
+               }
+       }
+
+       // Register any child implementations
+       for (int i = 0; impl->children && impl->children[i]; i++) {
+               r = nw_bus_register_implementation(bus, impl->children[i], data);
+               if (r)
+                       return r;
+       }
+
        return 0;
 }
index 55e65b817300e182b9d49539ba17eb9f988438be..6232ebb1f119bcfcd0a97e27890ec77ab1e7b2e9 100644 (file)
@@ -37,8 +37,11 @@ struct nw_bus_implementation {
        const char* interface;
 
        const sd_bus_vtable** vtables;
+       sd_bus_node_enumerator_t node_enumerator;
+       const struct nw_bus_implementation** children;
 };
 
+#define BUS_IMPLEMENTATIONS(...) ((const struct nw_bus_implementation* []) { __VA_ARGS__, NULL })
 #define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL })
 
 int nw_bus_register_implementation(sd_bus* bus,
index 97396c51da744d57c0353f15d06a71f35f910b30..ebd878988e45981bf52e8886a7673dcbc18ff777 100644 (file)
 #############################################################################*/
 
 #include "bus.h"
+#include "daemon.h"
+#include "logging.h"
+#include "zone.h"
 #include "zone-bus.h"
+#include "zones.h"
+
+static int nw_zone_node_enumerator(sd_bus* bus, const char* path, void* data,
+               char*** nodes, sd_bus_error* error) {
+       int r;
+
+       DEBUG("Enumerating zones...\n");
+
+       // Fetch a reference to the daemon
+       struct nw_daemon* daemon = (struct nw_daemon*)data;
+
+       // Fetch zones
+       struct nw_zones* zones = nw_daemon_zones(daemon);
+
+       // Make bus paths for all zones
+       r = nw_zones_bus_paths(zones, nodes);
+       if (r)
+               goto ERROR;
+
+ERROR:
+       nw_zones_unref(zones);
+
+       return r;
+}
 
 const struct nw_bus_implementation zone_bus_impl = {
        "/org/ipfire/network1/zone",
        "org.ipfire.network1.Zone",
+       //.fallback_vtables = BUS_FALLBACK_VTABLES({zone_bus_vtable, nw_zone_object_find}),
+       .node_enumerator = nw_zone_node_enumerator,
 };
index 4790d334de03f9ecc1c977ea012cb40bf2df7e35..f78334e6e19441e75339a5f84123d89d445e645e 100644 (file)
@@ -21,6 +21,8 @@
 #include <limits.h>
 #include <stdlib.h>
 
+#include <systemd/sd-bus.h>
+
 #include "config.h"
 #include "string.h"
 #include "zone.h"
@@ -130,3 +132,15 @@ struct nw_zone* nw_zone_unref(struct nw_zone* zone) {
 const char* nw_zone_name(struct nw_zone* zone) {
        return zone->name;
 }
+
+char* nw_zone_bus_path(struct nw_zone* zone) {
+       char* p = NULL;
+       int r;
+
+       // Encode the bus path
+       r = sd_bus_path_encode("/org/ipfire/network1/zone", zone->name, &p);
+       if (r < 0)
+               return NULL;
+
+       return p;
+}
index 78287ab38e059d79ff109397bcf314c2f56e37a8..081a720a0930865513cd7cb047ff996d793024fe 100644 (file)
@@ -32,4 +32,6 @@ struct nw_zone* nw_zone_unref(struct nw_zone* zone);
 
 const char* nw_zone_name(struct nw_zone* zone);
 
+char* nw_zone_bus_path(struct nw_zone* zone);
+
 #endif /* NETWORKD_ZONE_H */
index 7d04267fb54c229159bad4ecb5b205aaf94bc5f7..4f739f52069756a84b3c9b8deebe13f20dc7cc4a 100644 (file)
@@ -37,7 +37,11 @@ struct nw_zones_entry {
 struct nw_zones {
        int nrefs;
 
+       // Zone Entries
        STAILQ_HEAD(entries, nw_zones_entry) entries;
+
+       // A counter of the zone entries
+       unsigned int num;
 };
 
 static int nw_zones_create(struct nw_zones** zones) {
@@ -100,6 +104,9 @@ static int nw_zones_add_zone(struct nw_zones* zones, struct nw_zone* zone) {
        // Add it to the list
        STAILQ_INSERT_TAIL(&zones->entries, entry, nodes);
 
+       // Increment the counter
+       zones->num++;
+
        return 0;
 }
 
@@ -211,3 +218,40 @@ struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name) {
        // No match found
        return NULL;
 }
+
+int nw_zones_bus_paths(struct nw_zones* zones, char*** paths) {
+       struct nw_zones_entry* entry = NULL;
+       char* path = NULL;
+
+       // Allocate an array for all paths
+       char** p = calloc(zones->num + 1, sizeof(*p));
+       if (!p)
+               return 1;
+
+       unsigned int i = 0;
+
+       // Walk through all zones
+       STAILQ_FOREACH(entry, &zones->entries, nodes) {
+               // Generate the bus path
+               path = nw_zone_bus_path(entry->zone);
+               if (!path)
+                       goto ERROR;
+
+               // Append the bus path to the array
+               p[i++] = path;
+       }
+
+       // Return pointer
+       *paths = p;
+
+       return 0;
+
+ERROR:
+       if (p) {
+               for (char** e = p; *e; e++)
+                       free(*e);
+               free(p);
+       }
+
+       return 1;
+}
index 0d34c3ea64ecb0eb9b2675a63f67a7aaa54c5fcb..6e2686d0493e992aa83801fee4f050d7af7c944d 100644 (file)
@@ -32,4 +32,6 @@ size_t nw_zones_num(struct nw_zones* zones);
 
 struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name);
 
+int nw_zones_bus_paths(struct nw_zones* zones, char*** paths);
+
 #endif /* NETWORKD_ZONES_H */