1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <netinet/in.h>
5 #include <sys/capability.h>
7 #include "alloc-util.h"
8 #include "bus-common-errors.h"
9 #include "bus-message-util.h"
10 #include "bus-polkit.h"
11 #include "networkd-dhcp-server-bus.h"
12 #include "networkd-dhcp4-bus.h"
13 #include "networkd-dhcp6-bus.h"
14 #include "networkd-json.h"
15 #include "networkd-link-bus.h"
16 #include "networkd-link.h"
17 #include "networkd-manager-bus.h"
18 #include "networkd-manager.h"
19 #include "networkd-network-bus.h"
20 #include "path-util.h"
22 #include "user-util.h"
24 static int method_list_links(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
25 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
26 Manager
*manager
= userdata
;
30 r
= sd_bus_message_new_method_return(message
, &reply
);
34 r
= sd_bus_message_open_container(reply
, 'a', "(iso)");
38 HASHMAP_FOREACH(link
, manager
->links_by_index
) {
39 _cleanup_free_
char *path
= NULL
;
41 path
= link_bus_path(link
);
45 r
= sd_bus_message_append(
54 r
= sd_bus_message_close_container(reply
);
58 return sd_bus_send(NULL
, reply
, NULL
);
61 static int method_get_link_by_name(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
62 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
63 _cleanup_free_
char *path
= NULL
;
64 Manager
*manager
= userdata
;
69 r
= sd_bus_message_read(message
, "s", &name
);
73 if (link_get_by_name(manager
, name
, &link
) < 0)
74 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_LINK
, "Link %s not known", name
);
76 r
= sd_bus_message_new_method_return(message
, &reply
);
80 path
= link_bus_path(link
);
84 r
= sd_bus_message_append(reply
, "io", link
->ifindex
, empty_to_root(path
));
88 return sd_bus_send(NULL
, reply
, NULL
);
91 static int method_get_link_by_index(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
92 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
93 _cleanup_free_
char *path
= NULL
;
94 Manager
*manager
= userdata
;
98 r
= bus_message_read_ifindex(message
, error
, &ifindex
);
102 r
= link_get_by_index(manager
, ifindex
, &link
);
104 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_LINK
, "Link %i not known", ifindex
);
106 r
= sd_bus_message_new_method_return(message
, &reply
);
110 path
= link_bus_path(link
);
114 r
= sd_bus_message_append(reply
, "so", link
->ifname
, empty_to_root(path
));
118 return sd_bus_send(NULL
, reply
, NULL
);
121 static int call_link_method(Manager
*m
, sd_bus_message
*message
, sd_bus_message_handler_t handler
, sd_bus_error
*error
) {
129 r
= bus_message_read_ifindex(message
, error
, &ifindex
);
133 r
= link_get_by_index(m
, ifindex
, &l
);
135 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_LINK
, "Link %i not known", ifindex
);
137 return handler(message
, l
, error
);
140 static int bus_method_set_link_ntp_servers(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
141 return call_link_method(userdata
, message
, bus_link_method_set_ntp_servers
, error
);
144 static int bus_method_set_link_dns_servers(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
145 return call_link_method(userdata
, message
, bus_link_method_set_dns_servers
, error
);
148 static int bus_method_set_link_dns_servers_ex(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
149 return call_link_method(userdata
, message
, bus_link_method_set_dns_servers_ex
, error
);
152 static int bus_method_set_link_domains(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
153 return call_link_method(userdata
, message
, bus_link_method_set_domains
, error
);
156 static int bus_method_set_link_default_route(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
157 return call_link_method(userdata
, message
, bus_link_method_set_default_route
, error
);
160 static int bus_method_set_link_llmnr(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
161 return call_link_method(userdata
, message
, bus_link_method_set_llmnr
, error
);
164 static int bus_method_set_link_mdns(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
165 return call_link_method(userdata
, message
, bus_link_method_set_mdns
, error
);
168 static int bus_method_set_link_dns_over_tls(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
169 return call_link_method(userdata
, message
, bus_link_method_set_dns_over_tls
, error
);
172 static int bus_method_set_link_dnssec(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
173 return call_link_method(userdata
, message
, bus_link_method_set_dnssec
, error
);
176 static int bus_method_set_link_dnssec_negative_trust_anchors(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
177 return call_link_method(userdata
, message
, bus_link_method_set_dnssec_negative_trust_anchors
, error
);
180 static int bus_method_revert_link_ntp(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
181 return call_link_method(userdata
, message
, bus_link_method_revert_ntp
, error
);
184 static int bus_method_revert_link_dns(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
185 return call_link_method(userdata
, message
, bus_link_method_revert_dns
, error
);
188 static int bus_method_renew_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
189 return call_link_method(userdata
, message
, bus_link_method_renew
, error
);
192 static int bus_method_force_renew_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
193 return call_link_method(userdata
, message
, bus_link_method_force_renew
, error
);
196 static int bus_method_reconfigure_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
197 return call_link_method(userdata
, message
, bus_link_method_reconfigure
, error
);
200 static int bus_method_reload(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
201 Manager
*manager
= ASSERT_PTR(userdata
);
204 if (manager
->reloading
> 0)
205 return sd_bus_error_set(error
, BUS_ERROR_NETWORK_ALREADY_RELOADING
, "Already reloading.");
207 r
= bus_verify_polkit_async(
209 "org.freedesktop.network1.reload",
211 &manager
->polkit_registry
,
216 return 1; /* Polkit will call us back */
218 r
= manager_reload(manager
, message
);
222 if (manager
->reloading
> 0)
223 return 1; /* Will reply later. */
225 return sd_bus_reply_method_return(message
, NULL
);
228 static int bus_method_describe_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
229 return call_link_method(userdata
, message
, bus_link_method_describe
, error
);
232 static int bus_method_describe(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
233 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
234 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
235 _cleanup_free_
char *text
= NULL
;
236 Manager
*manager
= ASSERT_PTR(userdata
);
241 r
= manager_build_json(manager
, &v
);
243 return log_error_errno(r
, "Failed to build JSON data: %m");
245 r
= json_variant_format(v
, 0, &text
);
247 return log_error_errno(r
, "Failed to format JSON data: %m");
249 r
= sd_bus_message_new_method_return(message
, &reply
);
253 r
= sd_bus_message_append(reply
, "s", text
);
257 return sd_bus_send(NULL
, reply
, NULL
);
260 static int property_get_namespace_id(
263 const char *interface
,
264 const char *property
,
265 sd_bus_message
*reply
,
267 sd_bus_error
*error
) {
275 /* Returns our own network namespace ID, i.e. the inode number of /proc/self/ns/net. This allows
276 * unprivileged clients to determine whether they are in the same network namespace as us (note that
277 * access to that path is restricted, thus they can't check directly unless privileged). */
279 if (stat("/proc/self/ns/net", &st
) < 0) {
280 log_warning_errno(errno
, "Failed to stat network namespace, ignoring: %m");
285 return sd_bus_message_append(reply
, "t", id
);
288 static int property_get_namespace_nsid(
291 const char *interface
,
292 const char *property
,
293 sd_bus_message
*reply
,
295 sd_bus_error
*error
) {
297 uint32_t nsid
= UINT32_MAX
;
303 /* Returns our own "nsid", which is another ID for the network namespace, different from the inode
306 r
= netns_get_nsid(/* netnsfd= */ -EBADF
, &nsid
);
308 log_warning_errno(r
, "Failed to query network nsid, ignoring: %m");
310 return sd_bus_message_append(reply
, "u", nsid
);
313 static const sd_bus_vtable manager_vtable
[] = {
314 SD_BUS_VTABLE_START(0),
316 SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state
, offsetof(Manager
, operational_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
317 SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state
, offsetof(Manager
, carrier_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
318 SD_BUS_PROPERTY("AddressState", "s", property_get_address_state
, offsetof(Manager
, address_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
319 SD_BUS_PROPERTY("IPv4AddressState", "s", property_get_address_state
, offsetof(Manager
, ipv4_address_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
320 SD_BUS_PROPERTY("IPv6AddressState", "s", property_get_address_state
, offsetof(Manager
, ipv6_address_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
321 SD_BUS_PROPERTY("OnlineState", "s", property_get_online_state
, offsetof(Manager
, online_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
322 SD_BUS_PROPERTY("NamespaceId", "t", property_get_namespace_id
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
323 SD_BUS_PROPERTY("NamespaceNSID", "u", property_get_namespace_nsid
, 0, 0),
325 SD_BUS_METHOD_WITH_ARGS("ListLinks",
327 SD_BUS_RESULT("a(iso)", links
),
329 SD_BUS_VTABLE_UNPRIVILEGED
),
330 SD_BUS_METHOD_WITH_ARGS("GetLinkByName",
331 SD_BUS_ARGS("s", name
),
332 SD_BUS_RESULT("i", ifindex
, "o", path
),
333 method_get_link_by_name
,
334 SD_BUS_VTABLE_UNPRIVILEGED
),
335 SD_BUS_METHOD_WITH_ARGS("GetLinkByIndex",
336 SD_BUS_ARGS("i", ifindex
),
337 SD_BUS_RESULT("s", name
, "o", path
),
338 method_get_link_by_index
,
339 SD_BUS_VTABLE_UNPRIVILEGED
),
340 SD_BUS_METHOD_WITH_ARGS("SetLinkNTP",
341 SD_BUS_ARGS("i", ifindex
, "as", servers
),
343 bus_method_set_link_ntp_servers
,
344 SD_BUS_VTABLE_UNPRIVILEGED
),
345 SD_BUS_METHOD_WITH_ARGS("SetLinkDNS",
346 SD_BUS_ARGS("i", ifindex
, "a(iay)", addresses
),
348 bus_method_set_link_dns_servers
,
349 SD_BUS_VTABLE_UNPRIVILEGED
),
350 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSEx",
351 SD_BUS_ARGS("i", ifindex
, "a(iayqs)", addresses
),
353 bus_method_set_link_dns_servers_ex
,
354 SD_BUS_VTABLE_UNPRIVILEGED
),
355 SD_BUS_METHOD_WITH_ARGS("SetLinkDomains",
356 SD_BUS_ARGS("i", ifindex
, "a(sb)", domains
),
358 bus_method_set_link_domains
,
359 SD_BUS_VTABLE_UNPRIVILEGED
),
360 SD_BUS_METHOD_WITH_ARGS("SetLinkDefaultRoute",
361 SD_BUS_ARGS("i", ifindex
, "b", enable
),
363 bus_method_set_link_default_route
,
364 SD_BUS_VTABLE_UNPRIVILEGED
),
365 SD_BUS_METHOD_WITH_ARGS("SetLinkLLMNR",
366 SD_BUS_ARGS("i", ifindex
, "s", mode
),
368 bus_method_set_link_llmnr
,
369 SD_BUS_VTABLE_UNPRIVILEGED
),
370 SD_BUS_METHOD_WITH_ARGS("SetLinkMulticastDNS",
371 SD_BUS_ARGS("i", ifindex
, "s", mode
),
373 bus_method_set_link_mdns
,
374 SD_BUS_VTABLE_UNPRIVILEGED
),
375 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSOverTLS",
376 SD_BUS_ARGS("i", ifindex
, "s", mode
),
378 bus_method_set_link_dns_over_tls
,
379 SD_BUS_VTABLE_UNPRIVILEGED
),
380 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSEC",
381 SD_BUS_ARGS("i", ifindex
, "s", mode
),
383 bus_method_set_link_dnssec
,
384 SD_BUS_VTABLE_UNPRIVILEGED
),
385 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSECNegativeTrustAnchors",
386 SD_BUS_ARGS("i", ifindex
, "as", names
),
388 bus_method_set_link_dnssec_negative_trust_anchors
,
389 SD_BUS_VTABLE_UNPRIVILEGED
),
390 SD_BUS_METHOD_WITH_ARGS("RevertLinkNTP",
391 SD_BUS_ARGS("i", ifindex
),
393 bus_method_revert_link_ntp
,
394 SD_BUS_VTABLE_UNPRIVILEGED
),
395 SD_BUS_METHOD_WITH_ARGS("RevertLinkDNS",
396 SD_BUS_ARGS("i", ifindex
),
398 bus_method_revert_link_dns
,
399 SD_BUS_VTABLE_UNPRIVILEGED
),
400 SD_BUS_METHOD_WITH_ARGS("RenewLink",
401 SD_BUS_ARGS("i", ifindex
),
403 bus_method_renew_link
,
404 SD_BUS_VTABLE_UNPRIVILEGED
),
405 SD_BUS_METHOD_WITH_ARGS("ForceRenewLink",
406 SD_BUS_ARGS("i", ifindex
),
408 bus_method_force_renew_link
,
409 SD_BUS_VTABLE_UNPRIVILEGED
),
410 SD_BUS_METHOD_WITH_ARGS("ReconfigureLink",
411 SD_BUS_ARGS("i", ifindex
),
413 bus_method_reconfigure_link
,
414 SD_BUS_VTABLE_UNPRIVILEGED
),
415 SD_BUS_METHOD_WITH_ARGS("Reload",
419 SD_BUS_VTABLE_UNPRIVILEGED
),
420 SD_BUS_METHOD_WITH_ARGS("DescribeLink",
421 SD_BUS_ARGS("i", ifindex
),
422 SD_BUS_RESULT("s", json
),
423 bus_method_describe_link
,
424 SD_BUS_VTABLE_UNPRIVILEGED
),
425 SD_BUS_METHOD_WITH_ARGS("Describe",
427 SD_BUS_RESULT("s", json
),
429 SD_BUS_VTABLE_UNPRIVILEGED
),
434 int manager_send_changed_strv(Manager
*manager
, char **properties
) {
438 if (sd_bus_is_ready(manager
->bus
) <= 0)
441 return sd_bus_emit_properties_changed_strv(
443 "/org/freedesktop/network1",
444 "org.freedesktop.network1.Manager",
448 const BusObjectImplementation manager_object
= {
449 "/org/freedesktop/network1",
450 "org.freedesktop.network1.Manager",
451 .vtables
= BUS_VTABLES(manager_vtable
),
452 .children
= BUS_IMPLEMENTATIONS(
453 &link_object
, /* This is the main implementation for /org/freedesktop/network1/link,
454 * and must be earlier than the dhcp objects below. */
457 &dhcp6_client_object
,