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-json.h"
12 #include "networkd-link-bus.h"
13 #include "networkd-link.h"
14 #include "networkd-manager-bus.h"
15 #include "networkd-manager.h"
16 #include "path-util.h"
17 #include "socket-netlink.h"
19 #include "user-util.h"
21 static int method_list_links(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
22 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
23 Manager
*manager
= userdata
;
27 r
= sd_bus_message_new_method_return(message
, &reply
);
31 r
= sd_bus_message_open_container(reply
, 'a', "(iso)");
35 HASHMAP_FOREACH(link
, manager
->links
) {
36 _cleanup_free_
char *path
= NULL
;
38 path
= link_bus_path(link
);
42 r
= sd_bus_message_append(
51 r
= sd_bus_message_close_container(reply
);
55 return sd_bus_send(NULL
, reply
, NULL
);
58 static int method_get_link_by_name(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
59 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
60 _cleanup_free_
char *path
= NULL
;
61 Manager
*manager
= userdata
;
66 r
= sd_bus_message_read(message
, "s", &name
);
70 index
= resolve_ifname(&manager
->rtnl
, name
);
72 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_LINK
, "Link %s cannot be resolved", name
);
74 link
= hashmap_get(manager
->links
, INT_TO_PTR(index
));
76 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_LINK
, "Link %s not known", name
);
78 r
= sd_bus_message_new_method_return(message
, &reply
);
82 path
= link_bus_path(link
);
86 r
= sd_bus_message_append(reply
, "io", link
->ifindex
, empty_to_root(path
));
90 return sd_bus_send(NULL
, reply
, NULL
);
93 static int method_get_link_by_index(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
94 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
95 _cleanup_free_
char *path
= NULL
;
96 Manager
*manager
= userdata
;
100 r
= bus_message_read_ifindex(message
, error
, &ifindex
);
104 link
= hashmap_get(manager
->links
, INT_TO_PTR(ifindex
));
106 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_LINK
, "Link %i not known", ifindex
);
108 r
= sd_bus_message_new_method_return(message
, &reply
);
112 path
= link_bus_path(link
);
116 r
= sd_bus_message_append(reply
, "so", link
->ifname
, empty_to_root(path
));
120 return sd_bus_send(NULL
, reply
, NULL
);
123 static int call_link_method(Manager
*m
, sd_bus_message
*message
, sd_bus_message_handler_t handler
, sd_bus_error
*error
) {
131 r
= bus_message_read_ifindex(message
, error
, &ifindex
);
135 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
137 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_LINK
, "Link %i not known", ifindex
);
139 return handler(message
, l
, error
);
142 static int bus_method_set_link_ntp_servers(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
143 return call_link_method(userdata
, message
, bus_link_method_set_ntp_servers
, error
);
146 static int bus_method_set_link_dns_servers(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
147 return call_link_method(userdata
, message
, bus_link_method_set_dns_servers
, error
);
150 static int bus_method_set_link_dns_servers_ex(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
151 return call_link_method(userdata
, message
, bus_link_method_set_dns_servers_ex
, error
);
154 static int bus_method_set_link_domains(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
155 return call_link_method(userdata
, message
, bus_link_method_set_domains
, error
);
158 static int bus_method_set_link_default_route(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
159 return call_link_method(userdata
, message
, bus_link_method_set_default_route
, error
);
162 static int bus_method_set_link_llmnr(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
163 return call_link_method(userdata
, message
, bus_link_method_set_llmnr
, error
);
166 static int bus_method_set_link_mdns(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
167 return call_link_method(userdata
, message
, bus_link_method_set_mdns
, error
);
170 static int bus_method_set_link_dns_over_tls(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
171 return call_link_method(userdata
, message
, bus_link_method_set_dns_over_tls
, error
);
174 static int bus_method_set_link_dnssec(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
175 return call_link_method(userdata
, message
, bus_link_method_set_dnssec
, error
);
178 static int bus_method_set_link_dnssec_negative_trust_anchors(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
179 return call_link_method(userdata
, message
, bus_link_method_set_dnssec_negative_trust_anchors
, error
);
182 static int bus_method_revert_link_ntp(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
183 return call_link_method(userdata
, message
, bus_link_method_revert_ntp
, error
);
186 static int bus_method_revert_link_dns(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
187 return call_link_method(userdata
, message
, bus_link_method_revert_dns
, error
);
190 static int bus_method_renew_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
191 return call_link_method(userdata
, message
, bus_link_method_renew
, error
);
194 static int bus_method_force_renew_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
195 return call_link_method(userdata
, message
, bus_link_method_force_renew
, error
);
198 static int bus_method_reconfigure_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
199 return call_link_method(userdata
, message
, bus_link_method_reconfigure
, error
);
202 static int bus_method_reload(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
203 Manager
*manager
= userdata
;
207 r
= bus_verify_polkit_async(message
, CAP_NET_ADMIN
,
208 "org.freedesktop.network1.reload",
209 NULL
, true, UID_INVALID
,
210 &manager
->polkit_registry
, error
);
214 return 1; /* Polkit will call us back */
216 r
= netdev_load(manager
, true);
220 r
= network_reload(manager
);
224 HASHMAP_FOREACH(link
, manager
->links
) {
225 r
= link_reconfigure(link
, false);
230 return sd_bus_reply_method_return(message
, NULL
);
233 static int bus_method_describe_link(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
234 return call_link_method(userdata
, message
, bus_link_method_describe
, error
);
237 static int bus_method_describe(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
238 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
239 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
240 _cleanup_free_
char *text
= NULL
;
241 Manager
*manager
= userdata
;
247 r
= manager_build_json(manager
, &v
);
249 return log_error_errno(r
, "Failed to build JSON data: %m");
251 r
= json_variant_format(v
, 0, &text
);
253 return log_error_errno(r
, "Failed to format JSON data: %m");
255 r
= sd_bus_message_new_method_return(message
, &reply
);
259 r
= sd_bus_message_append(reply
, "s", text
);
263 return sd_bus_send(NULL
, reply
, NULL
);
266 const sd_bus_vtable manager_vtable
[] = {
267 SD_BUS_VTABLE_START(0),
269 SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state
, offsetof(Manager
, operational_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
270 SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state
, offsetof(Manager
, carrier_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
271 SD_BUS_PROPERTY("AddressState", "s", property_get_address_state
, offsetof(Manager
, address_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
272 SD_BUS_PROPERTY("IPv4AddressState", "s", property_get_address_state
, offsetof(Manager
, ipv4_address_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
273 SD_BUS_PROPERTY("IPv6AddressState", "s", property_get_address_state
, offsetof(Manager
, ipv6_address_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
274 SD_BUS_PROPERTY("OnlineState", "s", property_get_online_state
, offsetof(Manager
, online_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
276 SD_BUS_METHOD_WITH_ARGS("ListLinks",
278 SD_BUS_RESULT("a(iso)", links
),
280 SD_BUS_VTABLE_UNPRIVILEGED
),
281 SD_BUS_METHOD_WITH_ARGS("GetLinkByName",
282 SD_BUS_ARGS("s", name
),
283 SD_BUS_RESULT("i", ifindex
, "o", path
),
284 method_get_link_by_name
,
285 SD_BUS_VTABLE_UNPRIVILEGED
),
286 SD_BUS_METHOD_WITH_ARGS("GetLinkByIndex",
287 SD_BUS_ARGS("i", ifindex
),
288 SD_BUS_RESULT("s", name
, "o", path
),
289 method_get_link_by_index
,
290 SD_BUS_VTABLE_UNPRIVILEGED
),
291 SD_BUS_METHOD_WITH_ARGS("SetLinkNTP",
292 SD_BUS_ARGS("i", ifindex
, "as", servers
),
294 bus_method_set_link_ntp_servers
,
295 SD_BUS_VTABLE_UNPRIVILEGED
),
296 SD_BUS_METHOD_WITH_ARGS("SetLinkDNS",
297 SD_BUS_ARGS("i", ifindex
, "a(iay)", addresses
),
299 bus_method_set_link_dns_servers
,
300 SD_BUS_VTABLE_UNPRIVILEGED
),
301 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSEx",
302 SD_BUS_ARGS("i", ifindex
, "a(iayqs)", addresses
),
304 bus_method_set_link_dns_servers_ex
,
305 SD_BUS_VTABLE_UNPRIVILEGED
),
306 SD_BUS_METHOD_WITH_ARGS("SetLinkDomains",
307 SD_BUS_ARGS("i", ifindex
, "a(sb)", domains
),
309 bus_method_set_link_domains
,
310 SD_BUS_VTABLE_UNPRIVILEGED
),
311 SD_BUS_METHOD_WITH_ARGS("SetLinkDefaultRoute",
312 SD_BUS_ARGS("i", ifindex
, "b", enable
),
314 bus_method_set_link_default_route
,
315 SD_BUS_VTABLE_UNPRIVILEGED
),
316 SD_BUS_METHOD_WITH_ARGS("SetLinkLLMNR",
317 SD_BUS_ARGS("i", ifindex
, "s", mode
),
319 bus_method_set_link_llmnr
,
320 SD_BUS_VTABLE_UNPRIVILEGED
),
321 SD_BUS_METHOD_WITH_ARGS("SetLinkMulticastDNS",
322 SD_BUS_ARGS("i", ifindex
, "s", mode
),
324 bus_method_set_link_mdns
,
325 SD_BUS_VTABLE_UNPRIVILEGED
),
326 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSOverTLS",
327 SD_BUS_ARGS("i", ifindex
, "s", mode
),
329 bus_method_set_link_dns_over_tls
,
330 SD_BUS_VTABLE_UNPRIVILEGED
),
331 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSEC",
332 SD_BUS_ARGS("i", ifindex
, "s", mode
),
334 bus_method_set_link_dnssec
,
335 SD_BUS_VTABLE_UNPRIVILEGED
),
336 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSECNegativeTrustAnchors",
337 SD_BUS_ARGS("i", ifindex
, "as", names
),
339 bus_method_set_link_dnssec_negative_trust_anchors
,
340 SD_BUS_VTABLE_UNPRIVILEGED
),
341 SD_BUS_METHOD_WITH_ARGS("RevertLinkNTP",
342 SD_BUS_ARGS("i", ifindex
),
344 bus_method_revert_link_ntp
,
345 SD_BUS_VTABLE_UNPRIVILEGED
),
346 SD_BUS_METHOD_WITH_ARGS("RevertLinkDNS",
347 SD_BUS_ARGS("i", ifindex
),
349 bus_method_revert_link_dns
,
350 SD_BUS_VTABLE_UNPRIVILEGED
),
351 SD_BUS_METHOD_WITH_ARGS("RenewLink",
352 SD_BUS_ARGS("i", ifindex
),
354 bus_method_renew_link
,
355 SD_BUS_VTABLE_UNPRIVILEGED
),
356 SD_BUS_METHOD_WITH_ARGS("ForceRenewLink",
357 SD_BUS_ARGS("i", ifindex
),
359 bus_method_force_renew_link
,
360 SD_BUS_VTABLE_UNPRIVILEGED
),
361 SD_BUS_METHOD_WITH_ARGS("ReconfigureLink",
362 SD_BUS_ARGS("i", ifindex
),
364 bus_method_reconfigure_link
,
365 SD_BUS_VTABLE_UNPRIVILEGED
),
366 SD_BUS_METHOD_WITH_ARGS("Reload",
370 SD_BUS_VTABLE_UNPRIVILEGED
),
371 SD_BUS_METHOD_WITH_ARGS("DescribeLink",
372 SD_BUS_ARGS("i", ifindex
),
373 SD_BUS_RESULT("s", json
),
374 bus_method_describe_link
,
375 SD_BUS_VTABLE_UNPRIVILEGED
),
376 SD_BUS_METHOD_WITH_ARGS("Describe",
378 SD_BUS_RESULT("s", json
),
380 SD_BUS_VTABLE_UNPRIVILEGED
),
385 int manager_send_changed_strv(Manager
*manager
, char **properties
) {
389 if (sd_bus_is_ready(manager
->bus
) <= 0)
392 return sd_bus_emit_properties_changed_strv(
394 "/org/freedesktop/network1",
395 "org.freedesktop.network1.Manager",