Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <net/if.h>
4 : :
5 : : #include "alloc-util.h"
6 : : #include "bus-common-errors.h"
7 : : #include "bus-util.h"
8 : : #include "parse-util.h"
9 : : #include "resolve-util.h"
10 : : #include "resolved-bus.h"
11 : : #include "resolved-link-bus.h"
12 : : #include "resolved-resolv-conf.h"
13 : : #include "strv.h"
14 : :
15 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET(property_get_dnssec_supported, "b", Link, link_dnssec_supported);
# # ]
16 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET2(property_get_dnssec_mode, "s", Link, link_get_dnssec_mode, dnssec_mode_to_string);
# # ]
17 : :
18 : 0 : static int property_get_dns_over_tls_mode(
19 : : sd_bus *bus,
20 : : const char *path,
21 : : const char *interface,
22 : : const char *property,
23 : : sd_bus_message *reply,
24 : : void *userdata,
25 : : sd_bus_error *error) {
26 : :
27 : 0 : Link *l = userdata;
28 : :
29 [ # # ]: 0 : assert(reply);
30 [ # # ]: 0 : assert(l);
31 : :
32 : 0 : return sd_bus_message_append(reply, "s", dns_over_tls_mode_to_string(link_get_dns_over_tls_mode(l)));
33 : : }
34 : :
35 : 0 : static int property_get_dns(
36 : : sd_bus *bus,
37 : : const char *path,
38 : : const char *interface,
39 : : const char *property,
40 : : sd_bus_message *reply,
41 : : void *userdata,
42 : : sd_bus_error *error) {
43 : :
44 : 0 : Link *l = userdata;
45 : : DnsServer *s;
46 : : int r;
47 : :
48 [ # # ]: 0 : assert(reply);
49 [ # # ]: 0 : assert(l);
50 : :
51 : 0 : r = sd_bus_message_open_container(reply, 'a', "(iay)");
52 [ # # ]: 0 : if (r < 0)
53 : 0 : return r;
54 : :
55 [ # # ]: 0 : LIST_FOREACH(servers, s, l->dns_servers) {
56 : 0 : r = bus_dns_server_append(reply, s, false);
57 [ # # ]: 0 : if (r < 0)
58 : 0 : return r;
59 : : }
60 : :
61 : 0 : return sd_bus_message_close_container(reply);
62 : : }
63 : :
64 : 0 : static int property_get_current_dns_server(
65 : : sd_bus *bus,
66 : : const char *path,
67 : : const char *interface,
68 : : const char *property,
69 : : sd_bus_message *reply,
70 : : void *userdata,
71 : : sd_bus_error *error) {
72 : :
73 : : DnsServer *s;
74 : :
75 [ # # ]: 0 : assert(reply);
76 [ # # ]: 0 : assert(userdata);
77 : :
78 : 0 : s = *(DnsServer **) userdata;
79 : :
80 : 0 : return bus_dns_server_append(reply, s, false);
81 : : }
82 : :
83 : 0 : static int property_get_domains(
84 : : sd_bus *bus,
85 : : const char *path,
86 : : const char *interface,
87 : : const char *property,
88 : : sd_bus_message *reply,
89 : : void *userdata,
90 : : sd_bus_error *error) {
91 : :
92 : 0 : Link *l = userdata;
93 : : DnsSearchDomain *d;
94 : : int r;
95 : :
96 [ # # ]: 0 : assert(reply);
97 [ # # ]: 0 : assert(l);
98 : :
99 : 0 : r = sd_bus_message_open_container(reply, 'a', "(sb)");
100 [ # # ]: 0 : if (r < 0)
101 : 0 : return r;
102 : :
103 [ # # ]: 0 : LIST_FOREACH(domains, d, l->search_domains) {
104 : 0 : r = sd_bus_message_append(reply, "(sb)", d->name, d->route_only);
105 [ # # ]: 0 : if (r < 0)
106 : 0 : return r;
107 : : }
108 : :
109 : 0 : return sd_bus_message_close_container(reply);
110 : : }
111 : :
112 : 0 : static int property_get_default_route(
113 : : sd_bus *bus,
114 : : const char *path,
115 : : const char *interface,
116 : : const char *property,
117 : : sd_bus_message *reply,
118 : : void *userdata,
119 : : sd_bus_error *error) {
120 : :
121 : 0 : Link *l = userdata;
122 : :
123 [ # # ]: 0 : assert(reply);
124 [ # # ]: 0 : assert(l);
125 : :
126 : : /* Return what is configured, if there's something configured */
127 [ # # ]: 0 : if (l->default_route >= 0)
128 : 0 : return sd_bus_message_append(reply, "b", l->default_route);
129 : :
130 : : /* Otherwise report what is in effect */
131 [ # # ]: 0 : if (l->unicast_scope)
132 : 0 : return sd_bus_message_append(reply, "b", dns_scope_is_default_route(l->unicast_scope));
133 : :
134 : 0 : return sd_bus_message_append(reply, "b", false);
135 : : }
136 : :
137 : 0 : static int property_get_scopes_mask(
138 : : sd_bus *bus,
139 : : const char *path,
140 : : const char *interface,
141 : : const char *property,
142 : : sd_bus_message *reply,
143 : : void *userdata,
144 : : sd_bus_error *error) {
145 : :
146 : 0 : Link *l = userdata;
147 : : uint64_t mask;
148 : :
149 [ # # ]: 0 : assert(reply);
150 [ # # ]: 0 : assert(l);
151 : :
152 [ # # ]: 0 : mask = (l->unicast_scope ? SD_RESOLVED_DNS : 0) |
153 [ # # ]: 0 : (l->llmnr_ipv4_scope ? SD_RESOLVED_LLMNR_IPV4 : 0) |
154 [ # # ]: 0 : (l->llmnr_ipv6_scope ? SD_RESOLVED_LLMNR_IPV6 : 0) |
155 [ # # ]: 0 : (l->mdns_ipv4_scope ? SD_RESOLVED_MDNS_IPV4 : 0) |
156 [ # # ]: 0 : (l->mdns_ipv6_scope ? SD_RESOLVED_MDNS_IPV6 : 0);
157 : :
158 : 0 : return sd_bus_message_append(reply, "t", mask);
159 : : }
160 : :
161 : 0 : static int property_get_ntas(
162 : : sd_bus *bus,
163 : : const char *path,
164 : : const char *interface,
165 : : const char *property,
166 : : sd_bus_message *reply,
167 : : void *userdata,
168 : : sd_bus_error *error) {
169 : :
170 : 0 : Link *l = userdata;
171 : : const char *name;
172 : : Iterator i;
173 : : int r;
174 : :
175 [ # # ]: 0 : assert(reply);
176 [ # # ]: 0 : assert(l);
177 : :
178 : 0 : r = sd_bus_message_open_container(reply, 'a', "s");
179 [ # # ]: 0 : if (r < 0)
180 : 0 : return r;
181 : :
182 [ # # ]: 0 : SET_FOREACH(name, l->dnssec_negative_trust_anchors, i) {
183 : 0 : r = sd_bus_message_append(reply, "s", name);
184 [ # # ]: 0 : if (r < 0)
185 : 0 : return r;
186 : : }
187 : :
188 : 0 : return sd_bus_message_close_container(reply);
189 : : }
190 : :
191 : 0 : static int verify_unmanaged_link(Link *l, sd_bus_error *error) {
192 [ # # ]: 0 : assert(l);
193 : :
194 [ # # ]: 0 : if (l->flags & IFF_LOOPBACK)
195 : 0 : return sd_bus_error_setf(error, BUS_ERROR_LINK_BUSY, "Link %s is loopback device.", l->ifname);
196 [ # # ]: 0 : if (l->is_managed)
197 : 0 : return sd_bus_error_setf(error, BUS_ERROR_LINK_BUSY, "Link %s is managed.", l->ifname);
198 : :
199 : 0 : return 0;
200 : : }
201 : :
202 : 0 : int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) {
203 : 0 : _cleanup_free_ struct in_addr_data *dns = NULL;
204 : 0 : size_t allocated = 0, n = 0;
205 : 0 : Link *l = userdata;
206 : : unsigned i;
207 : : int r;
208 : :
209 [ # # ]: 0 : assert(message);
210 [ # # ]: 0 : assert(l);
211 : :
212 : 0 : r = verify_unmanaged_link(l, error);
213 [ # # ]: 0 : if (r < 0)
214 : 0 : return r;
215 : :
216 : 0 : r = sd_bus_message_enter_container(message, 'a', "(iay)");
217 [ # # ]: 0 : if (r < 0)
218 : 0 : return r;
219 : :
220 : 0 : for (;;) {
221 : : int family;
222 : : size_t sz;
223 : : const void *d;
224 : :
225 : : assert_cc(sizeof(int) == sizeof(int32_t));
226 : :
227 : 0 : r = sd_bus_message_enter_container(message, 'r', "iay");
228 [ # # ]: 0 : if (r < 0)
229 : 0 : return r;
230 [ # # ]: 0 : if (r == 0)
231 : 0 : break;
232 : :
233 : 0 : r = sd_bus_message_read(message, "i", &family);
234 [ # # ]: 0 : if (r < 0)
235 : 0 : return r;
236 : :
237 [ # # # # ]: 0 : if (!IN_SET(family, AF_INET, AF_INET6))
238 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
239 : :
240 : 0 : r = sd_bus_message_read_array(message, 'y', &d, &sz);
241 [ # # ]: 0 : if (r < 0)
242 : 0 : return r;
243 [ # # ]: 0 : if (sz != FAMILY_ADDRESS_SIZE(family))
244 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
245 : :
246 [ # # ]: 0 : if (!dns_server_address_valid(family, d))
247 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNS server address");
248 : :
249 : 0 : r = sd_bus_message_exit_container(message);
250 [ # # ]: 0 : if (r < 0)
251 : 0 : return r;
252 : :
253 [ # # ]: 0 : if (!GREEDY_REALLOC(dns, allocated, n+1))
254 : 0 : return -ENOMEM;
255 : :
256 : 0 : dns[n].family = family;
257 : 0 : memcpy(&dns[n].address, d, sz);
258 : 0 : n++;
259 : : }
260 : :
261 : 0 : r = sd_bus_message_exit_container(message);
262 [ # # ]: 0 : if (r < 0)
263 : 0 : return r;
264 : :
265 : 0 : dns_server_mark_all(l->dns_servers);
266 : :
267 [ # # ]: 0 : for (i = 0; i < n; i++) {
268 : : DnsServer *s;
269 : :
270 : 0 : s = dns_server_find(l->dns_servers, dns[i].family, &dns[i].address, 0);
271 [ # # ]: 0 : if (s)
272 : 0 : dns_server_move_back_and_unmark(s);
273 : : else {
274 : 0 : r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, dns[i].family, &dns[i].address, 0);
275 [ # # ]: 0 : if (r < 0)
276 : 0 : goto clear;
277 : : }
278 : :
279 : : }
280 : :
281 : 0 : dns_server_unlink_marked(l->dns_servers);
282 : 0 : link_allocate_scopes(l);
283 : :
284 : 0 : (void) link_save_user(l);
285 : 0 : (void) manager_write_resolv_conf(l->manager);
286 : :
287 : 0 : return sd_bus_reply_method_return(message, NULL);
288 : :
289 : 0 : clear:
290 : 0 : dns_server_unlink_all(l->dns_servers);
291 : 0 : return r;
292 : : }
293 : :
294 : 0 : int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
295 : 0 : Link *l = userdata;
296 : : int r;
297 : :
298 [ # # ]: 0 : assert(message);
299 [ # # ]: 0 : assert(l);
300 : :
301 : 0 : r = verify_unmanaged_link(l, error);
302 [ # # ]: 0 : if (r < 0)
303 : 0 : return r;
304 : :
305 : 0 : r = sd_bus_message_enter_container(message, 'a', "(sb)");
306 [ # # ]: 0 : if (r < 0)
307 : 0 : return r;
308 : :
309 : 0 : for (;;) {
310 : : const char *name;
311 : : int route_only;
312 : :
313 : 0 : r = sd_bus_message_read(message, "(sb)", &name, &route_only);
314 [ # # ]: 0 : if (r < 0)
315 : 0 : return r;
316 [ # # ]: 0 : if (r == 0)
317 : 0 : break;
318 : :
319 : 0 : r = dns_name_is_valid(name);
320 [ # # ]: 0 : if (r < 0)
321 : 0 : return r;
322 [ # # ]: 0 : if (r == 0)
323 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid search domain %s", name);
324 [ # # # # ]: 0 : if (!route_only && dns_name_is_root(name))
325 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root domain is not suitable as search domain");
326 : : }
327 : :
328 : 0 : dns_search_domain_mark_all(l->search_domains);
329 : :
330 : 0 : r = sd_bus_message_rewind(message, false);
331 [ # # ]: 0 : if (r < 0)
332 : 0 : return r;
333 : :
334 : 0 : for (;;) {
335 : : DnsSearchDomain *d;
336 : : const char *name;
337 : : int route_only;
338 : :
339 : 0 : r = sd_bus_message_read(message, "(sb)", &name, &route_only);
340 [ # # ]: 0 : if (r < 0)
341 : 0 : goto clear;
342 [ # # ]: 0 : if (r == 0)
343 : 0 : break;
344 : :
345 : 0 : r = dns_search_domain_find(l->search_domains, name, &d);
346 [ # # ]: 0 : if (r < 0)
347 : 0 : goto clear;
348 : :
349 [ # # ]: 0 : if (r > 0)
350 : 0 : dns_search_domain_move_back_and_unmark(d);
351 : : else {
352 : 0 : r = dns_search_domain_new(l->manager, &d, DNS_SEARCH_DOMAIN_LINK, l, name);
353 [ # # ]: 0 : if (r < 0)
354 : 0 : goto clear;
355 : : }
356 : :
357 : 0 : d->route_only = route_only;
358 : : }
359 : :
360 : 0 : r = sd_bus_message_exit_container(message);
361 [ # # ]: 0 : if (r < 0)
362 : 0 : goto clear;
363 : :
364 : 0 : dns_search_domain_unlink_marked(l->search_domains);
365 : :
366 : 0 : (void) link_save_user(l);
367 : 0 : (void) manager_write_resolv_conf(l->manager);
368 : :
369 : 0 : return sd_bus_reply_method_return(message, NULL);
370 : :
371 : 0 : clear:
372 : 0 : dns_search_domain_unlink_all(l->search_domains);
373 : 0 : return r;
374 : : }
375 : :
376 : 0 : int bus_link_method_set_default_route(sd_bus_message *message, void *userdata, sd_bus_error *error) {
377 : 0 : Link *l = userdata;
378 : : int r, b;
379 : :
380 [ # # ]: 0 : assert(message);
381 [ # # ]: 0 : assert(l);
382 : :
383 : 0 : r = verify_unmanaged_link(l, error);
384 [ # # ]: 0 : if (r < 0)
385 : 0 : return r;
386 : :
387 : 0 : r = sd_bus_message_read(message, "b", &b);
388 [ # # ]: 0 : if (r < 0)
389 : 0 : return r;
390 : :
391 [ # # ]: 0 : if (l->default_route != b) {
392 : 0 : l->default_route = b;
393 : :
394 : 0 : (void) link_save_user(l);
395 : 0 : (void) manager_write_resolv_conf(l->manager);
396 : : }
397 : :
398 : 0 : return sd_bus_reply_method_return(message, NULL);
399 : : }
400 : :
401 : 0 : int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error) {
402 : 0 : Link *l = userdata;
403 : : ResolveSupport mode;
404 : : const char *llmnr;
405 : : int r;
406 : :
407 [ # # ]: 0 : assert(message);
408 [ # # ]: 0 : assert(l);
409 : :
410 : 0 : r = verify_unmanaged_link(l, error);
411 [ # # ]: 0 : if (r < 0)
412 : 0 : return r;
413 : :
414 : 0 : r = sd_bus_message_read(message, "s", &llmnr);
415 [ # # ]: 0 : if (r < 0)
416 : 0 : return r;
417 : :
418 [ # # ]: 0 : if (isempty(llmnr))
419 : 0 : mode = RESOLVE_SUPPORT_YES;
420 : : else {
421 : 0 : mode = resolve_support_from_string(llmnr);
422 [ # # ]: 0 : if (mode < 0)
423 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid LLMNR setting: %s", llmnr);
424 : : }
425 : :
426 : 0 : l->llmnr_support = mode;
427 : 0 : link_allocate_scopes(l);
428 : 0 : link_add_rrs(l, false);
429 : :
430 : 0 : (void) link_save_user(l);
431 : :
432 : 0 : return sd_bus_reply_method_return(message, NULL);
433 : : }
434 : :
435 : 0 : int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
436 : 0 : Link *l = userdata;
437 : : ResolveSupport mode;
438 : : const char *mdns;
439 : : int r;
440 : :
441 [ # # ]: 0 : assert(message);
442 [ # # ]: 0 : assert(l);
443 : :
444 : 0 : r = verify_unmanaged_link(l, error);
445 [ # # ]: 0 : if (r < 0)
446 : 0 : return r;
447 : :
448 : 0 : r = sd_bus_message_read(message, "s", &mdns);
449 [ # # ]: 0 : if (r < 0)
450 : 0 : return r;
451 : :
452 [ # # ]: 0 : if (isempty(mdns))
453 : 0 : mode = RESOLVE_SUPPORT_NO;
454 : : else {
455 : 0 : mode = resolve_support_from_string(mdns);
456 [ # # ]: 0 : if (mode < 0)
457 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid MulticastDNS setting: %s", mdns);
458 : : }
459 : :
460 : 0 : l->mdns_support = mode;
461 : 0 : link_allocate_scopes(l);
462 : 0 : link_add_rrs(l, false);
463 : :
464 : 0 : (void) link_save_user(l);
465 : :
466 : 0 : return sd_bus_reply_method_return(message, NULL);
467 : : }
468 : :
469 : 0 : int bus_link_method_set_dns_over_tls(sd_bus_message *message, void *userdata, sd_bus_error *error) {
470 : 0 : Link *l = userdata;
471 : : const char *dns_over_tls;
472 : : DnsOverTlsMode mode;
473 : : int r;
474 : :
475 [ # # ]: 0 : assert(message);
476 [ # # ]: 0 : assert(l);
477 : :
478 : 0 : r = verify_unmanaged_link(l, error);
479 [ # # ]: 0 : if (r < 0)
480 : 0 : return r;
481 : :
482 : 0 : r = sd_bus_message_read(message, "s", &dns_over_tls);
483 [ # # ]: 0 : if (r < 0)
484 : 0 : return r;
485 : :
486 [ # # ]: 0 : if (isempty(dns_over_tls))
487 : 0 : mode = _DNS_OVER_TLS_MODE_INVALID;
488 : : else {
489 : 0 : mode = dns_over_tls_mode_from_string(dns_over_tls);
490 [ # # ]: 0 : if (mode < 0)
491 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSOverTLS setting: %s", dns_over_tls);
492 : : }
493 : :
494 : 0 : link_set_dns_over_tls_mode(l, mode);
495 : :
496 : 0 : (void) link_save_user(l);
497 : :
498 : 0 : return sd_bus_reply_method_return(message, NULL);
499 : : }
500 : :
501 : 0 : int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
502 : 0 : Link *l = userdata;
503 : : const char *dnssec;
504 : : DnssecMode mode;
505 : : int r;
506 : :
507 [ # # ]: 0 : assert(message);
508 [ # # ]: 0 : assert(l);
509 : :
510 : 0 : r = verify_unmanaged_link(l, error);
511 [ # # ]: 0 : if (r < 0)
512 : 0 : return r;
513 : :
514 : 0 : r = sd_bus_message_read(message, "s", &dnssec);
515 [ # # ]: 0 : if (r < 0)
516 : 0 : return r;
517 : :
518 [ # # ]: 0 : if (isempty(dnssec))
519 : 0 : mode = _DNSSEC_MODE_INVALID;
520 : : else {
521 : 0 : mode = dnssec_mode_from_string(dnssec);
522 [ # # ]: 0 : if (mode < 0)
523 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSSEC setting: %s", dnssec);
524 : : }
525 : :
526 : 0 : link_set_dnssec_mode(l, mode);
527 : :
528 : 0 : (void) link_save_user(l);
529 : :
530 : 0 : return sd_bus_reply_method_return(message, NULL);
531 : : }
532 : :
533 : 0 : int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
534 : 0 : _cleanup_set_free_free_ Set *ns = NULL;
535 : 0 : _cleanup_strv_free_ char **ntas = NULL;
536 : 0 : Link *l = userdata;
537 : : int r;
538 : : char **i;
539 : :
540 [ # # ]: 0 : assert(message);
541 [ # # ]: 0 : assert(l);
542 : :
543 : 0 : r = verify_unmanaged_link(l, error);
544 [ # # ]: 0 : if (r < 0)
545 : 0 : return r;
546 : :
547 : 0 : r = sd_bus_message_read_strv(message, &ntas);
548 [ # # ]: 0 : if (r < 0)
549 : 0 : return r;
550 : :
551 [ # # # # ]: 0 : STRV_FOREACH(i, ntas) {
552 : 0 : r = dns_name_is_valid(*i);
553 [ # # ]: 0 : if (r < 0)
554 : 0 : return r;
555 [ # # ]: 0 : if (r == 0)
556 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid negative trust anchor domain: %s", *i);
557 : : }
558 : :
559 : 0 : ns = set_new(&dns_name_hash_ops);
560 [ # # ]: 0 : if (!ns)
561 : 0 : return -ENOMEM;
562 : :
563 [ # # # # ]: 0 : STRV_FOREACH(i, ntas) {
564 : 0 : r = set_put_strdup(ns, *i);
565 [ # # ]: 0 : if (r < 0)
566 : 0 : return r;
567 : : }
568 : :
569 : 0 : set_free_free(l->dnssec_negative_trust_anchors);
570 : 0 : l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
571 : :
572 : 0 : (void) link_save_user(l);
573 : :
574 : 0 : return sd_bus_reply_method_return(message, NULL);
575 : : }
576 : :
577 : 0 : int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error *error) {
578 : 0 : Link *l = userdata;
579 : : int r;
580 : :
581 [ # # ]: 0 : assert(message);
582 [ # # ]: 0 : assert(l);
583 : :
584 : 0 : r = verify_unmanaged_link(l, error);
585 [ # # ]: 0 : if (r < 0)
586 : 0 : return r;
587 : :
588 : 0 : link_flush_settings(l);
589 : 0 : link_allocate_scopes(l);
590 : 0 : link_add_rrs(l, false);
591 : :
592 : 0 : (void) link_save_user(l);
593 : 0 : (void) manager_write_resolv_conf(l->manager);
594 : :
595 : 0 : return sd_bus_reply_method_return(message, NULL);
596 : : }
597 : :
598 : : const sd_bus_vtable link_vtable[] = {
599 : : SD_BUS_VTABLE_START(0),
600 : :
601 : : SD_BUS_PROPERTY("ScopesMask", "t", property_get_scopes_mask, 0, 0),
602 : : SD_BUS_PROPERTY("DNS", "a(iay)", property_get_dns, 0, 0),
603 : : SD_BUS_PROPERTY("CurrentDNSServer", "(iay)", property_get_current_dns_server, offsetof(Link, current_dns_server), 0),
604 : : SD_BUS_PROPERTY("Domains", "a(sb)", property_get_domains, 0, 0),
605 : : SD_BUS_PROPERTY("DefaultRoute", "b", property_get_default_route, 0, 0),
606 : : SD_BUS_PROPERTY("LLMNR", "s", bus_property_get_resolve_support, offsetof(Link, llmnr_support), 0),
607 : : SD_BUS_PROPERTY("MulticastDNS", "s", bus_property_get_resolve_support, offsetof(Link, mdns_support), 0),
608 : : SD_BUS_PROPERTY("DNSOverTLS", "s", property_get_dns_over_tls_mode, 0, 0),
609 : : SD_BUS_PROPERTY("DNSSEC", "s", property_get_dnssec_mode, 0, 0),
610 : : SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
611 : : SD_BUS_PROPERTY("DNSSECSupported", "b", property_get_dnssec_supported, 0, 0),
612 : :
613 : : SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, 0),
614 : : SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, 0),
615 : : SD_BUS_METHOD("SetDefaultRoute", "b", NULL, bus_link_method_set_default_route, 0),
616 : : SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, 0),
617 : : SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, 0),
618 : : SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, 0),
619 : : SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, 0),
620 : : SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, 0),
621 : : SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, 0),
622 : :
623 : : SD_BUS_VTABLE_END
624 : : };
625 : :
626 : 0 : int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
627 : 0 : _cleanup_free_ char *e = NULL;
628 : 0 : Manager *m = userdata;
629 : : int ifindex;
630 : : Link *link;
631 : : int r;
632 : :
633 [ # # ]: 0 : assert(bus);
634 [ # # ]: 0 : assert(path);
635 [ # # ]: 0 : assert(interface);
636 [ # # ]: 0 : assert(found);
637 [ # # ]: 0 : assert(m);
638 : :
639 : 0 : r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/link", &e);
640 [ # # ]: 0 : if (r <= 0)
641 : 0 : return 0;
642 : :
643 : 0 : r = parse_ifindex(e, &ifindex);
644 [ # # ]: 0 : if (r < 0)
645 : 0 : return 0;
646 : :
647 : 0 : link = hashmap_get(m->links, INT_TO_PTR(ifindex));
648 [ # # ]: 0 : if (!link)
649 : 0 : return 0;
650 : :
651 : 0 : *found = link;
652 : 0 : return 1;
653 : : }
654 : :
655 : 0 : char *link_bus_path(Link *link) {
656 : 0 : _cleanup_free_ char *ifindex = NULL;
657 : : char *p;
658 : : int r;
659 : :
660 [ # # ]: 0 : assert(link);
661 : :
662 [ # # ]: 0 : if (asprintf(&ifindex, "%i", link->ifindex) < 0)
663 : 0 : return NULL;
664 : :
665 : 0 : r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifindex, &p);
666 [ # # ]: 0 : if (r < 0)
667 : 0 : return NULL;
668 : :
669 : 0 : return p;
670 : : }
671 : :
672 : 0 : int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
673 : 0 : _cleanup_strv_free_ char **l = NULL;
674 : 0 : Manager *m = userdata;
675 : : Link *link;
676 : : Iterator i;
677 : 0 : unsigned c = 0;
678 : :
679 [ # # ]: 0 : assert(bus);
680 [ # # ]: 0 : assert(path);
681 [ # # ]: 0 : assert(m);
682 [ # # ]: 0 : assert(nodes);
683 : :
684 [ # # ]: 0 : l = new0(char*, hashmap_size(m->links) + 1);
685 [ # # ]: 0 : if (!l)
686 : 0 : return -ENOMEM;
687 : :
688 [ # # ]: 0 : HASHMAP_FOREACH(link, m->links, i) {
689 : : char *p;
690 : :
691 : 0 : p = link_bus_path(link);
692 [ # # ]: 0 : if (!p)
693 : 0 : return -ENOMEM;
694 : :
695 : 0 : l[c++] = p;
696 : : }
697 : :
698 : 0 : l[c] = NULL;
699 : 0 : *nodes = TAKE_PTR(l);
700 : :
701 : 0 : return 1;
702 : : }
|