]> git.ipfire.org Git - people/ms/network.git/commitdiff
ports: Implement listing ports over DBus
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 4 Jun 2023 16:50:35 +0000 (16:50 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 4 Jun 2023 16:50:35 +0000 (16:50 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/networkctl/main.c
src/networkctl/port.c [new file with mode: 0644]
src/networkctl/port.h [new file with mode: 0644]
src/networkd/daemon-bus.c

index aafa59c0e2d9f29d274b79b7846e4dce467778c6..273302b3f92036b9307fc8325edd09530e98b719 100644 (file)
@@ -392,6 +392,8 @@ dist_networkctl_SOURCES = \
        src/networkctl/command.c \
        src/networkctl/command.h \
        src/networkctl/main.c \
+       src/networkctl/port.c \
+       src/networkctl/port.h \
        src/networkctl/zone.c \
        src/networkctl/zone.h
 
index a08256cec64522bd68dda493e2fe3e465dac5a1c..73908f8f810940ee46841cb94bdb8523dc2b75f9 100644 (file)
@@ -26,6 +26,7 @@
 #include <systemd/sd-bus.h>
 
 #include "command.h"
+#include "port.h"
 #include "zone.h"
 
 static int networkctl_status(sd_bus* bus, int argc, char* argv[]) {
@@ -35,6 +36,7 @@ static int networkctl_status(sd_bus* bus, int argc, char* argv[]) {
 
 static int networkctl_main(sd_bus* bus, int argc, char* argv[]) {
        static const struct command commands[] = {
+               { "port",   0, networkctl_port },
                { "status", 0, networkctl_status },
                { "zone",   0, networkctl_zone },
                { NULL },
diff --git a/src/networkctl/port.c b/src/networkctl/port.c
new file mode 100644 (file)
index 0000000..689e2f1
--- /dev/null
@@ -0,0 +1,97 @@
+/*#############################################################################
+#                                                                             #
+# 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 <systemd/sd-bus.h>
+
+#include "command.h"
+#include "port.h"
+
+typedef int (*networkctl_port_walk_callback)
+       (sd_bus* bus, const char* path, const char* name, void* data);
+
+static int networkctl_port_walk(sd_bus* bus,
+               networkctl_port_walk_callback callback, void* data) {
+       sd_bus_message* reply = NULL;
+       sd_bus_error error = SD_BUS_ERROR_NULL;
+       int r;
+
+       // Call Listports
+       r = sd_bus_call_method(bus, "org.ipfire.network1", "/org/ipfire/network1",
+               "org.ipfire.network1", "ListPorts", &error, &reply, "");
+       if (r < 0) {
+               fprintf(stderr, "Listports call failed: %m\n");
+               goto ERROR;
+       }
+
+       const char* name = NULL;
+       const char* path = NULL;
+
+       // Open the container
+       r = sd_bus_message_enter_container(reply, 'a', "(so)");
+       if (r < 0) {
+               fprintf(stderr, "Could not open container: %m\n");
+               goto ERROR;
+       }
+
+       // Iterate over all ports
+       for (;;) {
+               r = sd_bus_message_read(reply, "(so)", &name, &path);
+               if (r < 0)
+                       goto ERROR;
+
+               // Break if we reached the end of the container
+               if (r == 0)
+                       break;
+
+               // Call the callback
+               r = callback(bus, path, name, data);
+               if (r)
+                       goto ERROR;
+       }
+
+       // Close the container
+       sd_bus_message_exit_container(reply);
+
+ERROR:
+       if (reply)
+               sd_bus_message_unref(reply);
+       sd_bus_error_free(&error);
+
+       return r;
+}
+
+static int __networkctl_port_list(sd_bus* bus, const char* path, const char* name, void* data) {
+       printf("%s\n", name);
+
+       return 0;
+}
+
+static int networkctl_port_list(sd_bus* bus, int argc, char* argv[]) {
+       return networkctl_port_walk(bus, __networkctl_port_list, NULL);
+}
+
+int networkctl_port(sd_bus* bus, int argc, char* argv[]) {
+       static const struct command commands[] = {
+               { "list", 0, networkctl_port_list },
+               { NULL },
+       };
+
+       return command_dispatch(bus, commands, argc, argv);
+}
diff --git a/src/networkctl/port.h b/src/networkctl/port.h
new file mode 100644 (file)
index 0000000..2326ce6
--- /dev/null
@@ -0,0 +1,26 @@
+/*#############################################################################
+#                                                                             #
+# 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 NETWORKCTL_PORT_H
+#define NETWORKCTL_PORT_H
+
+int networkctl_port(sd_bus* bus, int argc, char* argv[]);
+
+#endif /* NETWORKCTL_PORT_H */
index 7620eed8f152fbd3f6d86af515a367be7b11376b..4de8c0fb35a6c2455f9262bf50bccdaf76257561 100644 (file)
@@ -39,6 +39,55 @@ static int nw_daemon_bus_reload(sd_bus_message* m, void* data, sd_bus_error* err
        return sd_bus_reply_method_return(m, NULL);
 }
 
+static int __nw_daemon_bus_list_ports(nw_daemon* daemon, nw_port* port, void* data) {
+       sd_bus_message* reply = (sd_bus_message*)data;
+       int r;
+
+       // Fetch port name
+       const char* name = nw_port_name(port);
+
+       // Fetch bus path
+       char* path = nw_port_bus_path(port);
+
+       r = sd_bus_message_append(reply, "(so)", name, path);
+
+       free(path);
+
+       return r;
+}
+
+static int nw_daemon_bus_list_ports(sd_bus_message* m, void* data, sd_bus_error* error) {
+       nw_daemon* daemon = (nw_daemon*)data;
+       sd_bus_message* reply = NULL;
+       int r;
+
+       // Form a reply message
+       r = sd_bus_message_new_method_return(m, &reply);
+       if (r < 0)
+               goto ERROR;
+
+       r = sd_bus_message_open_container(reply, 'a', "(so)");
+       if (r < 0)
+               goto ERROR;
+
+       r = nw_daemon_ports_walk(daemon, __nw_daemon_bus_list_ports, reply);
+       if (r < 0)
+               goto ERROR;
+
+       r = sd_bus_message_close_container(reply);
+       if (r < 0)
+               goto ERROR;
+
+       // Send the reply
+       r = sd_bus_send(NULL, reply, NULL);
+
+ERROR:
+       if (reply)
+               sd_bus_message_unref(reply);
+
+       return r;
+}
+
 static int __nw_daemon_bus_list_zones(nw_daemon* daemon, nw_zone* zone, void* data) {
        sd_bus_message* reply = (sd_bus_message*)data;
        int r;
@@ -90,6 +139,8 @@ ERROR:
 
 static const sd_bus_vtable daemon_vtable[] = {
        SD_BUS_VTABLE_START(0),
+       SD_BUS_METHOD_WITH_ARGS("ListPorts", SD_BUS_NO_ARGS, SD_BUS_RESULT("a(so)", links),
+               nw_daemon_bus_list_ports, SD_BUS_VTABLE_UNPRIVILEGED),
        SD_BUS_METHOD_WITH_ARGS("ListZones", SD_BUS_NO_ARGS, SD_BUS_RESULT("a(so)", links),
                nw_daemon_bus_list_zones, SD_BUS_VTABLE_UNPRIVILEGED),
        SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT,