From: Michael Tremer Date: Thu, 2 Feb 2023 00:53:21 +0000 (+0000) Subject: networkd: Implement enumerating zones on the bus X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ebc65f19ecbf67f9c8a739316afe4892d4f6a732;p=network.git networkd: Implement enumerating zones on the bus Signed-off-by: Michael Tremer --- diff --git a/src/networkd/bus.c b/src/networkd/bus.c index e854f7ba..26876fa8 100644 --- a/src/networkd/bus.c +++ b/src/networkd/bus.c @@ -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; } diff --git a/src/networkd/bus.h b/src/networkd/bus.h index 55e65b81..6232ebb1 100644 --- a/src/networkd/bus.h +++ b/src/networkd/bus.h @@ -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, diff --git a/src/networkd/zone-bus.c b/src/networkd/zone-bus.c index 97396c51..ebd87898 100644 --- a/src/networkd/zone-bus.c +++ b/src/networkd/zone-bus.c @@ -19,9 +19,38 @@ #############################################################################*/ #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, }; diff --git a/src/networkd/zone.c b/src/networkd/zone.c index 4790d334..f78334e6 100644 --- a/src/networkd/zone.c +++ b/src/networkd/zone.c @@ -21,6 +21,8 @@ #include #include +#include + #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; +} diff --git a/src/networkd/zone.h b/src/networkd/zone.h index 78287ab3..081a720a 100644 --- a/src/networkd/zone.h +++ b/src/networkd/zone.h @@ -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 */ diff --git a/src/networkd/zones.c b/src/networkd/zones.c index 7d04267f..4f739f52 100644 --- a/src/networkd/zones.c +++ b/src/networkd/zones.c @@ -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; +} diff --git a/src/networkd/zones.h b/src/networkd/zones.h index 0d34c3ea..6e2686d0 100644 --- a/src/networkd/zones.h +++ b/src/networkd/zones.h @@ -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 */