]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager-bus.c
pid1: make sure we send our calling service manager RELOADING=1 when reloading
[thirdparty/systemd.git] / src / network / networkd-manager-bus.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
e331e246 2
071712b2 3#include <net/if.h>
f39dbf28 4#include <netinet/in.h>
7f06b3e1 5#include <sys/capability.h>
071712b2 6
b5efdb8a 7#include "alloc-util.h"
071712b2 8#include "bus-common-errors.h"
7695e2cb 9#include "bus-message-util.h"
269e4d2d 10#include "bus-polkit.h"
6e194652 11#include "networkd-dhcp-server-bus.h"
54a16efe 12#include "networkd-json.h"
7f3c07ad 13#include "networkd-link-bus.h"
37d577c8 14#include "networkd-link.h"
79a59fa5 15#include "networkd-manager-bus.h"
23f53b99 16#include "networkd-manager.h"
6e194652 17#include "networkd-network-bus.h"
37d577c8 18#include "path-util.h"
51517f9e 19#include "strv.h"
7f06b3e1 20#include "user-util.h"
e331e246 21
37d577c8
YW
22static int method_list_links(sd_bus_message *message, void *userdata, sd_bus_error *error) {
23 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
24 Manager *manager = userdata;
37d577c8
YW
25 Link *link;
26 int r;
27
28 r = sd_bus_message_new_method_return(message, &reply);
29 if (r < 0)
30 return r;
31
32 r = sd_bus_message_open_container(reply, 'a', "(iso)");
33 if (r < 0)
34 return r;
35
6eab614d 36 HASHMAP_FOREACH(link, manager->links_by_index) {
37d577c8
YW
37 _cleanup_free_ char *path = NULL;
38
39 path = link_bus_path(link);
40 if (!path)
41 return -ENOMEM;
42
43 r = sd_bus_message_append(
44 reply, "(iso)",
45 link->ifindex,
46 link->ifname,
47 empty_to_root(path));
48 if (r < 0)
49 return r;
50 }
51
52 r = sd_bus_message_close_container(reply);
53 if (r < 0)
54 return r;
55
56 return sd_bus_send(NULL, reply, NULL);
57}
58
071712b2
YW
59static int method_get_link_by_name(sd_bus_message *message, void *userdata, sd_bus_error *error) {
60 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
61 _cleanup_free_ char *path = NULL;
62 Manager *manager = userdata;
63 const char *name;
071712b2 64 Link *link;
f0ad7aed 65 int r;
071712b2
YW
66
67 r = sd_bus_message_read(message, "s", &name);
68 if (r < 0)
69 return r;
70
f0ad7aed 71 if (link_get_by_name(manager, name, &link) < 0)
071712b2
YW
72 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %s not known", name);
73
74 r = sd_bus_message_new_method_return(message, &reply);
75 if (r < 0)
76 return r;
77
78 path = link_bus_path(link);
79 if (!path)
80 return -ENOMEM;
81
82 r = sd_bus_message_append(reply, "io", link->ifindex, empty_to_root(path));
83 if (r < 0)
84 return r;
85
86 return sd_bus_send(NULL, reply, NULL);
87}
88
89static int method_get_link_by_index(sd_bus_message *message, void *userdata, sd_bus_error *error) {
90 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
91 _cleanup_free_ char *path = NULL;
92 Manager *manager = userdata;
7695e2cb 93 int ifindex, r;
071712b2 94 Link *link;
071712b2 95
7695e2cb 96 r = bus_message_read_ifindex(message, error, &ifindex);
071712b2
YW
97 if (r < 0)
98 return r;
99
6eab614d
YW
100 r = link_get_by_index(manager, ifindex, &link);
101 if (r < 0)
7695e2cb 102 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %i not known", ifindex);
071712b2
YW
103
104 r = sd_bus_message_new_method_return(message, &reply);
105 if (r < 0)
106 return r;
107
108 path = link_bus_path(link);
109 if (!path)
110 return -ENOMEM;
111
112 r = sd_bus_message_append(reply, "so", link->ifname, empty_to_root(path));
113 if (r < 0)
114 return r;
115
116 return sd_bus_send(NULL, reply, NULL);
117}
118
15761549
YW
119static int call_link_method(Manager *m, sd_bus_message *message, sd_bus_message_handler_t handler, sd_bus_error *error) {
120 int ifindex, r;
121 Link *l;
122
123 assert(m);
124 assert(message);
125 assert(handler);
126
7695e2cb 127 r = bus_message_read_ifindex(message, error, &ifindex);
15761549
YW
128 if (r < 0)
129 return r;
130
6eab614d
YW
131 r = link_get_by_index(m, ifindex, &l);
132 if (r < 0)
15761549
YW
133 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %i not known", ifindex);
134
135 return handler(message, l, error);
136}
137
138static int bus_method_set_link_ntp_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) {
139 return call_link_method(userdata, message, bus_link_method_set_ntp_servers, error);
140}
141
142static int bus_method_set_link_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) {
143 return call_link_method(userdata, message, bus_link_method_set_dns_servers, error);
144}
145
4e11ddfd
YW
146static int bus_method_set_link_dns_servers_ex(sd_bus_message *message, void *userdata, sd_bus_error *error) {
147 return call_link_method(userdata, message, bus_link_method_set_dns_servers_ex, error);
148}
149
15761549
YW
150static int bus_method_set_link_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
151 return call_link_method(userdata, message, bus_link_method_set_domains, error);
152}
153
154static int bus_method_set_link_default_route(sd_bus_message *message, void *userdata, sd_bus_error *error) {
155 return call_link_method(userdata, message, bus_link_method_set_default_route, error);
156}
157
158static int bus_method_set_link_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error) {
159 return call_link_method(userdata, message, bus_link_method_set_llmnr, error);
160}
161
162static int bus_method_set_link_mdns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
163 return call_link_method(userdata, message, bus_link_method_set_mdns, error);
164}
165
166static int bus_method_set_link_dns_over_tls(sd_bus_message *message, void *userdata, sd_bus_error *error) {
167 return call_link_method(userdata, message, bus_link_method_set_dns_over_tls, error);
168}
169
170static int bus_method_set_link_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
171 return call_link_method(userdata, message, bus_link_method_set_dnssec, error);
172}
173
174static int bus_method_set_link_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
175 return call_link_method(userdata, message, bus_link_method_set_dnssec_negative_trust_anchors, error);
176}
177
178static int bus_method_revert_link_ntp(sd_bus_message *message, void *userdata, sd_bus_error *error) {
179 return call_link_method(userdata, message, bus_link_method_revert_ntp, error);
180}
181
182static int bus_method_revert_link_dns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
183 return call_link_method(userdata, message, bus_link_method_revert_dns, error);
184}
185
ae65d7db
YW
186static int bus_method_renew_link(sd_bus_message *message, void *userdata, sd_bus_error *error) {
187 return call_link_method(userdata, message, bus_link_method_renew, error);
188}
189
90867f6a
SS
190static int bus_method_force_renew_link(sd_bus_message *message, void *userdata, sd_bus_error *error) {
191 return call_link_method(userdata, message, bus_link_method_force_renew, error);
192}
193
99b8517c
YW
194static int bus_method_reconfigure_link(sd_bus_message *message, void *userdata, sd_bus_error *error) {
195 return call_link_method(userdata, message, bus_link_method_reconfigure, error);
196}
197
7f06b3e1
YW
198static int bus_method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
199 Manager *manager = userdata;
7f06b3e1
YW
200 Link *link;
201 int r;
202
203 r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
204 "org.freedesktop.network1.reload",
205 NULL, true, UID_INVALID,
206 &manager->polkit_registry, error);
207 if (r < 0)
208 return r;
209 if (r == 0)
210 return 1; /* Polkit will call us back */
211
e272b621
YW
212 r = netdev_load(manager, true);
213 if (r < 0)
214 return r;
215
7f06b3e1
YW
216 r = network_reload(manager);
217 if (r < 0)
218 return r;
219
6eab614d 220 HASHMAP_FOREACH(link, manager->links_by_index) {
7f80fa12 221 r = link_reconfigure(link, /* force = */ false);
7f06b3e1
YW
222 if (r < 0)
223 return r;
224 }
225
226 return sd_bus_reply_method_return(message, NULL);
227}
228
54a16efe
YW
229static int bus_method_describe_link(sd_bus_message *message, void *userdata, sd_bus_error *error) {
230 return call_link_method(userdata, message, bus_link_method_describe, error);
231}
232
233static int bus_method_describe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
234 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
235 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
236 _cleanup_free_ char *text = NULL;
99534007 237 Manager *manager = ASSERT_PTR(userdata);
54a16efe
YW
238 int r;
239
240 assert(message);
54a16efe
YW
241
242 r = manager_build_json(manager, &v);
243 if (r < 0)
244 return log_error_errno(r, "Failed to build JSON data: %m");
245
246 r = json_variant_format(v, 0, &text);
247 if (r < 0)
248 return log_error_errno(r, "Failed to format JSON data: %m");
249
250 r = sd_bus_message_new_method_return(message, &reply);
251 if (r < 0)
252 return r;
253
254 r = sd_bus_message_append(reply, "s", text);
255 if (r < 0)
256 return r;
257
258 return sd_bus_send(NULL, reply, NULL);
259}
260
f2ef8b28
LP
261static int property_get_namespace_id(
262 sd_bus *bus,
263 const char *path,
264 const char *interface,
265 const char *property,
266 sd_bus_message *reply,
267 void *userdata,
268 sd_bus_error *error) {
269
270 uint64_t id = 0;
271 struct stat st;
272
273 assert(bus);
274 assert(reply);
275
276 /* Returns our own network namespace ID, i.e. the inode number of /proc/self/ns/net. This allows
277 * unprivileged clients to determine whether they are in the same network namespace as us (note that
278 * access to that path is restricted, thus they can't check directly unless privileged). */
279
280 if (stat("/proc/self/ns/net", &st) < 0) {
281 log_warning_errno(errno, "Failed to stat network namespace, ignoring: %m");
282 id = 0;
283 } else
284 id = st.st_ino;
285
286 return sd_bus_message_append(reply, "t", id);
287}
288
6e194652 289static const sd_bus_vtable manager_vtable[] = {
e331e246
TG
290 SD_BUS_VTABLE_START(0),
291
292 SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Manager, operational_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
7f3c07ad
YW
293 SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Manager, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
294 SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Manager, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
8430841b
L
295 SD_BUS_PROPERTY("IPv4AddressState", "s", property_get_address_state, offsetof(Manager, ipv4_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
296 SD_BUS_PROPERTY("IPv6AddressState", "s", property_get_address_state, offsetof(Manager, ipv6_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
bcdcc596 297 SD_BUS_PROPERTY("OnlineState", "s", property_get_online_state, offsetof(Manager, online_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
f2ef8b28 298 SD_BUS_PROPERTY("NamespaceId", "t", property_get_namespace_id, 0, SD_BUS_VTABLE_PROPERTY_CONST),
e331e246 299
23c32ff8
YW
300 SD_BUS_METHOD_WITH_ARGS("ListLinks",
301 SD_BUS_NO_ARGS,
302 SD_BUS_RESULT("a(iso)", links),
303 method_list_links,
304 SD_BUS_VTABLE_UNPRIVILEGED),
305 SD_BUS_METHOD_WITH_ARGS("GetLinkByName",
306 SD_BUS_ARGS("s", name),
307 SD_BUS_RESULT("i", ifindex, "o", path),
308 method_get_link_by_name,
309 SD_BUS_VTABLE_UNPRIVILEGED),
310 SD_BUS_METHOD_WITH_ARGS("GetLinkByIndex",
311 SD_BUS_ARGS("i", ifindex),
312 SD_BUS_RESULT("s", name, "o", path),
313 method_get_link_by_index,
314 SD_BUS_VTABLE_UNPRIVILEGED),
315 SD_BUS_METHOD_WITH_ARGS("SetLinkNTP",
316 SD_BUS_ARGS("i", ifindex, "as", servers),
317 SD_BUS_NO_RESULT,
318 bus_method_set_link_ntp_servers,
319 SD_BUS_VTABLE_UNPRIVILEGED),
320 SD_BUS_METHOD_WITH_ARGS("SetLinkDNS",
321 SD_BUS_ARGS("i", ifindex, "a(iay)", addresses),
322 SD_BUS_NO_RESULT,
323 bus_method_set_link_dns_servers,
324 SD_BUS_VTABLE_UNPRIVILEGED),
325 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSEx",
326 SD_BUS_ARGS("i", ifindex, "a(iayqs)", addresses),
327 SD_BUS_NO_RESULT,
328 bus_method_set_link_dns_servers_ex,
329 SD_BUS_VTABLE_UNPRIVILEGED),
330 SD_BUS_METHOD_WITH_ARGS("SetLinkDomains",
331 SD_BUS_ARGS("i", ifindex, "a(sb)", domains),
332 SD_BUS_NO_RESULT,
333 bus_method_set_link_domains,
334 SD_BUS_VTABLE_UNPRIVILEGED),
335 SD_BUS_METHOD_WITH_ARGS("SetLinkDefaultRoute",
336 SD_BUS_ARGS("i", ifindex, "b", enable),
337 SD_BUS_NO_RESULT,
338 bus_method_set_link_default_route,
339 SD_BUS_VTABLE_UNPRIVILEGED),
340 SD_BUS_METHOD_WITH_ARGS("SetLinkLLMNR",
341 SD_BUS_ARGS("i", ifindex, "s", mode),
342 SD_BUS_NO_RESULT,
343 bus_method_set_link_llmnr,
344 SD_BUS_VTABLE_UNPRIVILEGED),
345 SD_BUS_METHOD_WITH_ARGS("SetLinkMulticastDNS",
346 SD_BUS_ARGS("i", ifindex, "s", mode),
347 SD_BUS_NO_RESULT,
348 bus_method_set_link_mdns,
349 SD_BUS_VTABLE_UNPRIVILEGED),
350 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSOverTLS",
351 SD_BUS_ARGS("i", ifindex, "s", mode),
352 SD_BUS_NO_RESULT,
353 bus_method_set_link_dns_over_tls,
354 SD_BUS_VTABLE_UNPRIVILEGED),
355 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSEC",
356 SD_BUS_ARGS("i", ifindex, "s", mode),
357 SD_BUS_NO_RESULT,
358 bus_method_set_link_dnssec,
359 SD_BUS_VTABLE_UNPRIVILEGED),
360 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSECNegativeTrustAnchors",
361 SD_BUS_ARGS("i", ifindex, "as", names),
362 SD_BUS_NO_RESULT,
363 bus_method_set_link_dnssec_negative_trust_anchors,
364 SD_BUS_VTABLE_UNPRIVILEGED),
365 SD_BUS_METHOD_WITH_ARGS("RevertLinkNTP",
366 SD_BUS_ARGS("i", ifindex),
367 SD_BUS_NO_RESULT,
368 bus_method_revert_link_ntp,
369 SD_BUS_VTABLE_UNPRIVILEGED),
370 SD_BUS_METHOD_WITH_ARGS("RevertLinkDNS",
371 SD_BUS_ARGS("i", ifindex),
372 SD_BUS_NO_RESULT,
373 bus_method_revert_link_dns,
374 SD_BUS_VTABLE_UNPRIVILEGED),
375 SD_BUS_METHOD_WITH_ARGS("RenewLink",
376 SD_BUS_ARGS("i", ifindex),
377 SD_BUS_NO_RESULT,
378 bus_method_renew_link,
379 SD_BUS_VTABLE_UNPRIVILEGED),
380 SD_BUS_METHOD_WITH_ARGS("ForceRenewLink",
381 SD_BUS_ARGS("i", ifindex),
382 SD_BUS_NO_RESULT,
383 bus_method_force_renew_link,
384 SD_BUS_VTABLE_UNPRIVILEGED),
385 SD_BUS_METHOD_WITH_ARGS("ReconfigureLink",
386 SD_BUS_ARGS("i", ifindex),
387 SD_BUS_NO_RESULT,
388 bus_method_reconfigure_link,
389 SD_BUS_VTABLE_UNPRIVILEGED),
390 SD_BUS_METHOD_WITH_ARGS("Reload",
391 SD_BUS_NO_ARGS,
392 SD_BUS_NO_RESULT,
393 bus_method_reload,
394 SD_BUS_VTABLE_UNPRIVILEGED),
54a16efe
YW
395 SD_BUS_METHOD_WITH_ARGS("DescribeLink",
396 SD_BUS_ARGS("i", ifindex),
397 SD_BUS_RESULT("s", json),
398 bus_method_describe_link,
399 SD_BUS_VTABLE_UNPRIVILEGED),
400 SD_BUS_METHOD_WITH_ARGS("Describe",
401 SD_BUS_NO_ARGS,
402 SD_BUS_RESULT("s", json),
403 bus_method_describe,
404 SD_BUS_VTABLE_UNPRIVILEGED),
37d577c8 405
e331e246
TG
406 SD_BUS_VTABLE_END
407};
408
46606fdd 409int manager_send_changed_strv(Manager *manager, char **properties) {
e331e246 410 assert(manager);
46606fdd 411 assert(properties);
e331e246 412
5dbec9bd 413 if (sd_bus_is_ready(manager->bus) <= 0)
46606fdd 414 return 0;
e331e246
TG
415
416 return sd_bus_emit_properties_changed_strv(
417 manager->bus,
418 "/org/freedesktop/network1",
419 "org.freedesktop.network1.Manager",
46606fdd
YW
420 properties);
421}
6e194652
YW
422
423const BusObjectImplementation manager_object = {
424 "/org/freedesktop/network1",
425 "org.freedesktop.network1.Manager",
426 .vtables = BUS_VTABLES(manager_vtable),
427 .children = BUS_IMPLEMENTATIONS(&dhcp_server_object, &link_object, &network_object),
428};