1 /*#############################################################################
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2023 IPFire Network Development Team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
23 #include <systemd/sd-bus.h>
24 #include <systemd/sd-event.h>
28 #include "daemon-bus.h"
31 static int nw_bus_on_connect(sd_bus_message
* m
, void* data
, sd_bus_error
* error
) {
32 struct nw_daemon
* daemon
= (struct nw_daemon
*)data
;
34 DEBUG("Connected to D-Bus\n");
39 int nw_bus_connect(sd_bus
* bus
, sd_event
* loop
, struct nw_daemon
* daemon
) {
42 // Create a bus object
45 ERROR("Could not allocate a bus object: %s\n", strerror(-r
));
50 r
= sd_bus_set_description(bus
, NETWORKD_BUS_DESCRIPTION
);
52 ERROR("Could not set bus description: %s\n", strerror(-r
));
56 const char* address
= secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
58 address
= DEFAULT_SYSTEM_BUS_ADDRESS
;
61 r
= sd_bus_set_address(bus
, address
);
63 ERROR("Could not set bus address: %s\n", strerror(-r
));
68 r
= sd_bus_set_bus_client(bus
, 1);
70 ERROR("Could not set bus client: %s\n", strerror(-r
));
74 // Request some credentials for all messages
75 r
= sd_bus_negotiate_creds(bus
, 1,
76 SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_EFFECTIVE_CAPS
);
78 ERROR("Could not negotiate creds: %s\n", strerror(-r
));
82 // Automatically bind when the socket is available
83 r
= sd_bus_set_watch_bind(bus
, 1);
85 ERROR("Could not watch socket: %s\n", strerror(-r
));
89 // Emit a connected signal when we are connected
90 r
= sd_bus_set_connected_signal(bus
, 1);
92 ERROR("Could not enable sending a connect signal: %s\n", strerror(-r
));
97 r
= sd_bus_start(bus
);
99 ERROR("Could not connect to bus: %s\n", strerror(-r
));
103 // Register the implementation
104 r
= nw_bus_register_implementation(bus
, &daemon_bus_impl
, daemon
);
108 // Request interface name
109 r
= sd_bus_request_name_async(bus
, NULL
, "org.ipfire.network1", 0, NULL
, NULL
);
111 ERROR("Could not request bus name: %s\n", strerror(-r
));
115 // Attach the event loop
116 r
= sd_bus_attach_event(bus
, loop
, 0);
118 ERROR("Could not attach bus to event loop: %s\n", strerror(-r
));
122 // Request receiving a connect signal
123 r
= sd_bus_match_signal_async(bus
, NULL
, "org.freedesktop.DBus.Local",
124 NULL
, "org.freedesktop.DBus.Local", "Connected", nw_bus_on_connect
, NULL
, NULL
);
126 ERROR("Could not request match on Connected signal: %s\n", strerror(-r
));
133 int nw_bus_register_implementation(sd_bus
* bus
,
134 const struct nw_bus_implementation
* impl
, void* data
) {
137 DEBUG("Registering bus object implementation for path=%s iface=%s\n",
138 impl
->path
, impl
->interface
);
141 for (const sd_bus_vtable
** vtable
= impl
->vtables
; vtable
&& *vtable
; vtable
++) {
142 r
= sd_bus_add_object_vtable(bus
, NULL
, impl
->path
, impl
->interface
, *vtable
, data
);
144 ERROR("Could not register bus path %s with interface %s: %m\n",
145 impl
->path
, impl
->interface
);
150 // Register fallback vtables
151 for (const struct nw_bus_vtable_pair
* p
= impl
->fallback_vtables
; p
&& p
->vtable
; p
++) {
152 r
= sd_bus_add_fallback_vtable(bus
, NULL
, impl
->path
, impl
->interface
,
153 p
->vtable
, p
->object_find
, data
);
155 ERROR("Could not register bus path %s with interface %s: %m\n",
156 impl
->path
, impl
->interface
);
161 // Register the node enumerator
162 if (impl
->node_enumerator
) {
163 r
= sd_bus_add_node_enumerator(bus
, NULL
, impl
->path
, impl
->node_enumerator
, data
);
165 ERROR("Could not add the node enumerator for %s: %m\n", impl
->path
);
170 // Register any child implementations
171 for (int i
= 0; impl
->children
&& impl
->children
[i
]; i
++) {
172 r
= nw_bus_register_implementation(bus
, impl
->children
[i
], data
);