]> git.ipfire.org Git - network.git/blame - src/networkd/bus.c
networkd: Split daemon bus implementation into a separate file
[network.git] / src / networkd / bus.c
CommitLineData
09a6af17
MT
1/*#############################################################################
2# #
3# IPFire.org - A linux based firewall #
4# Copyright (C) 2023 IPFire Network Development Team #
5# #
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. #
10# #
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. #
15# #
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/>. #
18# #
19#############################################################################*/
20
21#include <stdlib.h>
09a6af17
MT
22
23#include <systemd/sd-bus.h>
24#include <systemd/sd-event.h>
25
26#include "bus.h"
27#include "daemon.h"
d6edaf63 28#include "daemon-bus.h"
09a6af17 29#include "logging.h"
9806a600 30
bf42846c
MT
31static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) {
32 struct nw_daemon* daemon = (struct nw_daemon*)data;
33
34 DEBUG("Connected to D-Bus\n");
35
36 return 0;
37}
38
eaeca0f9 39int nw_bus_connect(sd_bus* bus, sd_event* loop, struct nw_daemon* daemon) {
09a6af17
MT
40 int r;
41
42 // Create a bus object
43 r = sd_bus_new(&bus);
44 if (r < 0) {
45 ERROR("Could not allocate a bus object: %s\n", strerror(-r));
46 return 1;
47 }
48
49 // Set description
50 r = sd_bus_set_description(bus, NETWORKD_BUS_DESCRIPTION);
51 if (r < 0) {
52 ERROR("Could not set bus description: %s\n", strerror(-r));
53 return 1;
54 }
55
56 const char* address = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
57 if (!address)
58 address = DEFAULT_SYSTEM_BUS_ADDRESS;
59
60 // Set bus address
61 r = sd_bus_set_address(bus, address);
62 if (r < 0) {
63 ERROR("Could not set bus address: %s\n", strerror(-r));
64 return 1;
65 }
66
67 // Set bus client
68 r = sd_bus_set_bus_client(bus, 1);
69 if (r < 0) {
70 ERROR("Could not set bus client: %s\n", strerror(-r));
71 return 1;
72 }
73
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);
77 if (r < 0) {
78 ERROR("Could not negotiate creds: %s\n", strerror(-r));
79 return 1;
80 }
81
82 // Automatically bind when the socket is available
83 r = sd_bus_set_watch_bind(bus, 1);
84 if (r < 0) {
85 ERROR("Could not watch socket: %s\n", strerror(-r));
86 return 1;
87 }
88
89 // Emit a connected signal when we are connected
90 r = sd_bus_set_connected_signal(bus, 1);
91 if (r < 0) {
92 ERROR("Could not enable sending a connect signal: %s\n", strerror(-r));
93 return 1;
94 }
95
96 // Connect to the bus
97 r = sd_bus_start(bus);
98 if (r < 0) {
99 ERROR("Could not connect to bus: %s\n", strerror(-r));
100 return 1;
101 }
102
9806a600 103 // Register the implementation
d6edaf63 104 r = nw_bus_register_implementation(bus, &daemon_bus_impl, daemon);
9806a600
MT
105 if (r)
106 return r;
09a6af17
MT
107
108 // Request interface name
9806a600 109 r = sd_bus_request_name_async(bus, NULL, "org.ipfire.network1", 0, NULL, NULL);
09a6af17
MT
110 if (r < 0) {
111 ERROR("Could not request bus name: %s\n", strerror(-r));
112 return 1;
113 }
114
115 // Attach the event loop
116 r = sd_bus_attach_event(bus, loop, 0);
117 if (r < 0) {
118 ERROR("Could not attach bus to event loop: %s\n", strerror(-r));
119 return 1;
120 }
121
bf42846c
MT
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);
125 if (r < 0) {
126 ERROR("Could not request match on Connected signal: %s\n", strerror(-r));
127 return 1;
128 }
129
09a6af17
MT
130 return 0;
131}
9806a600
MT
132
133int nw_bus_register_implementation(sd_bus* bus,
134 const struct nw_bus_implementation* impl, void* data) {
135 int r;
136
137 DEBUG("Registering bus object implementation for path=%s iface=%s\n",
138 impl->path, impl->interface);
139
bd9ffd6a 140 // Register vtables
9806a600
MT
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);
143 if (r < 0) {
144 ERROR("Could not register bus path %s with interface %s: %m\n",
145 impl->path, impl->interface);
146 return 1;
147 }
148 }
149
bd9ffd6a
MT
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);
154 if (r < 0) {
155 ERROR("Could not register bus path %s with interface %s: %m\n",
156 impl->path, impl->interface);
157 return 1;
158 }
159 }
160
ebc65f19
MT
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);
164 if (r < 0) {
165 ERROR("Could not add the node enumerator for %s: %m\n", impl->path);
166 return 1;
167 }
168 }
169
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);
173 if (r)
174 return r;
175 }
176
9806a600
MT
177 return 0;
178}