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