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