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