From: Michael Tremer Date: Mon, 30 Jan 2023 02:08:50 +0000 (+0000) Subject: networkd: Add scaffolding to connect to dbus X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=09a6af1750714828bf109e17882ac0e7d0a6c738;p=network.git networkd: Add scaffolding to connect to dbus Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index abba6465..60a1bcde 100644 --- a/Makefile.am +++ b/Makefile.am @@ -304,6 +304,8 @@ sbin_PROGRAMS += \ networkd dist_networkd_SOURCES = \ + src/networkd/bus.c \ + src/networkd/bus.h \ src/networkd/daemon.c \ src/networkd/daemon.h \ src/networkd/logging.h \ diff --git a/src/networkd/bus.c b/src/networkd/bus.c new file mode 100644 index 00000000..95862d2d --- /dev/null +++ b/src/networkd/bus.c @@ -0,0 +1,131 @@ +/*############################################################################# +# # +# 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 + +#include +#include + +#include "bus.h" +#include "daemon.h" +#include "logging.h" + +static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* ret_error) { + return 1; +} + +static const sd_bus_vtable daemon_vtable[] = { + SD_BUS_VTABLE_START(0), + SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT, + nw_bus_daemon_reload, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_VTABLE_END, +}; + +int nw_bus_connect(sd_bus* bus, sd_event* loop) { + int r; + + // Create a bus object + r = sd_bus_new(&bus); + if (r < 0) { + ERROR("Could not allocate a bus object: %s\n", strerror(-r)); + return 1; + } + + // Set description + r = sd_bus_set_description(bus, NETWORKD_BUS_DESCRIPTION); + if (r < 0) { + ERROR("Could not set bus description: %s\n", strerror(-r)); + return 1; + } + + const char* address = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS"); + if (!address) + address = DEFAULT_SYSTEM_BUS_ADDRESS; + + // Set bus address + r = sd_bus_set_address(bus, address); + if (r < 0) { + ERROR("Could not set bus address: %s\n", strerror(-r)); + return 1; + } + + // Set bus client + r = sd_bus_set_bus_client(bus, 1); + if (r < 0) { + ERROR("Could not set bus client: %s\n", strerror(-r)); + return 1; + } + + // Request some credentials for all messages + r = sd_bus_negotiate_creds(bus, 1, + SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS); + if (r < 0) { + ERROR("Could not negotiate creds: %s\n", strerror(-r)); + return 1; + } + + // Automatically bind when the socket is available + r = sd_bus_set_watch_bind(bus, 1); + if (r < 0) { + ERROR("Could not watch socket: %s\n", strerror(-r)); + return 1; + } + + // Emit a connected signal when we are connected + r = sd_bus_set_connected_signal(bus, 1); + if (r < 0) { + ERROR("Could not enable sending a connect signal: %s\n", strerror(-r)); + return 1; + } + + // Connect to the bus + r = sd_bus_start(bus); + if (r < 0) { + ERROR("Could not connect to bus: %s\n", strerror(-r)); + return 1; + } + + // Register any functions + r = sd_bus_add_object_vtable(bus, NULL, + NETWORKD_BUS_OBJECT_PATH, NETWORKD_BUS_INTERFACE_NAME, daemon_vtable, NULL); + if (r < 0) { + ERROR("Could not add object vtable: %s\n", strerror(-r)); + return 1; + } + + // Request interface name + // XXX Should this be async? + // XXX How do we get the actual error message from dbus? + r = sd_bus_request_name(bus, NETWORKD_BUS_INTERFACE_NAME, 0); + if (r < 0) { + ERROR("Could not request bus name: %s\n", strerror(-r)); + return 1; + } + + // Attach the event loop + r = sd_bus_attach_event(bus, loop, 0); + if (r < 0) { + ERROR("Could not attach bus to event loop: %s\n", strerror(-r)); + return 1; + } + + return 0; +} diff --git a/src/networkd/bus.h b/src/networkd/bus.h new file mode 100644 index 00000000..90c1556c --- /dev/null +++ b/src/networkd/bus.h @@ -0,0 +1,35 @@ +/*############################################################################# +# # +# 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_BUS_H +#define NETWORKD_BUS_H + +#define NETWORKD_BUS_DESCRIPTION "networkd" +#define NETWORKD_BUS_OBJECT_PATH "/org/ipfire/network1" +#define NETWORKD_BUS_INTERFACE_NAME "org.ipfire.network1" + +#define DEFAULT_SYSTEM_BUS_ADDRESS "unix:path=/run/dbus/system_bus_socket" + +#include +#include + +int nw_bus_connect(sd_bus* bus, sd_event* loop); + +#endif /* NETWORKD_BUS_H */ diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c index 98fb5bd5..3aee8caf 100644 --- a/src/networkd/daemon.c +++ b/src/networkd/daemon.c @@ -22,8 +22,10 @@ #include #include +#include #include +#include "bus.h" #include "daemon.h" #include "logging.h" @@ -32,6 +34,9 @@ struct nw_daemon { // Event Loop sd_event* loop; + + // DBus Connection + sd_bus* bus; }; static int __nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si, @@ -105,6 +110,11 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { if (r) return r; + // Connect to the system bus + r = nw_bus_connect(daemon->bus, daemon->loop); + if (r) + return r; + return 0; } @@ -135,6 +145,8 @@ ERROR: } static void nw_daemon_free(struct nw_daemon* daemon) { + if (daemon->bus) + sd_bus_unref(daemon->bus); if (daemon->loop) sd_event_unref(daemon->loop);