]> git.ipfire.org Git - people/ms/network.git/commitdiff
networkd: Export ports over dbus
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 11 Feb 2023 12:34:41 +0000 (12:34 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 11 Feb 2023 12:40:18 +0000 (12:40 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/networkd/daemon-bus.c
src/networkd/daemon.c
src/networkd/daemon.h
src/networkd/port-bus.c [new file with mode: 0644]
src/networkd/port-bus.h [new file with mode: 0644]
src/networkd/port.c
src/networkd/port.h
src/networkd/ports.c
src/networkd/ports.h

index a27736a714b5b251094b02822ec90a3a1790d543..893f1b8394447cb3d3189ce417fe7720a81c1520 100644 (file)
@@ -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 \
index aac9775fd8af5f21882fe6d1eb65af051cb21362..ca0754f58275eb230eee54b73f4cc67b35fee750 100644 (file)
@@ -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),
 };
index aee27e3d076a795f0ce56ac745c86942d75f37d3..795a8b761b5d611fa3cc8a3ae1452c569341d629 100644 (file)
@@ -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
 */
index 8e534c57715cb128317b1a72aafe0184e2425ac6..e08537e891000adf2c9d64b0dd92d82ed895f92b 100644 (file)
@@ -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 (file)
index 0000000..8c327b9
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <errno.h>
+
+#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 (file)
index 0000000..95e49a8
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#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 */
index 89f31812b10851f790d91edfe3b6789d44c7d92b..d1e3f7ff9294204a844804c35b02b7ab8d89ec3b 100644 (file)
@@ -23,6 +23,8 @@
 #include <stdint.h>
 #include <stdlib.h>
 
+#include <systemd/sd-bus.h>
+
 #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;
+}
index af7fbdddca925a639f86204a30bd9c46dd8725d0..e3655cff8e266f8cfbd153dd6e9a4518499d6d85 100644 (file)
@@ -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 */
index 19a3a5979c0280324d92def503b63463be4bcae9..24bd257915cb6a3ce2d7496e6de5e992148664d1 100644 (file)
@@ -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;
+}
index 76a4a3ad34d54111569250a38c4ac8c5f59d8251..e807e25bae4de5c28ef57651bc3db14c2ac306ea 100644 (file)
@@ -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 */