]> git.ipfire.org Git - people/ms/network.git/blob - src/networkd/bus.c
networkd: Add scaffolding to connect to dbus
[people/ms/network.git] / src / networkd / bus.c
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>
22 #include <string.h>
23
24 #include <systemd/sd-bus.h>
25 #include <systemd/sd-event.h>
26
27 #include "bus.h"
28 #include "daemon.h"
29 #include "logging.h"
30
31 static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* ret_error) {
32 return 1;
33 }
34
35 static const sd_bus_vtable daemon_vtable[] = {
36 SD_BUS_VTABLE_START(0),
37 SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT,
38 nw_bus_daemon_reload, SD_BUS_VTABLE_UNPRIVILEGED),
39 SD_BUS_VTABLE_END,
40 };
41
42 int nw_bus_connect(sd_bus* bus, sd_event* loop) {
43 int r;
44
45 // Create a bus object
46 r = sd_bus_new(&bus);
47 if (r < 0) {
48 ERROR("Could not allocate a bus object: %s\n", strerror(-r));
49 return 1;
50 }
51
52 // Set description
53 r = sd_bus_set_description(bus, NETWORKD_BUS_DESCRIPTION);
54 if (r < 0) {
55 ERROR("Could not set bus description: %s\n", strerror(-r));
56 return 1;
57 }
58
59 const char* address = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
60 if (!address)
61 address = DEFAULT_SYSTEM_BUS_ADDRESS;
62
63 // Set bus address
64 r = sd_bus_set_address(bus, address);
65 if (r < 0) {
66 ERROR("Could not set bus address: %s\n", strerror(-r));
67 return 1;
68 }
69
70 // Set bus client
71 r = sd_bus_set_bus_client(bus, 1);
72 if (r < 0) {
73 ERROR("Could not set bus client: %s\n", strerror(-r));
74 return 1;
75 }
76
77 // Request some credentials for all messages
78 r = sd_bus_negotiate_creds(bus, 1,
79 SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS);
80 if (r < 0) {
81 ERROR("Could not negotiate creds: %s\n", strerror(-r));
82 return 1;
83 }
84
85 // Automatically bind when the socket is available
86 r = sd_bus_set_watch_bind(bus, 1);
87 if (r < 0) {
88 ERROR("Could not watch socket: %s\n", strerror(-r));
89 return 1;
90 }
91
92 // Emit a connected signal when we are connected
93 r = sd_bus_set_connected_signal(bus, 1);
94 if (r < 0) {
95 ERROR("Could not enable sending a connect signal: %s\n", strerror(-r));
96 return 1;
97 }
98
99 // Connect to the bus
100 r = sd_bus_start(bus);
101 if (r < 0) {
102 ERROR("Could not connect to bus: %s\n", strerror(-r));
103 return 1;
104 }
105
106 // Register any functions
107 r = sd_bus_add_object_vtable(bus, NULL,
108 NETWORKD_BUS_OBJECT_PATH, NETWORKD_BUS_INTERFACE_NAME, daemon_vtable, NULL);
109 if (r < 0) {
110 ERROR("Could not add object vtable: %s\n", strerror(-r));
111 return 1;
112 }
113
114 // Request interface name
115 // XXX Should this be async?
116 // XXX How do we get the actual error message from dbus?
117 r = sd_bus_request_name(bus, NETWORKD_BUS_INTERFACE_NAME, 0);
118 if (r < 0) {
119 ERROR("Could not request bus name: %s\n", strerror(-r));
120 return 1;
121 }
122
123 // Attach the event loop
124 r = sd_bus_attach_event(bus, loop, 0);
125 if (r < 0) {
126 ERROR("Could not attach bus to event loop: %s\n", strerror(-r));
127 return 1;
128 }
129
130 return 0;
131 }