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