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