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