1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2014 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include "sd-network.h"
25 #include "alloc-util.h"
30 #include "parse-util.h"
31 #include "resolved-link.h"
32 #include "resolved-llmnr.h"
33 #include "resolved-mdns.h"
34 #include "string-util.h"
37 int link_new(Manager
*m
, Link
**ret
, int ifindex
) {
38 _cleanup_(link_freep
) Link
*l
= NULL
;
44 r
= hashmap_ensure_allocated(&m
->links
, NULL
);
53 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
54 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
55 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
56 l
->operstate
= IF_OPER_UNKNOWN
;
58 if (asprintf(&l
->state_file
, "/run/systemd/resolve/netif/%i", ifindex
) < 0)
61 r
= hashmap_put(m
->links
, INT_TO_PTR(ifindex
), l
);
74 void link_flush_settings(Link
*l
) {
77 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
78 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
79 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
81 dns_server_unlink_all(l
->dns_servers
);
82 dns_search_domain_unlink_all(l
->search_domains
);
84 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
87 Link
*link_free(Link
*l
) {
91 /* Send goodbye messages. */
92 dns_scope_announce(l
->mdns_ipv4_scope
, true);
93 dns_scope_announce(l
->mdns_ipv6_scope
, true);
95 link_flush_settings(l
);
98 (void) link_address_free(l
->addresses
);
101 hashmap_remove(l
->manager
->links
, INT_TO_PTR(l
->ifindex
));
103 dns_scope_free(l
->unicast_scope
);
104 dns_scope_free(l
->llmnr_ipv4_scope
);
105 dns_scope_free(l
->llmnr_ipv6_scope
);
106 dns_scope_free(l
->mdns_ipv4_scope
);
107 dns_scope_free(l
->mdns_ipv6_scope
);
114 void link_allocate_scopes(Link
*l
) {
115 bool unicast_relevant
;
120 /* If a link that used to be relevant is no longer, or a link that did not use to be relevant now becomes
121 * relevant, let's reinit the learnt global DNS server information, since we might talk to different servers
122 * now, even if they have the same addresses as before. */
124 unicast_relevant
= link_relevant(l
, AF_UNSPEC
, false);
125 if (unicast_relevant
!= l
->unicast_relevant
) {
126 l
->unicast_relevant
= unicast_relevant
;
128 dns_server_reset_features_all(l
->manager
->fallback_dns_servers
);
129 dns_server_reset_features_all(l
->manager
->dns_servers
);
132 /* And now, allocate all scopes that makes sense now if we didn't have them yet, and drop those which we don't
135 if (unicast_relevant
&& l
->dns_servers
) {
136 if (!l
->unicast_scope
) {
137 dns_server_reset_features_all(l
->dns_servers
);
139 r
= dns_scope_new(l
->manager
, &l
->unicast_scope
, l
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
141 log_warning_errno(r
, "Failed to allocate DNS scope: %m");
144 l
->unicast_scope
= dns_scope_free(l
->unicast_scope
);
146 if (link_relevant(l
, AF_INET
, true) &&
147 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
148 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
149 if (!l
->llmnr_ipv4_scope
) {
150 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv4_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET
);
152 log_warning_errno(r
, "Failed to allocate LLMNR IPv4 scope: %m");
155 l
->llmnr_ipv4_scope
= dns_scope_free(l
->llmnr_ipv4_scope
);
157 if (link_relevant(l
, AF_INET6
, true) &&
158 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
159 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
160 socket_ipv6_is_supported()) {
161 if (!l
->llmnr_ipv6_scope
) {
162 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv6_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET6
);
164 log_warning_errno(r
, "Failed to allocate LLMNR IPv6 scope: %m");
167 l
->llmnr_ipv6_scope
= dns_scope_free(l
->llmnr_ipv6_scope
);
169 if (link_relevant(l
, AF_INET
, true) &&
170 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
171 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
172 if (!l
->mdns_ipv4_scope
) {
173 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv4_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET
);
175 log_warning_errno(r
, "Failed to allocate mDNS IPv4 scope: %m");
178 l
->mdns_ipv4_scope
= dns_scope_free(l
->mdns_ipv4_scope
);
180 if (link_relevant(l
, AF_INET6
, true) &&
181 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
182 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
183 if (!l
->mdns_ipv6_scope
) {
184 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv6_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET6
);
186 log_warning_errno(r
, "Failed to allocate mDNS IPv6 scope: %m");
189 l
->mdns_ipv6_scope
= dns_scope_free(l
->mdns_ipv6_scope
);
192 void link_add_rrs(Link
*l
, bool force_remove
) {
195 LIST_FOREACH(addresses
, a
, l
->addresses
)
196 link_address_add_rrs(a
, force_remove
);
199 int link_process_rtnl(Link
*l
, sd_netlink_message
*m
) {
200 const char *n
= NULL
;
206 r
= sd_rtnl_message_link_get_flags(m
, &l
->flags
);
210 (void) sd_netlink_message_read_u32(m
, IFLA_MTU
, &l
->mtu
);
211 (void) sd_netlink_message_read_u8(m
, IFLA_OPERSTATE
, &l
->operstate
);
213 if (sd_netlink_message_read_string(m
, IFLA_IFNAME
, &n
) >= 0) {
214 strncpy(l
->name
, n
, sizeof(l
->name
)-1);
215 char_array_0(l
->name
);
218 link_allocate_scopes(l
);
219 link_add_rrs(l
, false);
224 static int link_update_dns_server_one(Link
*l
, const char *name
) {
225 union in_addr_union a
;
232 r
= in_addr_from_string_auto(name
, &family
, &a
);
236 s
= dns_server_find(l
->dns_servers
, family
, &a
, 0);
238 dns_server_move_back_and_unmark(s
);
242 return dns_server_new(l
->manager
, NULL
, DNS_SERVER_LINK
, l
, family
, &a
, 0);
245 static int link_update_dns_servers(Link
*l
) {
246 _cleanup_strv_free_
char **nameservers
= NULL
;
252 r
= sd_network_link_get_dns(l
->ifindex
, &nameservers
);
260 dns_server_mark_all(l
->dns_servers
);
262 STRV_FOREACH(nameserver
, nameservers
) {
263 r
= link_update_dns_server_one(l
, *nameserver
);
268 dns_server_unlink_marked(l
->dns_servers
);
272 dns_server_unlink_all(l
->dns_servers
);
276 static int link_update_llmnr_support(Link
*l
) {
277 _cleanup_free_
char *b
= NULL
;
282 r
= sd_network_link_get_llmnr(l
->ifindex
, &b
);
290 l
->llmnr_support
= resolve_support_from_string(b
);
291 if (l
->llmnr_support
< 0) {
299 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
303 static int link_update_mdns_support(Link
*l
) {
304 _cleanup_free_
char *b
= NULL
;
309 r
= sd_network_link_get_mdns(l
->ifindex
, &b
);
317 l
->mdns_support
= resolve_support_from_string(b
);
318 if (l
->mdns_support
< 0) {
326 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
330 void link_set_dnssec_mode(Link
*l
, DnssecMode mode
) {
335 if (IN_SET(mode
, DNSSEC_YES
, DNSSEC_ALLOW_DOWNGRADE
))
336 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.");
340 if (l
->dnssec_mode
== mode
)
343 if ((l
->dnssec_mode
== _DNSSEC_MODE_INVALID
) ||
344 (l
->dnssec_mode
== DNSSEC_NO
&& mode
!= DNSSEC_NO
) ||
345 (l
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
&& mode
== DNSSEC_YES
)) {
347 /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
348 * allow-downgrade mode to full DNSSEC mode, flush it too. */
349 if (l
->unicast_scope
)
350 dns_cache_flush(&l
->unicast_scope
->cache
);
353 l
->dnssec_mode
= mode
;
356 static int link_update_dnssec_mode(Link
*l
) {
357 _cleanup_free_
char *m
= NULL
;
363 r
= sd_network_link_get_dnssec(l
->ifindex
, &m
);
371 mode
= dnssec_mode_from_string(m
);
377 link_set_dnssec_mode(l
, mode
);
382 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
386 static int link_update_dnssec_negative_trust_anchors(Link
*l
) {
387 _cleanup_strv_free_
char **ntas
= NULL
;
388 _cleanup_set_free_free_ Set
*ns
= NULL
;
393 r
= sd_network_link_get_dnssec_negative_trust_anchors(l
->ifindex
, &ntas
);
401 ns
= set_new(&dns_name_hash_ops
);
405 r
= set_put_strdupv(ns
, ntas
);
409 set_free_free(l
->dnssec_negative_trust_anchors
);
410 l
->dnssec_negative_trust_anchors
= ns
;
416 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
420 static int link_update_search_domain_one(Link
*l
, const char *name
, bool route_only
) {
427 r
= dns_search_domain_find(l
->search_domains
, name
, &d
);
431 dns_search_domain_move_back_and_unmark(d
);
433 r
= dns_search_domain_new(l
->manager
, &d
, DNS_SEARCH_DOMAIN_LINK
, l
, name
);
438 d
->route_only
= route_only
;
442 static int link_update_search_domains(Link
*l
) {
443 _cleanup_strv_free_
char **sdomains
= NULL
, **rdomains
= NULL
;
449 r
= sd_network_link_get_search_domains(l
->ifindex
, &sdomains
);
450 if (r
< 0 && r
!= -ENODATA
)
453 q
= sd_network_link_get_route_domains(l
->ifindex
, &rdomains
);
454 if (q
< 0 && q
!= -ENODATA
) {
459 if (r
== -ENODATA
&& q
== -ENODATA
) {
460 /* networkd knows nothing about this interface, and that's fine. */
465 dns_search_domain_mark_all(l
->search_domains
);
467 STRV_FOREACH(i
, sdomains
) {
468 r
= link_update_search_domain_one(l
, *i
, false);
473 STRV_FOREACH(i
, rdomains
) {
474 r
= link_update_search_domain_one(l
, *i
, true);
479 dns_search_domain_unlink_marked(l
->search_domains
);
483 dns_search_domain_unlink_all(l
->search_domains
);
487 static int link_is_managed(Link
*l
) {
488 _cleanup_free_
char *state
= NULL
;
493 r
= sd_network_link_get_setup_state(l
->ifindex
, &state
);
499 return !STR_IN_SET(state
, "pending", "unmanaged");
502 static void link_read_settings(Link
*l
) {
507 /* Read settings from networkd, except when networkd is not managing this interface. */
509 r
= link_is_managed(l
);
511 log_warning_errno(r
, "Failed to determine whether interface %s is managed: %m", l
->name
);
516 /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
518 link_flush_settings(l
);
520 l
->is_managed
= false;
524 l
->is_managed
= true;
526 r
= link_update_dns_servers(l
);
528 log_warning_errno(r
, "Failed to read DNS servers for interface %s, ignoring: %m", l
->name
);
530 r
= link_update_llmnr_support(l
);
532 log_warning_errno(r
, "Failed to read LLMNR support for interface %s, ignoring: %m", l
->name
);
534 r
= link_update_mdns_support(l
);
536 log_warning_errno(r
, "Failed to read mDNS support for interface %s, ignoring: %m", l
->name
);
538 r
= link_update_dnssec_mode(l
);
540 log_warning_errno(r
, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l
->name
);
542 r
= link_update_dnssec_negative_trust_anchors(l
);
544 log_warning_errno(r
, "Failed to read DNSSEC negative trust anchors for interface %s, ignoring: %m", l
->name
);
546 r
= link_update_search_domains(l
);
548 log_warning_errno(r
, "Failed to read search domains for interface %s, ignoring: %m", l
->name
);
551 int link_update(Link
*l
) {
556 link_read_settings(l
);
559 if (l
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
560 r
= manager_llmnr_start(l
->manager
);
565 if (l
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
566 r
= manager_mdns_start(l
->manager
);
571 link_allocate_scopes(l
);
572 link_add_rrs(l
, false);
577 bool link_relevant(Link
*l
, int family
, bool local_multicast
) {
578 _cleanup_free_
char *state
= NULL
;
583 /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
584 * beat, can do multicast and has at least one link-local (or better) IP address.
586 * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
587 * least one routable address. */
589 if (l
->flags
& (IFF_LOOPBACK
|IFF_DORMANT
))
592 if ((l
->flags
& (IFF_UP
|IFF_LOWER_UP
)) != (IFF_UP
|IFF_LOWER_UP
))
595 if (local_multicast
) {
596 if ((l
->flags
& IFF_MULTICAST
) != IFF_MULTICAST
)
600 /* Check kernel operstate
601 * https://www.kernel.org/doc/Documentation/networking/operstates.txt */
602 if (!IN_SET(l
->operstate
, IF_OPER_UNKNOWN
, IF_OPER_UP
))
605 (void) sd_network_link_get_operational_state(l
->ifindex
, &state
);
606 if (state
&& !STR_IN_SET(state
, "unknown", "degraded", "routable"))
609 LIST_FOREACH(addresses
, a
, l
->addresses
)
610 if ((family
== AF_UNSPEC
|| a
->family
== family
) && link_address_relevant(a
, local_multicast
))
616 LinkAddress
*link_find_address(Link
*l
, int family
, const union in_addr_union
*in_addr
) {
621 LIST_FOREACH(addresses
, a
, l
->addresses
)
622 if (a
->family
== family
&& in_addr_equal(family
, &a
->in_addr
, in_addr
))
628 DnsServer
* link_set_dns_server(Link
*l
, DnsServer
*s
) {
631 if (l
->current_dns_server
== s
)
635 log_debug("Switching to DNS server %s for interface %s.", dns_server_string(s
), l
->name
);
637 dns_server_unref(l
->current_dns_server
);
638 l
->current_dns_server
= dns_server_ref(s
);
640 if (l
->unicast_scope
)
641 dns_cache_flush(&l
->unicast_scope
->cache
);
646 DnsServer
*link_get_dns_server(Link
*l
) {
649 if (!l
->current_dns_server
)
650 link_set_dns_server(l
, l
->dns_servers
);
652 return l
->current_dns_server
;
655 void link_next_dns_server(Link
*l
) {
658 if (!l
->current_dns_server
)
661 /* Change to the next one, but make sure to follow the linked
662 * list only if this server is actually still linked. */
663 if (l
->current_dns_server
->linked
&& l
->current_dns_server
->servers_next
) {
664 link_set_dns_server(l
, l
->current_dns_server
->servers_next
);
668 link_set_dns_server(l
, l
->dns_servers
);
671 DnssecMode
link_get_dnssec_mode(Link
*l
) {
674 if (l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
675 return l
->dnssec_mode
;
677 return manager_get_dnssec_mode(l
->manager
);
680 bool link_dnssec_supported(Link
*l
) {
685 if (link_get_dnssec_mode(l
) == DNSSEC_NO
)
688 server
= link_get_dns_server(l
);
690 return dns_server_dnssec_supported(server
);
695 int link_address_new(Link
*l
, LinkAddress
**ret
, int family
, const union in_addr_union
*in_addr
) {
701 a
= new0(LinkAddress
, 1);
706 a
->in_addr
= *in_addr
;
709 LIST_PREPEND(addresses
, l
->addresses
, a
);
718 LinkAddress
*link_address_free(LinkAddress
*a
) {
723 LIST_REMOVE(addresses
, a
->link
->addresses
, a
);
725 assert(a
->link
->n_addresses
> 0);
726 a
->link
->n_addresses
--;
728 if (a
->llmnr_address_rr
) {
729 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
730 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
731 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
732 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
735 if (a
->llmnr_ptr_rr
) {
736 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
737 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
738 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
739 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
742 if (a
->mdns_address_rr
) {
743 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
744 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
745 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
746 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
749 if (a
->mdns_ptr_rr
) {
750 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
751 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
752 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
753 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
757 dns_resource_record_unref(a
->llmnr_address_rr
);
758 dns_resource_record_unref(a
->llmnr_ptr_rr
);
759 dns_resource_record_unref(a
->mdns_address_rr
);
760 dns_resource_record_unref(a
->mdns_ptr_rr
);
765 void link_address_add_rrs(LinkAddress
*a
, bool force_remove
) {
770 if (a
->family
== AF_INET
) {
773 link_address_relevant(a
, true) &&
774 a
->link
->llmnr_ipv4_scope
&&
775 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
776 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
778 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
779 a
->link
->manager
->llmnr_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->llmnr_hostname
);
780 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
786 if (!a
->llmnr_address_rr
) {
787 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv4_key
);
788 if (!a
->llmnr_address_rr
) {
793 a
->llmnr_address_rr
->a
.in_addr
= a
->in_addr
.in
;
794 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
797 if (!a
->llmnr_ptr_rr
) {
798 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
802 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
805 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_address_rr
, true);
807 log_warning_errno(r
, "Failed to add A record to LLMNR zone: %m");
809 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_ptr_rr
, false);
811 log_warning_errno(r
, "Failed to add IPv4 PTR record to LLMNR zone: %m");
813 if (a
->llmnr_address_rr
) {
814 if (a
->link
->llmnr_ipv4_scope
)
815 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
816 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
819 if (a
->llmnr_ptr_rr
) {
820 if (a
->link
->llmnr_ipv4_scope
)
821 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
822 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
827 link_address_relevant(a
, true) &&
828 a
->link
->mdns_ipv4_scope
&&
829 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
830 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
831 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
832 a
->link
->manager
->mdns_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->mdns_hostname
);
833 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
839 if (!a
->mdns_address_rr
) {
840 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv4_key
);
841 if (!a
->mdns_address_rr
) {
846 a
->mdns_address_rr
->a
.in_addr
= a
->in_addr
.in
;
847 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
850 if (!a
->mdns_ptr_rr
) {
851 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
855 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
858 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_address_rr
, true);
860 log_warning_errno(r
, "Failed to add A record to MDNS zone: %m");
862 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_ptr_rr
, false);
864 log_warning_errno(r
, "Failed to add IPv4 PTR record to MDNS zone: %m");
866 if (a
->mdns_address_rr
) {
867 if (a
->link
->mdns_ipv4_scope
)
868 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
869 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
872 if (a
->mdns_ptr_rr
) {
873 if (a
->link
->mdns_ipv4_scope
)
874 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
875 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
880 if (a
->family
== AF_INET6
) {
883 link_address_relevant(a
, true) &&
884 a
->link
->llmnr_ipv6_scope
&&
885 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
886 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
888 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
889 a
->link
->manager
->llmnr_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->llmnr_hostname
);
890 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
896 if (!a
->llmnr_address_rr
) {
897 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv6_key
);
898 if (!a
->llmnr_address_rr
) {
903 a
->llmnr_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
904 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
907 if (!a
->llmnr_ptr_rr
) {
908 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
912 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
915 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_address_rr
, true);
917 log_warning_errno(r
, "Failed to add AAAA record to LLMNR zone: %m");
919 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_ptr_rr
, false);
921 log_warning_errno(r
, "Failed to add IPv6 PTR record to LLMNR zone: %m");
923 if (a
->llmnr_address_rr
) {
924 if (a
->link
->llmnr_ipv6_scope
)
925 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
926 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
929 if (a
->llmnr_ptr_rr
) {
930 if (a
->link
->llmnr_ipv6_scope
)
931 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
932 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
937 link_address_relevant(a
, true) &&
938 a
->link
->mdns_ipv6_scope
&&
939 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
940 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
942 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
943 a
->link
->manager
->mdns_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->mdns_hostname
);
944 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
950 if (!a
->mdns_address_rr
) {
951 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv6_key
);
952 if (!a
->mdns_address_rr
) {
957 a
->mdns_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
958 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
961 if (!a
->mdns_ptr_rr
) {
962 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
966 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
969 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_address_rr
, true);
971 log_warning_errno(r
, "Failed to add AAAA record to MDNS zone: %m");
973 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_ptr_rr
, false);
975 log_warning_errno(r
, "Failed to add IPv6 PTR record to MDNS zone: %m");
977 if (a
->mdns_address_rr
) {
978 if (a
->link
->mdns_ipv6_scope
)
979 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
980 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
983 if (a
->mdns_ptr_rr
) {
984 if (a
->link
->mdns_ipv6_scope
)
985 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
986 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
994 log_debug_errno(r
, "Failed to update address RRs: %m");
997 int link_address_update_rtnl(LinkAddress
*a
, sd_netlink_message
*m
) {
1002 r
= sd_rtnl_message_addr_get_flags(m
, &a
->flags
);
1006 sd_rtnl_message_addr_get_scope(m
, &a
->scope
);
1008 link_allocate_scopes(a
->link
);
1009 link_add_rrs(a
->link
, false);
1014 bool link_address_relevant(LinkAddress
*a
, bool local_multicast
) {
1017 if (a
->flags
& (IFA_F_DEPRECATED
|IFA_F_TENTATIVE
))
1020 if (a
->scope
>= (local_multicast
? RT_SCOPE_HOST
: RT_SCOPE_LINK
))
1026 static bool link_needs_save(Link
*l
) {
1029 /* Returns true if any of the settings where set different from the default */
1034 if (l
->llmnr_support
!= RESOLVE_SUPPORT_YES
||
1035 l
->mdns_support
!= RESOLVE_SUPPORT_NO
||
1036 l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
1039 if (l
->dns_servers
||
1043 if (!set_isempty(l
->dnssec_negative_trust_anchors
))
1049 int link_save_user(Link
*l
) {
1050 _cleanup_free_
char *temp_path
= NULL
;
1051 _cleanup_fclose_
FILE *f
= NULL
;
1056 assert(l
->state_file
);
1058 if (!link_needs_save(l
)) {
1059 (void) unlink(l
->state_file
);
1063 r
= mkdir_parents(l
->state_file
, 0700);
1067 r
= fopen_temporary(l
->state_file
, &f
, &temp_path
);
1071 fputs_unlocked("# This is private data. Do not parse.\n", f
);
1073 v
= resolve_support_to_string(l
->llmnr_support
);
1075 fprintf(f
, "LLMNR=%s\n", v
);
1077 v
= resolve_support_to_string(l
->mdns_support
);
1079 fprintf(f
, "MDNS=%s\n", v
);
1081 v
= dnssec_mode_to_string(l
->dnssec_mode
);
1083 fprintf(f
, "DNSSEC=%s\n", v
);
1085 if (l
->dns_servers
) {
1088 fputs_unlocked("SERVERS=", f
);
1089 LIST_FOREACH(servers
, server
, l
->dns_servers
) {
1091 if (server
!= l
->dns_servers
)
1092 fputc_unlocked(' ', f
);
1094 v
= dns_server_string(server
);
1100 fputs_unlocked(v
, f
);
1102 fputc_unlocked('\n', f
);
1105 if (l
->search_domains
) {
1106 DnsSearchDomain
*domain
;
1108 fputs_unlocked("DOMAINS=", f
);
1109 LIST_FOREACH(domains
, domain
, l
->search_domains
) {
1111 if (domain
!= l
->search_domains
)
1112 fputc_unlocked(' ', f
);
1114 if (domain
->route_only
)
1115 fputc_unlocked('~', f
);
1117 fputs_unlocked(DNS_SEARCH_DOMAIN_NAME(domain
), f
);
1119 fputc_unlocked('\n', f
);
1122 if (!set_isempty(l
->dnssec_negative_trust_anchors
)) {
1127 fputs_unlocked("NTAS=", f
);
1128 SET_FOREACH(nta
, l
->dnssec_negative_trust_anchors
, i
) {
1131 fputc_unlocked(' ', f
);
1133 fputs_unlocked(nta
, f
);
1136 fputc_unlocked('\n', f
);
1139 r
= fflush_and_check(f
);
1143 if (rename(temp_path
, l
->state_file
) < 0) {
1151 (void) unlink(l
->state_file
);
1154 (void) unlink(temp_path
);
1156 return log_error_errno(r
, "Failed to save link data %s: %m", l
->state_file
);
1159 int link_load_user(Link
*l
) {
1173 assert(l
->state_file
);
1175 /* Try to load only a single time */
1181 return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */
1183 r
= parse_env_file(l
->state_file
, NEWLINE
,
1187 "SERVERS", &servers
,
1188 "DOMAINS", &domains
,
1196 link_flush_settings(l
);
1198 /* If we can't recognize the LLMNR or MDNS setting we don't override the default */
1199 s
= resolve_support_from_string(llmnr
);
1201 l
->llmnr_support
= s
;
1203 s
= resolve_support_from_string(mdns
);
1205 l
->mdns_support
= s
;
1207 /* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
1208 l
->dnssec_mode
= dnssec_mode_from_string(dnssec
);
1210 for (p
= servers
;;) {
1211 _cleanup_free_
char *word
= NULL
;
1213 r
= extract_first_word(&p
, &word
, NULL
, 0);
1219 r
= link_update_dns_server_one(l
, word
);
1221 log_debug_errno(r
, "Failed to load DNS server '%s', ignoring: %m", word
);
1226 for (p
= domains
;;) {
1227 _cleanup_free_
char *word
= NULL
;
1231 r
= extract_first_word(&p
, &word
, NULL
, 0);
1237 is_route
= word
[0] == '~';
1238 n
= is_route
? word
+ 1 : word
;
1240 r
= link_update_search_domain_one(l
, n
, is_route
);
1242 log_debug_errno(r
, "Failed to load search domain '%s', ignoring: %m", word
);
1248 _cleanup_set_free_free_ Set
*ns
= NULL
;
1250 ns
= set_new(&dns_name_hash_ops
);
1256 r
= set_put_strsplit(ns
, ntas
, NULL
, 0);
1260 l
->dnssec_negative_trust_anchors
= ns
;
1267 return log_error_errno(r
, "Failed to load link data %s: %m", l
->state_file
);
1270 void link_remove_user(Link
*l
) {
1272 assert(l
->state_file
);
1274 (void) unlink(l
->state_file
);