From: Michael Tremer Date: Sat, 11 Feb 2023 12:34:41 +0000 (+0000) Subject: networkd: Export ports over dbus X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7297ba7fab067d53560eaeba7e8aa992cef3308a;p=network.git networkd: Export ports over dbus Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index a27736a7..893f1b83 100644 --- a/Makefile.am +++ b/Makefile.am @@ -325,10 +325,12 @@ dist_networkd_SOURCES = \ src/networkd/links.h \ src/networkd/logging.h \ src/networkd/main.c \ - src/networkd/port.c \ - src/networkd/port.h \ src/networkd/ports.c \ src/networkd/ports.h \ + src/networkd/port.c \ + src/networkd/port.h \ + src/networkd/port-bus.c \ + src/networkd/port-bus.h \ src/networkd/string.h \ src/networkd/util.c \ src/networkd/util.h \ diff --git a/src/networkd/daemon-bus.c b/src/networkd/daemon-bus.c index aac9775f..ca0754f5 100644 --- a/src/networkd/daemon-bus.c +++ b/src/networkd/daemon-bus.c @@ -22,6 +22,7 @@ #include "bus.h" #include "daemon.h" +#include "port-bus.h" #include "zone-bus.h" static int nw_daemon_bus_reload(sd_bus_message* m, void* data, sd_bus_error* error) { @@ -45,5 +46,5 @@ const struct nw_bus_implementation daemon_bus_impl = { .path = "/org/ipfire/network1", .interface = "org.ipfire.network1", .vtables = BUS_VTABLES(daemon_vtable), - .children = BUS_IMPLEMENTATIONS(&zone_bus_impl), + .children = BUS_IMPLEMENTATIONS(&port_bus_impl, &zone_bus_impl), }; diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c index aee27e3d..795a8b76 100644 --- a/src/networkd/daemon.c +++ b/src/networkd/daemon.c @@ -448,6 +448,20 @@ struct nw_link* nw_daemon_get_link_by_ifindex(struct nw_daemon* daemon, int ifin return nw_links_get_by_ifindex(daemon->links, ifindex); } +/* + Ports +*/ +struct nw_ports* nw_daemon_ports(struct nw_daemon* daemon) { + return nw_ports_ref(daemon->ports); +} + +struct nw_port* nw_daemon_get_port_by_name(struct nw_daemon* daemon, const char* name) { + if (!daemon->ports) + return NULL; + + return nw_ports_get_by_name(daemon->ports, name); +} + /* Zones */ diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h index 8e534c57..e08537e8 100644 --- a/src/networkd/daemon.h +++ b/src/networkd/daemon.h @@ -49,6 +49,12 @@ struct nw_links* nw_daemon_links(struct nw_daemon* daemon); void nw_daemon_drop_link(struct nw_daemon* daemon, struct nw_link* link); struct nw_link* nw_daemon_get_link_by_ifindex(struct nw_daemon* daemon, int ifindex); +/* + Ports +*/ +struct nw_ports* nw_daemon_ports(struct nw_daemon* daemon); +struct nw_port* nw_daemon_get_port_by_name(struct nw_daemon* daemon, const char* name); + /* Zones */ diff --git a/src/networkd/port-bus.c b/src/networkd/port-bus.c new file mode 100644 index 00000000..8c327b93 --- /dev/null +++ b/src/networkd/port-bus.c @@ -0,0 +1,89 @@ +/*############################################################################# +# # +# 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 "bus.h" +#include "daemon.h" +#include "logging.h" +#include "port.h" +#include "port-bus.h" +#include "ports.h" + +static int nw_port_node_enumerator(sd_bus* bus, const char* path, void* data, + char*** nodes, sd_bus_error* error) { + int r; + + DEBUG("Enumerating ports...\n"); + + // Fetch a reference to the daemon + struct nw_daemon* daemon = (struct nw_daemon*)data; + + // Fetch ports + struct nw_ports* ports = nw_daemon_ports(daemon); + + // Make bus paths for all ports + r = nw_ports_bus_paths(ports, nodes); + if (r) + goto ERROR; + +ERROR: + nw_ports_unref(ports); + + return r; +} + +static int nw_port_object_find(sd_bus* bus, const char* path, const char* interface, + void* data, void** found, sd_bus_error* error) { + char* name = NULL; + int r; + + // Fetch a reference to the daemon + struct nw_daemon* daemon = (struct nw_daemon*)data; + + // Decode the path of the requested object + r = sd_bus_path_decode(path, "/org/ipfire/network1/port", &name); + if (r <= 0) + return 0; + + // Find the port + struct nw_port* port = nw_daemon_get_port_by_name(daemon, name); + if (!port) + return 0; + + // Match! + *found = port; + + nw_port_unref(port); + + return 1; +} + +static const sd_bus_vtable port_vtable[] = { + SD_BUS_VTABLE_START(0), + SD_BUS_VTABLE_END +}; + +const struct nw_bus_implementation port_bus_impl = { + "/org/ipfire/network1/port", + "org.ipfire.network1.Port", + .fallback_vtables = BUS_FALLBACK_VTABLES({port_vtable, nw_port_object_find}), + .node_enumerator = nw_port_node_enumerator, +}; diff --git a/src/networkd/port-bus.h b/src/networkd/port-bus.h new file mode 100644 index 00000000..95e49a89 --- /dev/null +++ b/src/networkd/port-bus.h @@ -0,0 +1,28 @@ +/*############################################################################# +# # +# 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_PORT_BUS_H +#define NETWORKD_PORT_BUS_H + +#include "bus.h" + +extern const struct nw_bus_implementation port_bus_impl; + +#endif /* NETWORKD_PORT_BUS_H */ diff --git a/src/networkd/port.c b/src/networkd/port.c index 89f31812..d1e3f7ff 100644 --- a/src/networkd/port.c +++ b/src/networkd/port.c @@ -23,6 +23,8 @@ #include #include +#include + #include "address.h" #include "config.h" #include "logging.h" @@ -207,3 +209,15 @@ struct nw_port* nw_port_unref(struct nw_port* port) { const char* nw_port_name(struct nw_port* port) { return port->name; } + +char* nw_port_bus_path(struct nw_port* port) { + char* p = NULL; + int r; + + // Encode the bus path + r = sd_bus_path_encode("/org/ipfire/network1/port", port->name, &p); + if (r < 0) + return NULL; + + return p; +} diff --git a/src/networkd/port.h b/src/networkd/port.h index af7fbddd..e3655cff 100644 --- a/src/networkd/port.h +++ b/src/networkd/port.h @@ -37,4 +37,6 @@ struct nw_port* nw_port_unref(struct nw_port* port); const char* nw_port_name(struct nw_port* port); +char* nw_port_bus_path(struct nw_port* port); + #endif /* NETWORKD_PORT_H */ diff --git a/src/networkd/ports.c b/src/networkd/ports.c index 19a3a597..24bd2579 100644 --- a/src/networkd/ports.c +++ b/src/networkd/ports.c @@ -157,3 +157,55 @@ ERROR: int nw_ports_enumerate(struct nw_ports* ports) { return nw_ftw(PORT_CONFIG_DIR, PORT_CONFIG_DIR "/*", __nw_ports_enumerate, ports); } + +struct nw_port* nw_ports_get_by_name(struct nw_ports* ports, const char* name) { + struct nw_ports_entry* entry = NULL; + + STAILQ_FOREACH(entry, &ports->entries, nodes) { + const char* __name = nw_port_name(entry->port); + + // If the name matches, return a reference to the zone + if (strcmp(name, __name) == 0) + return nw_port_ref(entry->port); + } + + // No match found + return NULL; +} + +int nw_ports_bus_paths(struct nw_ports* ports, char*** paths) { + struct nw_ports_entry* entry = NULL; + char* path = NULL; + + // Allocate an array for all paths + char** p = calloc(ports->num + 1, sizeof(*p)); + if (!p) + return 1; + + unsigned int i = 0; + + // Walk through all ports + STAILQ_FOREACH(entry, &ports->entries, nodes) { + // Generate the bus path + path = nw_port_bus_path(entry->port); + 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/ports.h b/src/networkd/ports.h index 76a4a3ad..e807e25b 100644 --- a/src/networkd/ports.h +++ b/src/networkd/ports.h @@ -32,4 +32,8 @@ struct nw_ports* nw_ports_unref(struct nw_ports* ports); int nw_ports_enumerate(struct nw_ports* ports); -#endif /* NETWORKD_ZONES_H */ +struct nw_port* nw_ports_get_by_name(struct nw_ports* ports, const char* name); + +int nw_ports_bus_paths(struct nw_ports* ports, char*** paths); + +#endif /* NETWORKD_PORTS_H */