]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-link.c
resolved: make sure DNS configuration pushed in by the user stays around on restarts
[thirdparty/systemd.git] / src / resolve / resolved-link.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2014 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <net/if.h>
21
22 #include "sd-network.h"
23
24 #include "alloc-util.h"
25 #include "fd-util.h"
26 #include "fileio.h"
27 #include "missing.h"
28 #include "mkdir.h"
29 #include "parse-util.h"
30 #include "resolved-link.h"
31 #include "string-util.h"
32 #include "strv.h"
33
34 int link_new(Manager *m, Link **ret, int ifindex) {
35 _cleanup_(link_freep) Link *l = NULL;
36 int r;
37
38 assert(m);
39 assert(ifindex > 0);
40
41 r = hashmap_ensure_allocated(&m->links, NULL);
42 if (r < 0)
43 return r;
44
45 l = new0(Link, 1);
46 if (!l)
47 return -ENOMEM;
48
49 l->ifindex = ifindex;
50 l->llmnr_support = RESOLVE_SUPPORT_YES;
51 l->mdns_support = RESOLVE_SUPPORT_NO;
52 l->dnssec_mode = _DNSSEC_MODE_INVALID;
53 l->operstate = IF_OPER_UNKNOWN;
54
55 if (asprintf(&l->state_file, "/run/systemd/resolve/netif/%i", ifindex) < 0)
56 return -ENOMEM;
57
58 r = hashmap_put(m->links, INT_TO_PTR(ifindex), l);
59 if (r < 0)
60 return r;
61
62 l->manager = m;
63
64 if (ret)
65 *ret = l;
66 l = NULL;
67
68 return 0;
69 }
70
71 void link_flush_settings(Link *l) {
72 assert(l);
73
74 l->llmnr_support = RESOLVE_SUPPORT_YES;
75 l->mdns_support = RESOLVE_SUPPORT_NO;
76 l->dnssec_mode = _DNSSEC_MODE_INVALID;
77
78 dns_server_unlink_all(l->dns_servers);
79 dns_search_domain_unlink_all(l->search_domains);
80
81 l->dnssec_negative_trust_anchors = set_free_free(l->dnssec_negative_trust_anchors);
82 }
83
84 Link *link_free(Link *l) {
85 if (!l)
86 return NULL;
87
88 link_flush_settings(l);
89
90 while (l->addresses)
91 (void) link_address_free(l->addresses);
92
93 if (l->manager)
94 hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex));
95
96 dns_scope_free(l->unicast_scope);
97 dns_scope_free(l->llmnr_ipv4_scope);
98 dns_scope_free(l->llmnr_ipv6_scope);
99 dns_scope_free(l->mdns_ipv4_scope);
100 dns_scope_free(l->mdns_ipv6_scope);
101
102 free(l->state_file);
103
104 free(l);
105 return NULL;
106 }
107
108 void link_allocate_scopes(Link *l) {
109 int r;
110
111 assert(l);
112
113 if (link_relevant(l, AF_UNSPEC, false) &&
114 l->dns_servers) {
115 if (!l->unicast_scope) {
116 r = dns_scope_new(l->manager, &l->unicast_scope, l, DNS_PROTOCOL_DNS, AF_UNSPEC);
117 if (r < 0)
118 log_warning_errno(r, "Failed to allocate DNS scope: %m");
119 }
120 } else
121 l->unicast_scope = dns_scope_free(l->unicast_scope);
122
123 if (link_relevant(l, AF_INET, true) &&
124 l->llmnr_support != RESOLVE_SUPPORT_NO &&
125 l->manager->llmnr_support != RESOLVE_SUPPORT_NO) {
126 if (!l->llmnr_ipv4_scope) {
127 r = dns_scope_new(l->manager, &l->llmnr_ipv4_scope, l, DNS_PROTOCOL_LLMNR, AF_INET);
128 if (r < 0)
129 log_warning_errno(r, "Failed to allocate LLMNR IPv4 scope: %m");
130 }
131 } else
132 l->llmnr_ipv4_scope = dns_scope_free(l->llmnr_ipv4_scope);
133
134 if (link_relevant(l, AF_INET6, true) &&
135 l->llmnr_support != RESOLVE_SUPPORT_NO &&
136 l->manager->llmnr_support != RESOLVE_SUPPORT_NO &&
137 socket_ipv6_is_supported()) {
138 if (!l->llmnr_ipv6_scope) {
139 r = dns_scope_new(l->manager, &l->llmnr_ipv6_scope, l, DNS_PROTOCOL_LLMNR, AF_INET6);
140 if (r < 0)
141 log_warning_errno(r, "Failed to allocate LLMNR IPv6 scope: %m");
142 }
143 } else
144 l->llmnr_ipv6_scope = dns_scope_free(l->llmnr_ipv6_scope);
145
146 if (link_relevant(l, AF_INET, true) &&
147 l->mdns_support != RESOLVE_SUPPORT_NO &&
148 l->manager->mdns_support != RESOLVE_SUPPORT_NO) {
149 if (!l->mdns_ipv4_scope) {
150 r = dns_scope_new(l->manager, &l->mdns_ipv4_scope, l, DNS_PROTOCOL_MDNS, AF_INET);
151 if (r < 0)
152 log_warning_errno(r, "Failed to allocate mDNS IPv4 scope: %m");
153 }
154 } else
155 l->mdns_ipv4_scope = dns_scope_free(l->mdns_ipv4_scope);
156
157 if (link_relevant(l, AF_INET6, true) &&
158 l->mdns_support != RESOLVE_SUPPORT_NO &&
159 l->manager->mdns_support != RESOLVE_SUPPORT_NO) {
160 if (!l->mdns_ipv6_scope) {
161 r = dns_scope_new(l->manager, &l->mdns_ipv6_scope, l, DNS_PROTOCOL_MDNS, AF_INET6);
162 if (r < 0)
163 log_warning_errno(r, "Failed to allocate mDNS IPv6 scope: %m");
164 }
165 } else
166 l->mdns_ipv6_scope = dns_scope_free(l->mdns_ipv6_scope);
167 }
168
169 void link_add_rrs(Link *l, bool force_remove) {
170 LinkAddress *a;
171
172 LIST_FOREACH(addresses, a, l->addresses)
173 link_address_add_rrs(a, force_remove);
174 }
175
176 int link_process_rtnl(Link *l, sd_netlink_message *m) {
177 const char *n = NULL;
178 int r;
179
180 assert(l);
181 assert(m);
182
183 r = sd_rtnl_message_link_get_flags(m, &l->flags);
184 if (r < 0)
185 return r;
186
187 (void) sd_netlink_message_read_u32(m, IFLA_MTU, &l->mtu);
188 (void) sd_netlink_message_read_u8(m, IFLA_OPERSTATE, &l->operstate);
189
190 if (sd_netlink_message_read_string(m, IFLA_IFNAME, &n) >= 0) {
191 strncpy(l->name, n, sizeof(l->name)-1);
192 char_array_0(l->name);
193 }
194
195 link_allocate_scopes(l);
196 link_add_rrs(l, false);
197
198 return 0;
199 }
200
201 static int link_update_dns_server_one(Link *l, const char *name) {
202 union in_addr_union a;
203 DnsServer *s;
204 int family, r;
205
206 assert(l);
207 assert(name);
208
209 r = in_addr_from_string_auto(name, &family, &a);
210 if (r < 0)
211 return r;
212
213 s = dns_server_find(l->dns_servers, family, &a, 0);
214 if (s) {
215 dns_server_move_back_and_unmark(s);
216 return 0;
217 }
218
219 return dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a, 0);
220 }
221
222 static int link_update_dns_servers(Link *l) {
223 _cleanup_strv_free_ char **nameservers = NULL;
224 char **nameserver;
225 int r;
226
227 assert(l);
228
229 r = sd_network_link_get_dns(l->ifindex, &nameservers);
230 if (r == -ENODATA) {
231 r = 0;
232 goto clear;
233 }
234 if (r < 0)
235 goto clear;
236
237 dns_server_mark_all(l->dns_servers);
238
239 STRV_FOREACH(nameserver, nameservers) {
240 r = link_update_dns_server_one(l, *nameserver);
241 if (r < 0)
242 goto clear;
243 }
244
245 dns_server_unlink_marked(l->dns_servers);
246 return 0;
247
248 clear:
249 dns_server_unlink_all(l->dns_servers);
250 return r;
251 }
252
253 static int link_update_llmnr_support(Link *l) {
254 _cleanup_free_ char *b = NULL;
255 int r;
256
257 assert(l);
258
259 r = sd_network_link_get_llmnr(l->ifindex, &b);
260 if (r == -ENODATA) {
261 r = 0;
262 goto clear;
263 }
264 if (r < 0)
265 goto clear;
266
267 l->llmnr_support = resolve_support_from_string(b);
268 if (l->llmnr_support < 0) {
269 r = -EINVAL;
270 goto clear;
271 }
272
273 return 0;
274
275 clear:
276 l->llmnr_support = RESOLVE_SUPPORT_YES;
277 return r;
278 }
279
280 static int link_update_mdns_support(Link *l) {
281 _cleanup_free_ char *b = NULL;
282 int r;
283
284 assert(l);
285
286 r = sd_network_link_get_mdns(l->ifindex, &b);
287 if (r == -ENODATA) {
288 r = 0;
289 goto clear;
290 }
291 if (r < 0)
292 goto clear;
293
294 l->mdns_support = resolve_support_from_string(b);
295 if (l->mdns_support < 0) {
296 r = -EINVAL;
297 goto clear;
298 }
299
300 return 0;
301
302 clear:
303 l->mdns_support = RESOLVE_SUPPORT_NO;
304 return r;
305 }
306
307 void link_set_dnssec_mode(Link *l, DnssecMode mode) {
308
309 assert(l);
310
311 if (l->dnssec_mode == mode)
312 return;
313
314 if ((l->dnssec_mode == _DNSSEC_MODE_INVALID) ||
315 (l->dnssec_mode == DNSSEC_NO && mode != DNSSEC_NO) ||
316 (l->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE && mode == DNSSEC_YES)) {
317
318 /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
319 * allow-downgrade mode to full DNSSEC mode, flush it too. */
320 if (l->unicast_scope)
321 dns_cache_flush(&l->unicast_scope->cache);
322 }
323
324 l->dnssec_mode = mode;
325 }
326
327 static int link_update_dnssec_mode(Link *l) {
328 _cleanup_free_ char *m = NULL;
329 DnssecMode mode;
330 int r;
331
332 assert(l);
333
334 r = sd_network_link_get_dnssec(l->ifindex, &m);
335 if (r == -ENODATA) {
336 r = 0;
337 goto clear;
338 }
339 if (r < 0)
340 goto clear;
341
342 mode = dnssec_mode_from_string(m);
343 if (mode < 0) {
344 r = -EINVAL;
345 goto clear;
346 }
347
348 link_set_dnssec_mode(l, mode);
349
350 return 0;
351
352 clear:
353 l->dnssec_mode = _DNSSEC_MODE_INVALID;
354 return r;
355 }
356
357 static int link_update_dnssec_negative_trust_anchors(Link *l) {
358 _cleanup_strv_free_ char **ntas = NULL;
359 _cleanup_set_free_free_ Set *ns = NULL;
360 int r;
361
362 assert(l);
363
364 r = sd_network_link_get_dnssec_negative_trust_anchors(l->ifindex, &ntas);
365 if (r == -ENODATA) {
366 r = 0;
367 goto clear;
368 }
369 if (r < 0)
370 goto clear;
371
372 ns = set_new(&dns_name_hash_ops);
373 if (!ns)
374 return -ENOMEM;
375
376 r = set_put_strdupv(ns, ntas);
377 if (r < 0)
378 return r;
379
380 set_free_free(l->dnssec_negative_trust_anchors);
381 l->dnssec_negative_trust_anchors = ns;
382 ns = NULL;
383
384 return 0;
385
386 clear:
387 l->dnssec_negative_trust_anchors = set_free_free(l->dnssec_negative_trust_anchors);
388 return r;
389 }
390
391 static int link_update_search_domain_one(Link *l, const char *name, bool route_only) {
392 DnsSearchDomain *d;
393 int r;
394
395 assert(l);
396 assert(name);
397
398 r = dns_search_domain_find(l->search_domains, name, &d);
399 if (r < 0)
400 return r;
401 if (r > 0)
402 dns_search_domain_move_back_and_unmark(d);
403 else {
404 r = dns_search_domain_new(l->manager, &d, DNS_SEARCH_DOMAIN_LINK, l, name);
405 if (r < 0)
406 return r;
407 }
408
409 d->route_only = route_only;
410 return 0;
411 }
412
413 static int link_update_search_domains(Link *l) {
414 _cleanup_strv_free_ char **sdomains = NULL, **rdomains = NULL;
415 char **i;
416 int r, q;
417
418 assert(l);
419
420 r = sd_network_link_get_search_domains(l->ifindex, &sdomains);
421 if (r < 0 && r != -ENODATA)
422 goto clear;
423
424 q = sd_network_link_get_route_domains(l->ifindex, &rdomains);
425 if (q < 0 && q != -ENODATA) {
426 r = q;
427 goto clear;
428 }
429
430 if (r == -ENODATA && q == -ENODATA) {
431 /* networkd knows nothing about this interface, and that's fine. */
432 r = 0;
433 goto clear;
434 }
435
436 dns_search_domain_mark_all(l->search_domains);
437
438 STRV_FOREACH(i, sdomains) {
439 r = link_update_search_domain_one(l, *i, false);
440 if (r < 0)
441 goto clear;
442 }
443
444 STRV_FOREACH(i, rdomains) {
445 r = link_update_search_domain_one(l, *i, true);
446 if (r < 0)
447 goto clear;
448 }
449
450 dns_search_domain_unlink_marked(l->search_domains);
451 return 0;
452
453 clear:
454 dns_search_domain_unlink_all(l->search_domains);
455 return r;
456 }
457
458 static int link_is_managed(Link *l) {
459 _cleanup_free_ char *state = NULL;
460 int r;
461
462 assert(l);
463
464 r = sd_network_link_get_setup_state(l->ifindex, &state);
465 if (r == -ENODATA)
466 return 0;
467 if (r < 0)
468 return r;
469
470 return !STR_IN_SET(state, "pending", "unmanaged");
471 }
472
473 static void link_read_settings(Link *l) {
474 int r;
475
476 assert(l);
477
478 /* Read settings from networkd, except when networkd is not managing this interface. */
479
480 r = link_is_managed(l);
481 if (r < 0) {
482 log_warning_errno(r, "Failed to determine whether interface %s is managed: %m", l->name);
483 return;
484 }
485 if (r == 0) {
486
487 /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
488 if (l->is_managed)
489 link_flush_settings(l);
490
491 l->is_managed = false;
492 return;
493 }
494
495 l->is_managed = true;
496
497 r = link_update_dns_servers(l);
498 if (r < 0)
499 log_warning_errno(r, "Failed to read DNS servers for interface %s, ignoring: %m", l->name);
500
501 r = link_update_llmnr_support(l);
502 if (r < 0)
503 log_warning_errno(r, "Failed to read LLMNR support for interface %s, ignoring: %m", l->name);
504
505 r = link_update_mdns_support(l);
506 if (r < 0)
507 log_warning_errno(r, "Failed to read mDNS support for interface %s, ignoring: %m", l->name);
508
509 r = link_update_dnssec_mode(l);
510 if (r < 0)
511 log_warning_errno(r, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l->name);
512
513 r = link_update_dnssec_negative_trust_anchors(l);
514 if (r < 0)
515 log_warning_errno(r, "Failed to read DNSSEC negative trust anchors for interface %s, ignoring: %m", l->name);
516
517 r = link_update_search_domains(l);
518 if (r < 0)
519 log_warning_errno(r, "Failed to read search domains for interface %s, ignoring: %m", l->name);
520 }
521
522 int link_update(Link *l) {
523 assert(l);
524
525 link_read_settings(l);
526 link_load_user(l);
527 link_allocate_scopes(l);
528 link_add_rrs(l, false);
529
530 return 0;
531 }
532
533 bool link_relevant(Link *l, int family, bool local_multicast) {
534 _cleanup_free_ char *state = NULL;
535 LinkAddress *a;
536
537 assert(l);
538
539 /* A link is relevant for local multicast traffic if it isn't a loopback or pointopoint device, has a link
540 * beat, can do multicast and has at least one link-local (or better) IP address.
541 *
542 * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
543 * least one routable address.*/
544
545 if (l->flags & (IFF_LOOPBACK|IFF_DORMANT))
546 return false;
547
548 if ((l->flags & (IFF_UP|IFF_LOWER_UP)) != (IFF_UP|IFF_LOWER_UP))
549 return false;
550
551 if (local_multicast) {
552 if (l->flags & IFF_POINTOPOINT)
553 return false;
554
555 if ((l->flags & IFF_MULTICAST) != IFF_MULTICAST)
556 return false;
557 }
558
559 /* Check kernel operstate
560 * https://www.kernel.org/doc/Documentation/networking/operstates.txt */
561 if (!IN_SET(l->operstate, IF_OPER_UNKNOWN, IF_OPER_UP))
562 return false;
563
564 (void) sd_network_link_get_operational_state(l->ifindex, &state);
565 if (state && !STR_IN_SET(state, "unknown", "degraded", "routable"))
566 return false;
567
568 LIST_FOREACH(addresses, a, l->addresses)
569 if ((family == AF_UNSPEC || a->family == family) && link_address_relevant(a, local_multicast))
570 return true;
571
572 return false;
573 }
574
575 LinkAddress *link_find_address(Link *l, int family, const union in_addr_union *in_addr) {
576 LinkAddress *a;
577
578 assert(l);
579
580 LIST_FOREACH(addresses, a, l->addresses)
581 if (a->family == family && in_addr_equal(family, &a->in_addr, in_addr))
582 return a;
583
584 return NULL;
585 }
586
587 DnsServer* link_set_dns_server(Link *l, DnsServer *s) {
588 assert(l);
589
590 if (l->current_dns_server == s)
591 return s;
592
593 if (s)
594 log_info("Switching to DNS server %s for interface %s.", dns_server_string(s), l->name);
595
596 dns_server_unref(l->current_dns_server);
597 l->current_dns_server = dns_server_ref(s);
598
599 if (l->unicast_scope)
600 dns_cache_flush(&l->unicast_scope->cache);
601
602 return s;
603 }
604
605 DnsServer *link_get_dns_server(Link *l) {
606 assert(l);
607
608 if (!l->current_dns_server)
609 link_set_dns_server(l, l->dns_servers);
610
611 return l->current_dns_server;
612 }
613
614 void link_next_dns_server(Link *l) {
615 assert(l);
616
617 if (!l->current_dns_server)
618 return;
619
620 /* Change to the next one, but make sure to follow the linked
621 * list only if this server is actually still linked. */
622 if (l->current_dns_server->linked && l->current_dns_server->servers_next) {
623 link_set_dns_server(l, l->current_dns_server->servers_next);
624 return;
625 }
626
627 link_set_dns_server(l, l->dns_servers);
628 }
629
630 DnssecMode link_get_dnssec_mode(Link *l) {
631 assert(l);
632
633 if (l->dnssec_mode != _DNSSEC_MODE_INVALID)
634 return l->dnssec_mode;
635
636 return manager_get_dnssec_mode(l->manager);
637 }
638
639 bool link_dnssec_supported(Link *l) {
640 DnsServer *server;
641
642 assert(l);
643
644 if (link_get_dnssec_mode(l) == DNSSEC_NO)
645 return false;
646
647 server = link_get_dns_server(l);
648 if (server)
649 return dns_server_dnssec_supported(server);
650
651 return true;
652 }
653
654 int link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr_union *in_addr) {
655 LinkAddress *a;
656
657 assert(l);
658 assert(in_addr);
659
660 a = new0(LinkAddress, 1);
661 if (!a)
662 return -ENOMEM;
663
664 a->family = family;
665 a->in_addr = *in_addr;
666
667 a->link = l;
668 LIST_PREPEND(addresses, l->addresses, a);
669
670 if (ret)
671 *ret = a;
672
673 return 0;
674 }
675
676 LinkAddress *link_address_free(LinkAddress *a) {
677 if (!a)
678 return NULL;
679
680 if (a->link) {
681 LIST_REMOVE(addresses, a->link->addresses, a);
682
683 if (a->llmnr_address_rr) {
684 if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
685 dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
686 else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
687 dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
688 }
689
690 if (a->llmnr_ptr_rr) {
691 if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
692 dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
693 else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
694 dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
695 }
696 }
697
698 dns_resource_record_unref(a->llmnr_address_rr);
699 dns_resource_record_unref(a->llmnr_ptr_rr);
700
701 free(a);
702 return NULL;
703 }
704
705 void link_address_add_rrs(LinkAddress *a, bool force_remove) {
706 int r;
707
708 assert(a);
709
710 if (a->family == AF_INET) {
711
712 if (!force_remove &&
713 link_address_relevant(a, true) &&
714 a->link->llmnr_ipv4_scope &&
715 a->link->llmnr_support == RESOLVE_SUPPORT_YES &&
716 a->link->manager->llmnr_support == RESOLVE_SUPPORT_YES) {
717
718 if (!a->link->manager->llmnr_host_ipv4_key) {
719 a->link->manager->llmnr_host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->llmnr_hostname);
720 if (!a->link->manager->llmnr_host_ipv4_key) {
721 r = -ENOMEM;
722 goto fail;
723 }
724 }
725
726 if (!a->llmnr_address_rr) {
727 a->llmnr_address_rr = dns_resource_record_new(a->link->manager->llmnr_host_ipv4_key);
728 if (!a->llmnr_address_rr) {
729 r = -ENOMEM;
730 goto fail;
731 }
732
733 a->llmnr_address_rr->a.in_addr = a->in_addr.in;
734 a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
735 }
736
737 if (!a->llmnr_ptr_rr) {
738 r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->llmnr_hostname);
739 if (r < 0)
740 goto fail;
741
742 a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
743 }
744
745 r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_address_rr, true);
746 if (r < 0)
747 log_warning_errno(r, "Failed to add A record to LLMNR zone: %m");
748
749 r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_ptr_rr, false);
750 if (r < 0)
751 log_warning_errno(r, "Failed to add IPv6 PTR record to LLMNR zone: %m");
752 } else {
753 if (a->llmnr_address_rr) {
754 if (a->link->llmnr_ipv4_scope)
755 dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
756 a->llmnr_address_rr = dns_resource_record_unref(a->llmnr_address_rr);
757 }
758
759 if (a->llmnr_ptr_rr) {
760 if (a->link->llmnr_ipv4_scope)
761 dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
762 a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
763 }
764 }
765 }
766
767 if (a->family == AF_INET6) {
768
769 if (!force_remove &&
770 link_address_relevant(a, true) &&
771 a->link->llmnr_ipv6_scope &&
772 a->link->llmnr_support == RESOLVE_SUPPORT_YES &&
773 a->link->manager->llmnr_support == RESOLVE_SUPPORT_YES) {
774
775 if (!a->link->manager->llmnr_host_ipv6_key) {
776 a->link->manager->llmnr_host_ipv6_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, a->link->manager->llmnr_hostname);
777 if (!a->link->manager->llmnr_host_ipv6_key) {
778 r = -ENOMEM;
779 goto fail;
780 }
781 }
782
783 if (!a->llmnr_address_rr) {
784 a->llmnr_address_rr = dns_resource_record_new(a->link->manager->llmnr_host_ipv6_key);
785 if (!a->llmnr_address_rr) {
786 r = -ENOMEM;
787 goto fail;
788 }
789
790 a->llmnr_address_rr->aaaa.in6_addr = a->in_addr.in6;
791 a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
792 }
793
794 if (!a->llmnr_ptr_rr) {
795 r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->llmnr_hostname);
796 if (r < 0)
797 goto fail;
798
799 a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
800 }
801
802 r = dns_zone_put(&a->link->llmnr_ipv6_scope->zone, a->link->llmnr_ipv6_scope, a->llmnr_address_rr, true);
803 if (r < 0)
804 log_warning_errno(r, "Failed to add AAAA record to LLMNR zone: %m");
805
806 r = dns_zone_put(&a->link->llmnr_ipv6_scope->zone, a->link->llmnr_ipv6_scope, a->llmnr_ptr_rr, false);
807 if (r < 0)
808 log_warning_errno(r, "Failed to add IPv6 PTR record to LLMNR zone: %m");
809 } else {
810 if (a->llmnr_address_rr) {
811 if (a->link->llmnr_ipv6_scope)
812 dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
813 a->llmnr_address_rr = dns_resource_record_unref(a->llmnr_address_rr);
814 }
815
816 if (a->llmnr_ptr_rr) {
817 if (a->link->llmnr_ipv6_scope)
818 dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
819 a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
820 }
821 }
822 }
823
824 return;
825
826 fail:
827 log_debug_errno(r, "Failed to update address RRs: %m");
828 }
829
830 int link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m) {
831 int r;
832 assert(a);
833 assert(m);
834
835 r = sd_rtnl_message_addr_get_flags(m, &a->flags);
836 if (r < 0)
837 return r;
838
839 sd_rtnl_message_addr_get_scope(m, &a->scope);
840
841 link_allocate_scopes(a->link);
842 link_add_rrs(a->link, false);
843
844 return 0;
845 }
846
847 bool link_address_relevant(LinkAddress *a, bool local_multicast) {
848 assert(a);
849
850 if (a->flags & (IFA_F_DEPRECATED|IFA_F_TENTATIVE))
851 return false;
852
853 if (a->scope >= (local_multicast ? RT_SCOPE_HOST : RT_SCOPE_LINK))
854 return false;
855
856 return true;
857 }
858
859 static bool link_needs_save(Link *l) {
860 assert(l);
861
862 /* Returns true if any of the settings where set different from the default */
863
864 if (l->is_managed)
865 return false;
866
867 if (l->llmnr_support != RESOLVE_SUPPORT_YES ||
868 l->mdns_support != RESOLVE_SUPPORT_NO ||
869 l->dnssec_mode != _DNSSEC_MODE_INVALID)
870 return true;
871
872 if (l->dns_servers ||
873 l->search_domains)
874 return true;
875
876 if (!set_isempty(l->dnssec_negative_trust_anchors))
877 return true;
878
879 return false;
880 }
881
882 int link_save_user(Link *l) {
883 _cleanup_free_ char *temp_path = NULL;
884 _cleanup_fclose_ FILE *f = NULL;
885 const char *v;
886 int r;
887
888 assert(l);
889 assert(l->state_file);
890
891 if (!link_needs_save(l)) {
892 (void) unlink(l->state_file);
893 return 0;
894 }
895
896 r = mkdir_parents(l->state_file, 0700);
897 if (r < 0)
898 goto fail;
899
900 r = fopen_temporary(l->state_file, &f, &temp_path);
901 if (r < 0)
902 goto fail;
903
904 fputs("# This is private data. Do not parse.\n", f);
905
906 v = resolve_support_to_string(l->llmnr_support);
907 if (v)
908 fprintf(f, "LLMNR=%s\n", v);
909
910 v = resolve_support_to_string(l->mdns_support);
911 if (v)
912 fprintf(f, "MDNS=%s\n", v);
913
914 v = dnssec_mode_to_string(l->dnssec_mode);
915 if (v)
916 fprintf(f, "DNSSEC=%s\n", v);
917
918 if (l->dns_servers) {
919 DnsServer *server;
920
921 fputs("SERVERS=", f);
922 LIST_FOREACH(servers, server, l->dns_servers) {
923
924 if (server != l->dns_servers)
925 fputc(' ', f);
926
927 v = dns_server_string(server);
928 if (!v) {
929 r = -ENOMEM;
930 goto fail;
931 }
932
933 fputs(v, f);
934 }
935 fputc('\n', f);
936 }
937
938 if (l->search_domains) {
939 DnsSearchDomain *domain;
940
941 fputs("DOMAINS=", f);
942 LIST_FOREACH(domains, domain, l->search_domains) {
943
944 if (domain != l->search_domains)
945 fputc(' ', f);
946
947 if (domain->route_only)
948 fputc('~', f);
949
950 fputs(DNS_SEARCH_DOMAIN_NAME(domain), f);
951 }
952 fputc('\n', f);
953 }
954
955 if (!set_isempty(l->dnssec_negative_trust_anchors)) {
956 bool space = false;
957 Iterator i;
958 char *nta;
959
960 fputs("NTAS=", f);
961 SET_FOREACH(nta, l->dnssec_negative_trust_anchors, i) {
962
963 if (space)
964 fputc(' ', f);
965
966 fputs(nta, f);
967 space = true;
968 }
969 fputc('\n', f);
970 }
971
972 r = fflush_and_check(f);
973 if (r < 0)
974 goto fail;
975
976 if (rename(temp_path, l->state_file) < 0) {
977 r = -errno;
978 goto fail;
979 }
980
981 return 0;
982
983 fail:
984 (void) unlink(l->state_file);
985
986 if (temp_path)
987 (void) unlink(temp_path);
988
989 return log_error_errno(r, "Failed to save link data %s: %m", l->state_file);
990 }
991
992 int link_load_user(Link *l) {
993 _cleanup_free_ char
994 *llmnr = NULL,
995 *mdns = NULL,
996 *dnssec = NULL,
997 *servers = NULL,
998 *domains = NULL,
999 *ntas = NULL;
1000
1001 ResolveSupport s;
1002 int r;
1003
1004 assert(l);
1005 assert(l->state_file);
1006
1007 /* Try to load only a single time */
1008 if (l->loaded)
1009 return 0;
1010 l->loaded = true;
1011
1012 if (l->is_managed)
1013 return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */
1014
1015 r = parse_env_file(l->state_file, NEWLINE,
1016 "LLMNR", &llmnr,
1017 "MDNS", &mdns,
1018 "DNSSEC", &dnssec,
1019 "SERVERS", &servers,
1020 "DOMAINS", &domains,
1021 "NTAS", &ntas,
1022 NULL);
1023 if (r == -ENOENT)
1024 return 0;
1025 if (r < 0)
1026 goto fail;
1027
1028 link_flush_settings(l);
1029
1030 /* If we can't recognize the LLMNR or MDNS setting we don't override the default */
1031 s = resolve_support_from_string(llmnr);
1032 if (s >= 0)
1033 l->llmnr_support = s;
1034
1035 s = resolve_support_from_string(mdns);
1036 if (s >= 0)
1037 l->mdns_support = s;
1038
1039 /* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
1040 l->dnssec_mode = dnssec_mode_from_string(dnssec);
1041
1042 if (servers) {
1043 const char *p = servers;
1044
1045 for (;;) {
1046 _cleanup_free_ char *word = NULL;
1047
1048 r = extract_first_word(&p, &word, NULL, 0);
1049 if (r < 0)
1050 goto fail;
1051 if (r == 0)
1052 break;
1053
1054 r = link_update_dns_server_one(l, word);
1055 if (r < 0) {
1056 log_debug_errno(r, "Failed to load DNS server '%s', ignoring: %m", word);
1057 continue;
1058 }
1059 }
1060 }
1061
1062 if (domains) {
1063 const char *p = domains;
1064
1065 for (;;) {
1066 _cleanup_free_ char *word = NULL;
1067 const char *n;
1068 bool is_route;
1069
1070 r = extract_first_word(&p, &word, NULL, 0);
1071 if (r < 0)
1072 goto fail;
1073 if (r == 0)
1074 break;
1075
1076 is_route = word[0] == '~';
1077 n = is_route ? word + 1 : word;
1078
1079 r = link_update_search_domain_one(l, n, is_route);
1080 if (r < 0) {
1081 log_debug_errno(r, "Failed to load search domain '%s', ignoring: %m", word);
1082 continue;
1083 }
1084 }
1085 }
1086
1087 if (ntas) {
1088 _cleanup_set_free_free_ Set *ns = NULL;
1089
1090 ns = set_new(&dns_name_hash_ops);
1091 if (!ns) {
1092 r = -ENOMEM;
1093 goto fail;
1094 }
1095
1096 r = set_put_strsplit(ns, ntas, NULL, 0);
1097 if (r < 0)
1098 goto fail;
1099
1100 l->dnssec_negative_trust_anchors = ns;
1101 ns = NULL;
1102 }
1103
1104 return 0;
1105
1106 fail:
1107 return log_error_errno(r, "Failed to load link data %s: %m", l->state_file);
1108 }
1109
1110 void link_remove_user(Link *l) {
1111 assert(l);
1112 assert(l->state_file);
1113
1114 (void) unlink(l->state_file);
1115 }