]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-link.c
Merge pull request #21838 from lnussel/logind-refactor
[thirdparty/systemd.git] / src / resolve / resolved-link.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <linux/if.h>
4 #include <unistd.h>
5
6 #include "sd-network.h"
7
8 #include "alloc-util.h"
9 #include "env-file.h"
10 #include "fd-util.h"
11 #include "fileio.h"
12 #include "log-link.h"
13 #include "mkdir.h"
14 #include "netif-util.h"
15 #include "parse-util.h"
16 #include "resolved-link.h"
17 #include "resolved-llmnr.h"
18 #include "resolved-mdns.h"
19 #include "socket-netlink.h"
20 #include "stat-util.h"
21 #include "string-util.h"
22 #include "strv.h"
23 #include "tmpfile-util.h"
24
25 int link_new(Manager *m, Link **ret, int ifindex) {
26 _cleanup_(link_freep) Link *l = NULL;
27 int r;
28
29 assert(m);
30 assert(ifindex > 0);
31
32 l = new(Link, 1);
33 if (!l)
34 return -ENOMEM;
35
36 *l = (Link) {
37 .ifindex = ifindex,
38 .default_route = -1,
39 .llmnr_support = RESOLVE_SUPPORT_YES,
40 .mdns_support = RESOLVE_SUPPORT_NO,
41 .dnssec_mode = _DNSSEC_MODE_INVALID,
42 .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
43 .operstate = IF_OPER_UNKNOWN,
44 };
45
46 if (asprintf(&l->state_file, "/run/systemd/resolve/netif/%i", ifindex) < 0)
47 return -ENOMEM;
48
49 r = hashmap_ensure_put(&m->links, NULL, INT_TO_PTR(ifindex), l);
50 if (r < 0)
51 return r;
52
53 l->manager = m;
54
55 if (ret)
56 *ret = l;
57 TAKE_PTR(l);
58
59 return 0;
60 }
61
62 void link_flush_settings(Link *l) {
63 assert(l);
64
65 l->default_route = -1;
66 l->llmnr_support = RESOLVE_SUPPORT_YES;
67 l->mdns_support = RESOLVE_SUPPORT_NO;
68 l->dnssec_mode = _DNSSEC_MODE_INVALID;
69 l->dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID;
70
71 dns_server_unlink_all(l->dns_servers);
72 dns_search_domain_unlink_all(l->search_domains);
73
74 l->dnssec_negative_trust_anchors = set_free_free(l->dnssec_negative_trust_anchors);
75 }
76
77 Link *link_free(Link *l) {
78 if (!l)
79 return NULL;
80
81 /* Send goodbye messages. */
82 dns_scope_announce(l->mdns_ipv4_scope, true);
83 dns_scope_announce(l->mdns_ipv6_scope, true);
84
85 link_flush_settings(l);
86
87 while (l->addresses)
88 (void) link_address_free(l->addresses);
89
90 if (l->manager)
91 hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex));
92
93 dns_scope_free(l->unicast_scope);
94 dns_scope_free(l->llmnr_ipv4_scope);
95 dns_scope_free(l->llmnr_ipv6_scope);
96 dns_scope_free(l->mdns_ipv4_scope);
97 dns_scope_free(l->mdns_ipv6_scope);
98
99 free(l->state_file);
100 free(l->ifname);
101
102 return mfree(l);
103 }
104
105 void link_allocate_scopes(Link *l) {
106 bool unicast_relevant;
107 int r;
108
109 assert(l);
110
111 /* If a link that used to be relevant is no longer, or a link that did not use to be relevant now becomes
112 * relevant, let's reinit the learnt global DNS server information, since we might talk to different servers
113 * now, even if they have the same addresses as before. */
114
115 unicast_relevant = link_relevant(l, AF_UNSPEC, false);
116 if (unicast_relevant != l->unicast_relevant) {
117 l->unicast_relevant = unicast_relevant;
118
119 dns_server_reset_features_all(l->manager->fallback_dns_servers);
120 dns_server_reset_features_all(l->manager->dns_servers);
121
122 /* Also, flush the global unicast scope, to deal with split horizon setups, where talking through one
123 * interface reveals different DNS zones than through others. */
124 if (l->manager->unicast_scope)
125 dns_cache_flush(&l->manager->unicast_scope->cache);
126 }
127
128 /* And now, allocate all scopes that makes sense now if we didn't have them yet, and drop those which we don't
129 * need anymore */
130
131 if (unicast_relevant && l->dns_servers) {
132 if (!l->unicast_scope) {
133 dns_server_reset_features_all(l->dns_servers);
134
135 r = dns_scope_new(l->manager, &l->unicast_scope, l, DNS_PROTOCOL_DNS, AF_UNSPEC);
136 if (r < 0)
137 log_link_warning_errno(l, r, "Failed to allocate DNS scope, ignoring: %m");
138 }
139 } else
140 l->unicast_scope = dns_scope_free(l->unicast_scope);
141
142 if (link_relevant(l, AF_INET, true) &&
143 l->llmnr_support != RESOLVE_SUPPORT_NO &&
144 l->manager->llmnr_support != RESOLVE_SUPPORT_NO) {
145 if (!l->llmnr_ipv4_scope) {
146 r = dns_scope_new(l->manager, &l->llmnr_ipv4_scope, l, DNS_PROTOCOL_LLMNR, AF_INET);
147 if (r < 0)
148 log_link_warning_errno(l, r, "Failed to allocate LLMNR IPv4 scope, ignoring: %m");
149 }
150 } else
151 l->llmnr_ipv4_scope = dns_scope_free(l->llmnr_ipv4_scope);
152
153 if (link_relevant(l, AF_INET6, true) &&
154 l->llmnr_support != RESOLVE_SUPPORT_NO &&
155 l->manager->llmnr_support != RESOLVE_SUPPORT_NO &&
156 socket_ipv6_is_supported()) {
157 if (!l->llmnr_ipv6_scope) {
158 r = dns_scope_new(l->manager, &l->llmnr_ipv6_scope, l, DNS_PROTOCOL_LLMNR, AF_INET6);
159 if (r < 0)
160 log_link_warning_errno(l, r, "Failed to allocate LLMNR IPv6 scope, ignoring: %m");
161 }
162 } else
163 l->llmnr_ipv6_scope = dns_scope_free(l->llmnr_ipv6_scope);
164
165 if (link_relevant(l, AF_INET, true) &&
166 l->mdns_support != RESOLVE_SUPPORT_NO &&
167 l->manager->mdns_support != RESOLVE_SUPPORT_NO) {
168 if (!l->mdns_ipv4_scope) {
169 r = dns_scope_new(l->manager, &l->mdns_ipv4_scope, l, DNS_PROTOCOL_MDNS, AF_INET);
170 if (r < 0)
171 log_link_warning_errno(l, r, "Failed to allocate mDNS IPv4 scope, ignoring: %m");
172 }
173 } else
174 l->mdns_ipv4_scope = dns_scope_free(l->mdns_ipv4_scope);
175
176 if (link_relevant(l, AF_INET6, true) &&
177 l->mdns_support != RESOLVE_SUPPORT_NO &&
178 l->manager->mdns_support != RESOLVE_SUPPORT_NO) {
179 if (!l->mdns_ipv6_scope) {
180 r = dns_scope_new(l->manager, &l->mdns_ipv6_scope, l, DNS_PROTOCOL_MDNS, AF_INET6);
181 if (r < 0)
182 log_link_warning_errno(l, r, "Failed to allocate mDNS IPv6 scope, ignoring: %m");
183 }
184 } else
185 l->mdns_ipv6_scope = dns_scope_free(l->mdns_ipv6_scope);
186 }
187
188 void link_add_rrs(Link *l, bool force_remove) {
189 LinkAddress *a;
190 int r;
191
192 LIST_FOREACH(addresses, a, l->addresses)
193 link_address_add_rrs(a, force_remove);
194
195 if (!force_remove &&
196 l->mdns_support == RESOLVE_SUPPORT_YES &&
197 l->manager->mdns_support == RESOLVE_SUPPORT_YES) {
198
199 if (l->mdns_ipv4_scope) {
200 r = dns_scope_add_dnssd_services(l->mdns_ipv4_scope);
201 if (r < 0)
202 log_link_warning_errno(l, r, "Failed to add IPv4 DNS-SD services, ignoring: %m");
203 }
204
205 if (l->mdns_ipv6_scope) {
206 r = dns_scope_add_dnssd_services(l->mdns_ipv6_scope);
207 if (r < 0)
208 log_link_warning_errno(l, r, "Failed to add IPv6 DNS-SD services, ignoring: %m");
209 }
210
211 } else {
212
213 if (l->mdns_ipv4_scope) {
214 r = dns_scope_remove_dnssd_services(l->mdns_ipv4_scope);
215 if (r < 0)
216 log_link_warning_errno(l, r, "Failed to remove IPv4 DNS-SD services, ignoring: %m");
217 }
218
219 if (l->mdns_ipv6_scope) {
220 r = dns_scope_remove_dnssd_services(l->mdns_ipv6_scope);
221 if (r < 0)
222 log_link_warning_errno(l, r, "Failed to remove IPv6 DNS-SD services, ignoring: %m");
223 }
224 }
225 }
226
227 int link_process_rtnl(Link *l, sd_netlink_message *m) {
228 const char *n = NULL;
229 int r;
230
231 assert(l);
232 assert(m);
233
234 r = sd_rtnl_message_link_get_flags(m, &l->flags);
235 if (r < 0)
236 return r;
237
238 (void) sd_netlink_message_read_u32(m, IFLA_MTU, &l->mtu);
239 (void) sd_netlink_message_read_u8(m, IFLA_OPERSTATE, &l->operstate);
240
241 if (sd_netlink_message_read_string(m, IFLA_IFNAME, &n) >= 0 &&
242 !streq_ptr(l->ifname, n)) {
243 if (l->ifname)
244 log_link_debug(l, "Interface name change detected: %s -> %s", l->ifname, n);
245
246 r = free_and_strdup(&l->ifname, n);
247 if (r < 0)
248 return r;
249 }
250
251 return 0;
252 }
253
254 static int link_update_dns_server_one(Link *l, const char *str) {
255 _cleanup_free_ char *name = NULL;
256 int family, ifindex, r;
257 union in_addr_union a;
258 DnsServer *s;
259 uint16_t port;
260
261 assert(l);
262 assert(str);
263
264 r = in_addr_port_ifindex_name_from_string_auto(str, &family, &a, &port, &ifindex, &name);
265 if (r < 0)
266 return r;
267
268 if (ifindex != 0 && ifindex != l->ifindex)
269 return -EINVAL;
270
271 /* By default, the port number is determined with the transaction feature level.
272 * See dns_transaction_port() and dns_server_port(). */
273 if (IN_SET(port, 53, 853))
274 port = 0;
275
276 s = dns_server_find(l->dns_servers, family, &a, port, 0, name);
277 if (s) {
278 dns_server_move_back_and_unmark(s);
279 return 0;
280 }
281
282 return dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a, port, 0, name);
283 }
284
285 static int link_update_dns_servers(Link *l) {
286 _cleanup_strv_free_ char **nameservers = NULL;
287 char **nameserver;
288 int r;
289
290 assert(l);
291
292 r = sd_network_link_get_dns(l->ifindex, &nameservers);
293 if (r == -ENODATA) {
294 r = 0;
295 goto clear;
296 }
297 if (r < 0)
298 goto clear;
299
300 dns_server_mark_all(l->dns_servers);
301
302 STRV_FOREACH(nameserver, nameservers) {
303 r = link_update_dns_server_one(l, *nameserver);
304 if (r < 0)
305 goto clear;
306 }
307
308 dns_server_unlink_marked(l->dns_servers);
309 return 0;
310
311 clear:
312 dns_server_unlink_all(l->dns_servers);
313 return r;
314 }
315
316 static int link_update_default_route(Link *l) {
317 int r;
318
319 assert(l);
320
321 r = sd_network_link_get_dns_default_route(l->ifindex);
322 if (r == -ENODATA) {
323 r = 0;
324 goto clear;
325 }
326 if (r < 0)
327 goto clear;
328
329 l->default_route = r > 0;
330 return 0;
331
332 clear:
333 l->default_route = -1;
334 return r;
335 }
336
337 static int link_update_llmnr_support(Link *l) {
338 _cleanup_free_ char *b = NULL;
339 int r;
340
341 assert(l);
342
343 l->llmnr_support = RESOLVE_SUPPORT_YES; /* yes, yes, we set it twice which is ugly */
344
345 r = sd_network_link_get_llmnr(l->ifindex, &b);
346 if (r == -ENODATA)
347 return 0;
348 if (r < 0)
349 return r;
350
351 r = resolve_support_from_string(b);
352 if (r < 0)
353 return r;
354
355 l->llmnr_support = r;
356 return 0;
357 }
358
359 static int link_update_mdns_support(Link *l) {
360 _cleanup_free_ char *b = NULL;
361 int r;
362
363 assert(l);
364
365 l->mdns_support = RESOLVE_SUPPORT_NO;
366
367 r = sd_network_link_get_mdns(l->ifindex, &b);
368 if (r == -ENODATA)
369 return 0;
370 if (r < 0)
371 return r;
372
373 r = resolve_support_from_string(b);
374 if (r < 0)
375 return r;
376
377 l->mdns_support = r;
378 return 0;
379 }
380
381 void link_set_dns_over_tls_mode(Link *l, DnsOverTlsMode mode) {
382
383 assert(l);
384
385 #if ! ENABLE_DNS_OVER_TLS
386 if (mode != DNS_OVER_TLS_NO)
387 log_link_warning(l,
388 "DNS-over-TLS option for the link cannot be enabled or set to opportunistic "
389 "when systemd-resolved is built without DNS-over-TLS support. "
390 "Turning off DNS-over-TLS support.");
391 return;
392 #endif
393
394 l->dns_over_tls_mode = mode;
395 }
396
397 static int link_update_dns_over_tls_mode(Link *l) {
398 _cleanup_free_ char *b = NULL;
399 int r;
400
401 assert(l);
402
403 l->dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID;
404
405 r = sd_network_link_get_dns_over_tls(l->ifindex, &b);
406 if (r == -ENODATA)
407 return 0;
408 if (r < 0)
409 return r;
410
411 r = dns_over_tls_mode_from_string(b);
412 if (r < 0)
413 return r;
414
415 l->dns_over_tls_mode = r;
416 return 0;
417 }
418
419 void link_set_dnssec_mode(Link *l, DnssecMode mode) {
420
421 assert(l);
422
423 #if !HAVE_OPENSSL_OR_GCRYPT
424 if (IN_SET(mode, DNSSEC_YES, DNSSEC_ALLOW_DOWNGRADE))
425 log_link_warning(l,
426 "DNSSEC option for the link cannot be enabled or set to allow-downgrade "
427 "when systemd-resolved is built without a cryptographic library. "
428 "Turning off DNSSEC support.");
429 return;
430 #endif
431
432 if (l->dnssec_mode == mode)
433 return;
434
435 if ((l->dnssec_mode == _DNSSEC_MODE_INVALID) ||
436 (l->dnssec_mode == DNSSEC_NO && mode != DNSSEC_NO) ||
437 (l->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE && mode == DNSSEC_YES)) {
438
439 /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
440 * allow-downgrade mode to full DNSSEC mode, flush it too. */
441 if (l->unicast_scope)
442 dns_cache_flush(&l->unicast_scope->cache);
443 }
444
445 l->dnssec_mode = mode;
446 }
447
448 static int link_update_dnssec_mode(Link *l) {
449 _cleanup_free_ char *m = NULL;
450 DnssecMode mode;
451 int r;
452
453 assert(l);
454
455 l->dnssec_mode = _DNSSEC_MODE_INVALID;
456
457 r = sd_network_link_get_dnssec(l->ifindex, &m);
458 if (r == -ENODATA)
459 return 0;
460 if (r < 0)
461 return r;
462
463 mode = dnssec_mode_from_string(m);
464 if (mode < 0)
465 return mode;
466
467 link_set_dnssec_mode(l, mode);
468 return 0;
469 }
470
471 static int link_update_dnssec_negative_trust_anchors(Link *l) {
472 _cleanup_strv_free_ char **ntas = NULL;
473 _cleanup_set_free_free_ Set *ns = NULL;
474 int r;
475
476 assert(l);
477
478 l->dnssec_negative_trust_anchors = set_free_free(l->dnssec_negative_trust_anchors);
479
480 r = sd_network_link_get_dnssec_negative_trust_anchors(l->ifindex, &ntas);
481 if (r == -ENODATA)
482 return r;
483 if (r < 0)
484 return r;
485
486 ns = set_new(&dns_name_hash_ops);
487 if (!ns)
488 return -ENOMEM;
489
490 r = set_put_strdupv(&ns, ntas);
491 if (r < 0)
492 return r;
493
494 l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
495 return 0;
496 }
497
498 static int link_update_search_domain_one(Link *l, const char *name, bool route_only) {
499 DnsSearchDomain *d;
500 int r;
501
502 assert(l);
503 assert(name);
504
505 r = dns_search_domain_find(l->search_domains, name, &d);
506 if (r < 0)
507 return r;
508 if (r > 0)
509 dns_search_domain_move_back_and_unmark(d);
510 else {
511 r = dns_search_domain_new(l->manager, &d, DNS_SEARCH_DOMAIN_LINK, l, name);
512 if (r < 0)
513 return r;
514 }
515
516 d->route_only = route_only;
517 return 0;
518 }
519
520 static int link_update_search_domains(Link *l) {
521 _cleanup_strv_free_ char **sdomains = NULL, **rdomains = NULL;
522 char **i;
523 int r, q;
524
525 assert(l);
526
527 r = sd_network_link_get_search_domains(l->ifindex, &sdomains);
528 if (r < 0 && r != -ENODATA)
529 goto clear;
530
531 q = sd_network_link_get_route_domains(l->ifindex, &rdomains);
532 if (q < 0 && q != -ENODATA) {
533 r = q;
534 goto clear;
535 }
536
537 if (r == -ENODATA && q == -ENODATA) {
538 /* networkd knows nothing about this interface, and that's fine. */
539 r = 0;
540 goto clear;
541 }
542
543 dns_search_domain_mark_all(l->search_domains);
544
545 STRV_FOREACH(i, sdomains) {
546 r = link_update_search_domain_one(l, *i, false);
547 if (r < 0)
548 goto clear;
549 }
550
551 STRV_FOREACH(i, rdomains) {
552 r = link_update_search_domain_one(l, *i, true);
553 if (r < 0)
554 goto clear;
555 }
556
557 dns_search_domain_unlink_marked(l->search_domains);
558 return 0;
559
560 clear:
561 dns_search_domain_unlink_all(l->search_domains);
562 return r;
563 }
564
565 static int link_is_managed(Link *l) {
566 _cleanup_free_ char *state = NULL;
567 int r;
568
569 assert(l);
570
571 r = sd_network_link_get_setup_state(l->ifindex, &state);
572 if (r == -ENODATA)
573 return 0;
574 if (r < 0)
575 return r;
576
577 return !STR_IN_SET(state, "pending", "initialized", "unmanaged");
578 }
579
580 static void link_enter_unmanaged(Link *l) {
581 assert(l);
582
583 /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
584 if (l->is_managed)
585 link_flush_settings(l);
586
587 l->is_managed = false;
588 }
589
590 static void link_read_settings(Link *l) {
591 struct stat st;
592 int r;
593
594 assert(l);
595
596 /* Read settings from networkd, except when networkd is not managing this interface. */
597
598 r = sd_network_link_get_stat(l->ifindex, &st);
599 if (r == -ENOENT)
600 return link_enter_unmanaged(l);
601 if (r < 0)
602 return (void) log_link_warning_errno(l, r, "Failed to stat() networkd's link state file, ignoring: %m");
603
604 if (stat_inode_unmodified(&l->networkd_state_file_stat, &st))
605 /* The state file is unmodified. Not necessary to re-read settings. */
606 return;
607
608 /* Save the new stat for the next event. */
609 l->networkd_state_file_stat = st;
610
611 r = link_is_managed(l);
612 if (r < 0)
613 return (void) log_link_warning_errno(l, r, "Failed to determine whether the interface is managed, ignoring: %m");
614 if (r == 0)
615 return link_enter_unmanaged(l);
616
617 l->is_managed = true;
618
619 r = network_link_get_operational_state(l->ifindex, &l->networkd_operstate);
620 if (r < 0)
621 log_link_warning_errno(l, r, "Failed to read networkd's link operational state, ignoring: %m");
622
623 r = link_update_dns_servers(l);
624 if (r < 0)
625 log_link_warning_errno(l, r, "Failed to read DNS servers for the interface, ignoring: %m");
626
627 r = link_update_llmnr_support(l);
628 if (r < 0)
629 log_link_warning_errno(l, r, "Failed to read LLMNR support for the interface, ignoring: %m");
630
631 r = link_update_mdns_support(l);
632 if (r < 0)
633 log_link_warning_errno(l, r, "Failed to read mDNS support for the interface, ignoring: %m");
634
635 r = link_update_dns_over_tls_mode(l);
636 if (r < 0)
637 log_link_warning_errno(l, r, "Failed to read DNS-over-TLS mode for the interface, ignoring: %m");
638
639 r = link_update_dnssec_mode(l);
640 if (r < 0)
641 log_link_warning_errno(l, r, "Failed to read DNSSEC mode for the interface, ignoring: %m");
642
643 r = link_update_dnssec_negative_trust_anchors(l);
644 if (r < 0)
645 log_link_warning_errno(l, r, "Failed to read DNSSEC negative trust anchors for the interface, ignoring: %m");
646
647 r = link_update_search_domains(l);
648 if (r < 0)
649 log_link_warning_errno(l, r, "Failed to read search domains for the interface, ignoring: %m");
650
651 r = link_update_default_route(l);
652 if (r < 0)
653 log_link_warning_errno(l, r, "Failed to read default route setting for the interface, proceeding anyway: %m");
654 }
655
656 int link_update(Link *l) {
657 int r;
658
659 assert(l);
660
661 link_read_settings(l);
662 r = link_load_user(l);
663 if (r < 0)
664 return r;
665
666 if (l->llmnr_support != RESOLVE_SUPPORT_NO) {
667 r = manager_llmnr_start(l->manager);
668 if (r < 0)
669 return r;
670 }
671
672 if (l->mdns_support != RESOLVE_SUPPORT_NO) {
673 r = manager_mdns_start(l->manager);
674 if (r < 0)
675 return r;
676 }
677
678 link_allocate_scopes(l);
679 link_add_rrs(l, false);
680
681 return 0;
682 }
683
684 bool link_relevant(Link *l, int family, bool local_multicast) {
685 LinkAddress *a;
686
687 assert(l);
688
689 /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
690 * beat, can do multicast and has at least one link-local (or better) IP address.
691 *
692 * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
693 * least one routable address. */
694
695 if ((l->flags & (IFF_LOOPBACK | IFF_DORMANT)) != 0)
696 return false;
697
698 if (!FLAGS_SET(l->flags, IFF_UP | IFF_LOWER_UP))
699 return false;
700
701 if (local_multicast &&
702 !FLAGS_SET(l->flags, IFF_MULTICAST))
703 return false;
704
705 if (!netif_has_carrier(l->operstate, l->flags))
706 return false;
707
708 if (l->is_managed &&
709 !IN_SET(l->networkd_operstate, LINK_OPERSTATE_DEGRADED_CARRIER, LINK_OPERSTATE_DEGRADED, LINK_OPERSTATE_ROUTABLE))
710 return false;
711
712 LIST_FOREACH(addresses, a, l->addresses)
713 if ((family == AF_UNSPEC || a->family == family) && link_address_relevant(a, local_multicast))
714 return true;
715
716 return false;
717 }
718
719 LinkAddress *link_find_address(Link *l, int family, const union in_addr_union *in_addr) {
720 LinkAddress *a;
721
722 assert(l);
723
724 if (!IN_SET(family, AF_INET, AF_INET6))
725 return NULL;
726
727 if (!in_addr)
728 return NULL;
729
730 LIST_FOREACH(addresses, a, l->addresses)
731 if (a->family == family && in_addr_equal(family, &a->in_addr, in_addr))
732 return a;
733
734 return NULL;
735 }
736
737 DnsServer* link_set_dns_server(Link *l, DnsServer *s) {
738 assert(l);
739
740 if (l->current_dns_server == s)
741 return s;
742
743 if (s)
744 log_link_debug(l, "Switching to DNS server %s.", strna(dns_server_string_full(s)));
745
746 dns_server_unref(l->current_dns_server);
747 l->current_dns_server = dns_server_ref(s);
748
749 if (l->unicast_scope)
750 dns_cache_flush(&l->unicast_scope->cache);
751
752 return s;
753 }
754
755 DnsServer *link_get_dns_server(Link *l) {
756 assert(l);
757
758 if (!l->current_dns_server)
759 link_set_dns_server(l, l->dns_servers);
760
761 return l->current_dns_server;
762 }
763
764 void link_next_dns_server(Link *l, DnsServer *if_current) {
765 assert(l);
766
767 /* If the current server of the transaction is specified, and we already are at a different one,
768 * don't do anything */
769 if (if_current && l->current_dns_server != if_current)
770 return;
771
772 /* If currently have no DNS server, then don't do anything, we'll pick it lazily the next time a DNS
773 * server is needed. */
774 if (!l->current_dns_server)
775 return;
776
777 /* Change to the next one, but make sure to follow the linked list only if this server is actually
778 * still linked. */
779 if (l->current_dns_server->linked && l->current_dns_server->servers_next) {
780 link_set_dns_server(l, l->current_dns_server->servers_next);
781 return;
782 }
783
784 /* Pick the first one again, after we reached the end */
785 link_set_dns_server(l, l->dns_servers);
786 }
787
788 DnsOverTlsMode link_get_dns_over_tls_mode(Link *l) {
789 assert(l);
790
791 if (l->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
792 return l->dns_over_tls_mode;
793
794 return manager_get_dns_over_tls_mode(l->manager);
795 }
796
797 DnssecMode link_get_dnssec_mode(Link *l) {
798 assert(l);
799
800 if (l->dnssec_mode != _DNSSEC_MODE_INVALID)
801 return l->dnssec_mode;
802
803 return manager_get_dnssec_mode(l->manager);
804 }
805
806 bool link_dnssec_supported(Link *l) {
807 DnsServer *server;
808
809 assert(l);
810
811 if (link_get_dnssec_mode(l) == DNSSEC_NO)
812 return false;
813
814 server = link_get_dns_server(l);
815 if (server)
816 return dns_server_dnssec_supported(server);
817
818 return true;
819 }
820
821 int link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr_union *in_addr) {
822 LinkAddress *a;
823
824 assert(l);
825 assert(in_addr);
826
827 a = new(LinkAddress, 1);
828 if (!a)
829 return -ENOMEM;
830
831 *a = (LinkAddress) {
832 .family = family,
833 .in_addr = *in_addr,
834 .link = l,
835 .prefixlen = UCHAR_MAX,
836 };
837
838 LIST_PREPEND(addresses, l->addresses, a);
839 l->n_addresses++;
840
841 if (ret)
842 *ret = a;
843
844 return 0;
845 }
846
847 LinkAddress *link_address_free(LinkAddress *a) {
848 if (!a)
849 return NULL;
850
851 if (a->link) {
852 LIST_REMOVE(addresses, a->link->addresses, a);
853
854 assert(a->link->n_addresses > 0);
855 a->link->n_addresses--;
856
857 if (a->llmnr_address_rr) {
858 if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
859 dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
860 else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
861 dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
862 }
863
864 if (a->llmnr_ptr_rr) {
865 if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
866 dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
867 else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
868 dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
869 }
870
871 if (a->mdns_address_rr) {
872 if (a->family == AF_INET && a->link->mdns_ipv4_scope)
873 dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_address_rr);
874 else if (a->family == AF_INET6 && a->link->mdns_ipv6_scope)
875 dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_address_rr);
876 }
877
878 if (a->mdns_ptr_rr) {
879 if (a->family == AF_INET && a->link->mdns_ipv4_scope)
880 dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_ptr_rr);
881 else if (a->family == AF_INET6 && a->link->mdns_ipv6_scope)
882 dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_ptr_rr);
883 }
884 }
885
886 dns_resource_record_unref(a->llmnr_address_rr);
887 dns_resource_record_unref(a->llmnr_ptr_rr);
888 dns_resource_record_unref(a->mdns_address_rr);
889 dns_resource_record_unref(a->mdns_ptr_rr);
890
891 return mfree(a);
892 }
893
894 void link_address_add_rrs(LinkAddress *a, bool force_remove) {
895 int r;
896
897 assert(a);
898
899 if (a->family == AF_INET) {
900
901 if (!force_remove &&
902 link_address_relevant(a, true) &&
903 a->link->llmnr_ipv4_scope &&
904 a->link->llmnr_support == RESOLVE_SUPPORT_YES &&
905 a->link->manager->llmnr_support == RESOLVE_SUPPORT_YES) {
906
907 if (!a->link->manager->llmnr_host_ipv4_key) {
908 a->link->manager->llmnr_host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->llmnr_hostname);
909 if (!a->link->manager->llmnr_host_ipv4_key) {
910 r = -ENOMEM;
911 goto fail;
912 }
913 }
914
915 if (!a->llmnr_address_rr) {
916 a->llmnr_address_rr = dns_resource_record_new(a->link->manager->llmnr_host_ipv4_key);
917 if (!a->llmnr_address_rr) {
918 r = -ENOMEM;
919 goto fail;
920 }
921
922 a->llmnr_address_rr->a.in_addr = a->in_addr.in;
923 a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
924 }
925
926 if (!a->llmnr_ptr_rr) {
927 r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->llmnr_hostname);
928 if (r < 0)
929 goto fail;
930
931 a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
932 }
933
934 r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_address_rr, true);
935 if (r < 0)
936 log_link_warning_errno(a->link, r, "Failed to add A record to LLMNR zone, ignoring: %m");
937
938 r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_ptr_rr, false);
939 if (r < 0)
940 log_link_warning_errno(a->link, r, "Failed to add IPv4 PTR record to LLMNR zone, ignoring: %m");
941 } else {
942 if (a->llmnr_address_rr) {
943 if (a->link->llmnr_ipv4_scope)
944 dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
945 a->llmnr_address_rr = dns_resource_record_unref(a->llmnr_address_rr);
946 }
947
948 if (a->llmnr_ptr_rr) {
949 if (a->link->llmnr_ipv4_scope)
950 dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
951 a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
952 }
953 }
954
955 if (!force_remove &&
956 link_address_relevant(a, true) &&
957 a->link->mdns_ipv4_scope &&
958 a->link->mdns_support == RESOLVE_SUPPORT_YES &&
959 a->link->manager->mdns_support == RESOLVE_SUPPORT_YES) {
960 if (!a->link->manager->mdns_host_ipv4_key) {
961 a->link->manager->mdns_host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->mdns_hostname);
962 if (!a->link->manager->mdns_host_ipv4_key) {
963 r = -ENOMEM;
964 goto fail;
965 }
966 }
967
968 if (!a->mdns_address_rr) {
969 a->mdns_address_rr = dns_resource_record_new(a->link->manager->mdns_host_ipv4_key);
970 if (!a->mdns_address_rr) {
971 r = -ENOMEM;
972 goto fail;
973 }
974
975 a->mdns_address_rr->a.in_addr = a->in_addr.in;
976 a->mdns_address_rr->ttl = MDNS_DEFAULT_TTL;
977 }
978
979 if (!a->mdns_ptr_rr) {
980 r = dns_resource_record_new_reverse(&a->mdns_ptr_rr, a->family, &a->in_addr, a->link->manager->mdns_hostname);
981 if (r < 0)
982 goto fail;
983
984 a->mdns_ptr_rr->ttl = MDNS_DEFAULT_TTL;
985 }
986
987 r = dns_zone_put(&a->link->mdns_ipv4_scope->zone, a->link->mdns_ipv4_scope, a->mdns_address_rr, true);
988 if (r < 0)
989 log_link_warning_errno(a->link, r, "Failed to add A record to MDNS zone, ignoring: %m");
990
991 r = dns_zone_put(&a->link->mdns_ipv4_scope->zone, a->link->mdns_ipv4_scope, a->mdns_ptr_rr, false);
992 if (r < 0)
993 log_link_warning_errno(a->link, r, "Failed to add IPv4 PTR record to MDNS zone, ignoring: %m");
994 } else {
995 if (a->mdns_address_rr) {
996 if (a->link->mdns_ipv4_scope)
997 dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_address_rr);
998 a->mdns_address_rr = dns_resource_record_unref(a->mdns_address_rr);
999 }
1000
1001 if (a->mdns_ptr_rr) {
1002 if (a->link->mdns_ipv4_scope)
1003 dns_zone_remove_rr(&a->link->mdns_ipv4_scope->zone, a->mdns_ptr_rr);
1004 a->mdns_ptr_rr = dns_resource_record_unref(a->mdns_ptr_rr);
1005 }
1006 }
1007 }
1008
1009 if (a->family == AF_INET6) {
1010
1011 if (!force_remove &&
1012 link_address_relevant(a, true) &&
1013 a->link->llmnr_ipv6_scope &&
1014 a->link->llmnr_support == RESOLVE_SUPPORT_YES &&
1015 a->link->manager->llmnr_support == RESOLVE_SUPPORT_YES) {
1016
1017 if (!a->link->manager->llmnr_host_ipv6_key) {
1018 a->link->manager->llmnr_host_ipv6_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, a->link->manager->llmnr_hostname);
1019 if (!a->link->manager->llmnr_host_ipv6_key) {
1020 r = -ENOMEM;
1021 goto fail;
1022 }
1023 }
1024
1025 if (!a->llmnr_address_rr) {
1026 a->llmnr_address_rr = dns_resource_record_new(a->link->manager->llmnr_host_ipv6_key);
1027 if (!a->llmnr_address_rr) {
1028 r = -ENOMEM;
1029 goto fail;
1030 }
1031
1032 a->llmnr_address_rr->aaaa.in6_addr = a->in_addr.in6;
1033 a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
1034 }
1035
1036 if (!a->llmnr_ptr_rr) {
1037 r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->llmnr_hostname);
1038 if (r < 0)
1039 goto fail;
1040
1041 a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
1042 }
1043
1044 r = dns_zone_put(&a->link->llmnr_ipv6_scope->zone, a->link->llmnr_ipv6_scope, a->llmnr_address_rr, true);
1045 if (r < 0)
1046 log_link_warning_errno(a->link, r, "Failed to add AAAA record to LLMNR zone, ignoring: %m");
1047
1048 r = dns_zone_put(&a->link->llmnr_ipv6_scope->zone, a->link->llmnr_ipv6_scope, a->llmnr_ptr_rr, false);
1049 if (r < 0)
1050 log_link_warning_errno(a->link, r, "Failed to add IPv6 PTR record to LLMNR zone, ignoring: %m");
1051 } else {
1052 if (a->llmnr_address_rr) {
1053 if (a->link->llmnr_ipv6_scope)
1054 dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
1055 a->llmnr_address_rr = dns_resource_record_unref(a->llmnr_address_rr);
1056 }
1057
1058 if (a->llmnr_ptr_rr) {
1059 if (a->link->llmnr_ipv6_scope)
1060 dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
1061 a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
1062 }
1063 }
1064
1065 if (!force_remove &&
1066 link_address_relevant(a, true) &&
1067 a->link->mdns_ipv6_scope &&
1068 a->link->mdns_support == RESOLVE_SUPPORT_YES &&
1069 a->link->manager->mdns_support == RESOLVE_SUPPORT_YES) {
1070
1071 if (!a->link->manager->mdns_host_ipv6_key) {
1072 a->link->manager->mdns_host_ipv6_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, a->link->manager->mdns_hostname);
1073 if (!a->link->manager->mdns_host_ipv6_key) {
1074 r = -ENOMEM;
1075 goto fail;
1076 }
1077 }
1078
1079 if (!a->mdns_address_rr) {
1080 a->mdns_address_rr = dns_resource_record_new(a->link->manager->mdns_host_ipv6_key);
1081 if (!a->mdns_address_rr) {
1082 r = -ENOMEM;
1083 goto fail;
1084 }
1085
1086 a->mdns_address_rr->aaaa.in6_addr = a->in_addr.in6;
1087 a->mdns_address_rr->ttl = MDNS_DEFAULT_TTL;
1088 }
1089
1090 if (!a->mdns_ptr_rr) {
1091 r = dns_resource_record_new_reverse(&a->mdns_ptr_rr, a->family, &a->in_addr, a->link->manager->mdns_hostname);
1092 if (r < 0)
1093 goto fail;
1094
1095 a->mdns_ptr_rr->ttl = MDNS_DEFAULT_TTL;
1096 }
1097
1098 r = dns_zone_put(&a->link->mdns_ipv6_scope->zone, a->link->mdns_ipv6_scope, a->mdns_address_rr, true);
1099 if (r < 0)
1100 log_link_warning_errno(a->link, r, "Failed to add AAAA record to MDNS zone, ignoring: %m");
1101
1102 r = dns_zone_put(&a->link->mdns_ipv6_scope->zone, a->link->mdns_ipv6_scope, a->mdns_ptr_rr, false);
1103 if (r < 0)
1104 log_link_warning_errno(a->link, r, "Failed to add IPv6 PTR record to MDNS zone, ignoring: %m");
1105 } else {
1106 if (a->mdns_address_rr) {
1107 if (a->link->mdns_ipv6_scope)
1108 dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_address_rr);
1109 a->mdns_address_rr = dns_resource_record_unref(a->mdns_address_rr);
1110 }
1111
1112 if (a->mdns_ptr_rr) {
1113 if (a->link->mdns_ipv6_scope)
1114 dns_zone_remove_rr(&a->link->mdns_ipv6_scope->zone, a->mdns_ptr_rr);
1115 a->mdns_ptr_rr = dns_resource_record_unref(a->mdns_ptr_rr);
1116 }
1117 }
1118 }
1119
1120 return;
1121
1122 fail:
1123 log_link_debug_errno(a->link, r, "Failed to update address RRs, ignoring: %m");
1124 }
1125
1126 int link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m) {
1127 int r;
1128
1129 assert(a);
1130 assert(m);
1131
1132 r = sd_rtnl_message_addr_get_flags(m, &a->flags);
1133 if (r < 0)
1134 return r;
1135
1136 (void) sd_rtnl_message_addr_get_prefixlen(m, &a->prefixlen);
1137 (void) sd_rtnl_message_addr_get_scope(m, &a->scope);
1138
1139 link_allocate_scopes(a->link);
1140 link_add_rrs(a->link, false);
1141
1142 return 0;
1143 }
1144
1145 bool link_address_relevant(LinkAddress *a, bool local_multicast) {
1146 assert(a);
1147
1148 if (a->flags & (IFA_F_DEPRECATED|IFA_F_TENTATIVE))
1149 return false;
1150
1151 if (a->scope >= (local_multicast ? RT_SCOPE_HOST : RT_SCOPE_LINK))
1152 return false;
1153
1154 return true;
1155 }
1156
1157 static bool link_needs_save(Link *l) {
1158 assert(l);
1159
1160 /* Returns true if any of the settings where set different from the default */
1161
1162 if (l->is_managed)
1163 return false;
1164
1165 if (l->llmnr_support != RESOLVE_SUPPORT_YES ||
1166 l->mdns_support != RESOLVE_SUPPORT_NO ||
1167 l->dnssec_mode != _DNSSEC_MODE_INVALID ||
1168 l->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
1169 return true;
1170
1171 if (l->dns_servers ||
1172 l->search_domains)
1173 return true;
1174
1175 if (!set_isempty(l->dnssec_negative_trust_anchors))
1176 return true;
1177
1178 if (l->default_route >= 0)
1179 return true;
1180
1181 return false;
1182 }
1183
1184 int link_save_user(Link *l) {
1185 _cleanup_free_ char *temp_path = NULL;
1186 _cleanup_fclose_ FILE *f = NULL;
1187 const char *v;
1188 int r;
1189
1190 assert(l);
1191 assert(l->state_file);
1192
1193 if (!link_needs_save(l)) {
1194 (void) unlink(l->state_file);
1195 return 0;
1196 }
1197
1198 r = mkdir_parents(l->state_file, 0700);
1199 if (r < 0)
1200 goto fail;
1201
1202 r = fopen_temporary(l->state_file, &f, &temp_path);
1203 if (r < 0)
1204 goto fail;
1205
1206 (void) fchmod(fileno(f), 0644);
1207
1208 fputs("# This is private data. Do not parse.\n", f);
1209
1210 v = resolve_support_to_string(l->llmnr_support);
1211 if (v)
1212 fprintf(f, "LLMNR=%s\n", v);
1213
1214 v = resolve_support_to_string(l->mdns_support);
1215 if (v)
1216 fprintf(f, "MDNS=%s\n", v);
1217
1218 v = dnssec_mode_to_string(l->dnssec_mode);
1219 if (v)
1220 fprintf(f, "DNSSEC=%s\n", v);
1221
1222 if (l->default_route >= 0)
1223 fprintf(f, "DEFAULT_ROUTE=%s\n", yes_no(l->default_route));
1224
1225 if (l->dns_servers) {
1226 DnsServer *server;
1227
1228 fputs("SERVERS=", f);
1229 LIST_FOREACH(servers, server, l->dns_servers) {
1230
1231 if (server != l->dns_servers)
1232 fputc(' ', f);
1233
1234 v = dns_server_string_full(server);
1235 if (!v) {
1236 r = -ENOMEM;
1237 goto fail;
1238 }
1239
1240 fputs(v, f);
1241 }
1242 fputc('\n', f);
1243 }
1244
1245 if (l->search_domains) {
1246 DnsSearchDomain *domain;
1247
1248 fputs("DOMAINS=", f);
1249 LIST_FOREACH(domains, domain, l->search_domains) {
1250
1251 if (domain != l->search_domains)
1252 fputc(' ', f);
1253
1254 if (domain->route_only)
1255 fputc('~', f);
1256
1257 fputs(DNS_SEARCH_DOMAIN_NAME(domain), f);
1258 }
1259 fputc('\n', f);
1260 }
1261
1262 if (!set_isempty(l->dnssec_negative_trust_anchors)) {
1263 bool space = false;
1264 char *nta;
1265
1266 fputs("NTAS=", f);
1267 SET_FOREACH(nta, l->dnssec_negative_trust_anchors) {
1268
1269 if (space)
1270 fputc(' ', f);
1271
1272 fputs(nta, f);
1273 space = true;
1274 }
1275 fputc('\n', f);
1276 }
1277
1278 r = fflush_and_check(f);
1279 if (r < 0)
1280 goto fail;
1281
1282 if (rename(temp_path, l->state_file) < 0) {
1283 r = -errno;
1284 goto fail;
1285 }
1286
1287 return 0;
1288
1289 fail:
1290 (void) unlink(l->state_file);
1291
1292 if (temp_path)
1293 (void) unlink(temp_path);
1294
1295 return log_link_error_errno(l, r, "Failed to save link data %s: %m", l->state_file);
1296 }
1297
1298 int link_load_user(Link *l) {
1299 _cleanup_free_ char
1300 *llmnr = NULL,
1301 *mdns = NULL,
1302 *dnssec = NULL,
1303 *servers = NULL,
1304 *domains = NULL,
1305 *ntas = NULL,
1306 *default_route = NULL;
1307
1308 ResolveSupport s;
1309 const char *p;
1310 int r;
1311
1312 assert(l);
1313 assert(l->state_file);
1314
1315 /* Try to load only a single time */
1316 if (l->loaded)
1317 return 0;
1318 l->loaded = true;
1319
1320 if (l->is_managed)
1321 return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */
1322
1323 r = parse_env_file(NULL, l->state_file,
1324 "LLMNR", &llmnr,
1325 "MDNS", &mdns,
1326 "DNSSEC", &dnssec,
1327 "SERVERS", &servers,
1328 "DOMAINS", &domains,
1329 "NTAS", &ntas,
1330 "DEFAULT_ROUTE", &default_route);
1331 if (r == -ENOENT)
1332 return 0;
1333 if (r < 0)
1334 goto fail;
1335
1336 link_flush_settings(l);
1337
1338 /* If we can't recognize the LLMNR or MDNS setting we don't override the default */
1339 s = resolve_support_from_string(llmnr);
1340 if (s >= 0)
1341 l->llmnr_support = s;
1342
1343 s = resolve_support_from_string(mdns);
1344 if (s >= 0)
1345 l->mdns_support = s;
1346
1347 r = parse_boolean(default_route);
1348 if (r >= 0)
1349 l->default_route = r;
1350
1351 /* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
1352 l->dnssec_mode = dnssec_mode_from_string(dnssec);
1353
1354 for (p = servers;;) {
1355 _cleanup_free_ char *word = NULL;
1356
1357 r = extract_first_word(&p, &word, NULL, 0);
1358 if (r < 0)
1359 goto fail;
1360 if (r == 0)
1361 break;
1362
1363 r = link_update_dns_server_one(l, word);
1364 if (r < 0) {
1365 log_link_debug_errno(l, r, "Failed to load DNS server '%s', ignoring: %m", word);
1366 continue;
1367 }
1368 }
1369
1370 for (p = domains;;) {
1371 _cleanup_free_ char *word = NULL;
1372 const char *n;
1373 bool is_route;
1374
1375 r = extract_first_word(&p, &word, NULL, 0);
1376 if (r < 0)
1377 goto fail;
1378 if (r == 0)
1379 break;
1380
1381 is_route = word[0] == '~';
1382 n = is_route ? word + 1 : word;
1383
1384 r = link_update_search_domain_one(l, n, is_route);
1385 if (r < 0) {
1386 log_link_debug_errno(l, r, "Failed to load search domain '%s', ignoring: %m", word);
1387 continue;
1388 }
1389 }
1390
1391 if (ntas) {
1392 _cleanup_set_free_free_ Set *ns = NULL;
1393
1394 ns = set_new(&dns_name_hash_ops);
1395 if (!ns) {
1396 r = -ENOMEM;
1397 goto fail;
1398 }
1399
1400 r = set_put_strsplit(ns, ntas, NULL, 0);
1401 if (r < 0)
1402 goto fail;
1403
1404 l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
1405 }
1406
1407 return 0;
1408
1409 fail:
1410 return log_link_error_errno(l, r, "Failed to load link data %s: %m", l->state_file);
1411 }
1412
1413 void link_remove_user(Link *l) {
1414 assert(l);
1415 assert(l->state_file);
1416
1417 (void) unlink(l->state_file);
1418 }
1419
1420 bool link_negative_trust_anchor_lookup(Link *l, const char *name) {
1421 int r;
1422
1423 assert(l);
1424 assert(name);
1425
1426 /* Checks whether the specified domain (or any of its parent domains) are listed as per-link NTA. */
1427
1428 for (;;) {
1429 if (set_contains(l->dnssec_negative_trust_anchors, name))
1430 return true;
1431
1432 /* And now, let's look at the parent, and check that too */
1433 r = dns_name_parent(&name);
1434 if (r < 0)
1435 return r;
1436 if (r == 0)
1437 break;
1438 }
1439
1440 return false;
1441 }