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