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