1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2014 Lennart Poettering
11 #include "sd-network.h"
13 #include "alloc-util.h"
18 #include "parse-util.h"
19 #include "resolved-link.h"
20 #include "resolved-llmnr.h"
21 #include "resolved-mdns.h"
22 #include "string-util.h"
25 int link_new(Manager
*m
, Link
**ret
, int ifindex
) {
26 _cleanup_(link_freep
) Link
*l
= NULL
;
32 r
= hashmap_ensure_allocated(&m
->links
, NULL
);
41 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
42 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
43 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
44 l
->private_dns_mode
= _PRIVATE_DNS_MODE_INVALID
;
45 l
->operstate
= IF_OPER_UNKNOWN
;
47 if (asprintf(&l
->state_file
, "/run/systemd/resolve/netif/%i", ifindex
) < 0)
50 r
= hashmap_put(m
->links
, INT_TO_PTR(ifindex
), l
);
63 void link_flush_settings(Link
*l
) {
66 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
67 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
68 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
69 l
->private_dns_mode
= _PRIVATE_DNS_MODE_INVALID
;
71 dns_server_unlink_all(l
->dns_servers
);
72 dns_search_domain_unlink_all(l
->search_domains
);
74 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
77 Link
*link_free(Link
*l
) {
81 /* Send goodbye messages. */
82 dns_scope_announce(l
->mdns_ipv4_scope
, true);
83 dns_scope_announce(l
->mdns_ipv6_scope
, true);
85 link_flush_settings(l
);
88 (void) link_address_free(l
->addresses
);
91 hashmap_remove(l
->manager
->links
, INT_TO_PTR(l
->ifindex
));
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
);
104 void link_allocate_scopes(Link
*l
) {
105 bool unicast_relevant
;
110 /* If a link that used to be relevant is no longer, or a link that did not use to be relevant now becomes
111 * relevant, let's reinit the learnt global DNS server information, since we might talk to different servers
112 * now, even if they have the same addresses as before. */
114 unicast_relevant
= link_relevant(l
, AF_UNSPEC
, false);
115 if (unicast_relevant
!= l
->unicast_relevant
) {
116 l
->unicast_relevant
= unicast_relevant
;
118 dns_server_reset_features_all(l
->manager
->fallback_dns_servers
);
119 dns_server_reset_features_all(l
->manager
->dns_servers
);
121 /* Also, flush the global unicast scope, to deal with split horizon setups, where talking through one
122 * interface reveals different DNS zones than through others. */
123 if (l
->manager
->unicast_scope
)
124 dns_cache_flush(&l
->manager
->unicast_scope
->cache
);
127 /* And now, allocate all scopes that makes sense now if we didn't have them yet, and drop those which we don't
130 if (unicast_relevant
&& l
->dns_servers
) {
131 if (!l
->unicast_scope
) {
132 dns_server_reset_features_all(l
->dns_servers
);
134 r
= dns_scope_new(l
->manager
, &l
->unicast_scope
, l
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
136 log_warning_errno(r
, "Failed to allocate DNS scope: %m");
139 l
->unicast_scope
= dns_scope_free(l
->unicast_scope
);
141 if (link_relevant(l
, AF_INET
, true) &&
142 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
143 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
144 if (!l
->llmnr_ipv4_scope
) {
145 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv4_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET
);
147 log_warning_errno(r
, "Failed to allocate LLMNR IPv4 scope: %m");
150 l
->llmnr_ipv4_scope
= dns_scope_free(l
->llmnr_ipv4_scope
);
152 if (link_relevant(l
, AF_INET6
, true) &&
153 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
154 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
155 socket_ipv6_is_supported()) {
156 if (!l
->llmnr_ipv6_scope
) {
157 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv6_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET6
);
159 log_warning_errno(r
, "Failed to allocate LLMNR IPv6 scope: %m");
162 l
->llmnr_ipv6_scope
= dns_scope_free(l
->llmnr_ipv6_scope
);
164 if (link_relevant(l
, AF_INET
, true) &&
165 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
166 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
167 if (!l
->mdns_ipv4_scope
) {
168 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv4_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET
);
170 log_warning_errno(r
, "Failed to allocate mDNS IPv4 scope: %m");
173 l
->mdns_ipv4_scope
= dns_scope_free(l
->mdns_ipv4_scope
);
175 if (link_relevant(l
, AF_INET6
, true) &&
176 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
177 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
178 if (!l
->mdns_ipv6_scope
) {
179 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv6_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET6
);
181 log_warning_errno(r
, "Failed to allocate mDNS IPv6 scope: %m");
184 l
->mdns_ipv6_scope
= dns_scope_free(l
->mdns_ipv6_scope
);
187 void link_add_rrs(Link
*l
, bool force_remove
) {
191 LIST_FOREACH(addresses
, a
, l
->addresses
)
192 link_address_add_rrs(a
, force_remove
);
195 l
->mdns_support
== RESOLVE_SUPPORT_YES
&&
196 l
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
198 if (l
->mdns_ipv4_scope
) {
199 r
= dns_scope_add_dnssd_services(l
->mdns_ipv4_scope
);
201 log_warning_errno(r
, "Failed to add IPv4 DNS-SD services: %m");
204 if (l
->mdns_ipv6_scope
) {
205 r
= dns_scope_add_dnssd_services(l
->mdns_ipv6_scope
);
207 log_warning_errno(r
, "Failed to add IPv6 DNS-SD services: %m");
212 if (l
->mdns_ipv4_scope
) {
213 r
= dns_scope_remove_dnssd_services(l
->mdns_ipv4_scope
);
215 log_warning_errno(r
, "Failed to remove IPv4 DNS-SD services: %m");
218 if (l
->mdns_ipv6_scope
) {
219 r
= dns_scope_remove_dnssd_services(l
->mdns_ipv6_scope
);
221 log_warning_errno(r
, "Failed to remove IPv6 DNS-SD services: %m");
226 int link_process_rtnl(Link
*l
, sd_netlink_message
*m
) {
227 const char *n
= NULL
;
233 r
= sd_rtnl_message_link_get_flags(m
, &l
->flags
);
237 (void) sd_netlink_message_read_u32(m
, IFLA_MTU
, &l
->mtu
);
238 (void) sd_netlink_message_read_u8(m
, IFLA_OPERSTATE
, &l
->operstate
);
240 if (sd_netlink_message_read_string(m
, IFLA_IFNAME
, &n
) >= 0) {
241 strncpy(l
->name
, n
, sizeof(l
->name
)-1);
242 char_array_0(l
->name
);
245 link_allocate_scopes(l
);
246 link_add_rrs(l
, false);
251 static int link_update_dns_server_one(Link
*l
, const char *name
) {
252 union in_addr_union a
;
259 r
= in_addr_from_string_auto(name
, &family
, &a
);
263 s
= dns_server_find(l
->dns_servers
, family
, &a
, 0);
265 dns_server_move_back_and_unmark(s
);
269 return dns_server_new(l
->manager
, NULL
, DNS_SERVER_LINK
, l
, family
, &a
, 0);
272 static int link_update_dns_servers(Link
*l
) {
273 _cleanup_strv_free_
char **nameservers
= NULL
;
279 r
= sd_network_link_get_dns(l
->ifindex
, &nameservers
);
287 dns_server_mark_all(l
->dns_servers
);
289 STRV_FOREACH(nameserver
, nameservers
) {
290 r
= link_update_dns_server_one(l
, *nameserver
);
295 dns_server_unlink_marked(l
->dns_servers
);
299 dns_server_unlink_all(l
->dns_servers
);
303 static int link_update_llmnr_support(Link
*l
) {
304 _cleanup_free_
char *b
= NULL
;
309 r
= sd_network_link_get_llmnr(l
->ifindex
, &b
);
317 l
->llmnr_support
= resolve_support_from_string(b
);
318 if (l
->llmnr_support
< 0) {
326 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
330 static int link_update_mdns_support(Link
*l
) {
331 _cleanup_free_
char *b
= NULL
;
336 r
= sd_network_link_get_mdns(l
->ifindex
, &b
);
344 l
->mdns_support
= resolve_support_from_string(b
);
345 if (l
->mdns_support
< 0) {
353 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
357 void link_set_private_dns_mode(Link
*l
, PrivateDnsMode mode
) {
362 if (mode
!= PRIVATE_DNS_NO
)
363 log_warning("Private DNS option for the link cannot be set to opportunistic when systemd-resolved is built without gnutls support. Turning off Private DNS support.");
367 l
->private_dns_mode
= mode
;
370 static int link_update_private_dns_mode(Link
*l
) {
371 _cleanup_free_
char *b
= NULL
;
376 r
= sd_network_link_get_private_dns(l
->ifindex
, &b
);
384 l
->private_dns_mode
= private_dns_mode_from_string(b
);
385 if (l
->private_dns_mode
< 0) {
393 l
->private_dns_mode
= _PRIVATE_DNS_MODE_INVALID
;
397 void link_set_dnssec_mode(Link
*l
, DnssecMode mode
) {
402 if (IN_SET(mode
, DNSSEC_YES
, DNSSEC_ALLOW_DOWNGRADE
))
403 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.");
407 if (l
->dnssec_mode
== mode
)
410 if ((l
->dnssec_mode
== _DNSSEC_MODE_INVALID
) ||
411 (l
->dnssec_mode
== DNSSEC_NO
&& mode
!= DNSSEC_NO
) ||
412 (l
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
&& mode
== DNSSEC_YES
)) {
414 /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
415 * allow-downgrade mode to full DNSSEC mode, flush it too. */
416 if (l
->unicast_scope
)
417 dns_cache_flush(&l
->unicast_scope
->cache
);
420 l
->dnssec_mode
= mode
;
423 static int link_update_dnssec_mode(Link
*l
) {
424 _cleanup_free_
char *m
= NULL
;
430 r
= sd_network_link_get_dnssec(l
->ifindex
, &m
);
438 mode
= dnssec_mode_from_string(m
);
444 link_set_dnssec_mode(l
, mode
);
449 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
453 static int link_update_dnssec_negative_trust_anchors(Link
*l
) {
454 _cleanup_strv_free_
char **ntas
= NULL
;
455 _cleanup_set_free_free_ Set
*ns
= NULL
;
460 r
= sd_network_link_get_dnssec_negative_trust_anchors(l
->ifindex
, &ntas
);
468 ns
= set_new(&dns_name_hash_ops
);
472 r
= set_put_strdupv(ns
, ntas
);
476 set_free_free(l
->dnssec_negative_trust_anchors
);
477 l
->dnssec_negative_trust_anchors
= TAKE_PTR(ns
);
482 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
486 static int link_update_search_domain_one(Link
*l
, const char *name
, bool route_only
) {
493 r
= dns_search_domain_find(l
->search_domains
, name
, &d
);
497 dns_search_domain_move_back_and_unmark(d
);
499 r
= dns_search_domain_new(l
->manager
, &d
, DNS_SEARCH_DOMAIN_LINK
, l
, name
);
504 d
->route_only
= route_only
;
508 static int link_update_search_domains(Link
*l
) {
509 _cleanup_strv_free_
char **sdomains
= NULL
, **rdomains
= NULL
;
515 r
= sd_network_link_get_search_domains(l
->ifindex
, &sdomains
);
516 if (r
< 0 && r
!= -ENODATA
)
519 q
= sd_network_link_get_route_domains(l
->ifindex
, &rdomains
);
520 if (q
< 0 && q
!= -ENODATA
) {
525 if (r
== -ENODATA
&& q
== -ENODATA
) {
526 /* networkd knows nothing about this interface, and that's fine. */
531 dns_search_domain_mark_all(l
->search_domains
);
533 STRV_FOREACH(i
, sdomains
) {
534 r
= link_update_search_domain_one(l
, *i
, false);
539 STRV_FOREACH(i
, rdomains
) {
540 r
= link_update_search_domain_one(l
, *i
, true);
545 dns_search_domain_unlink_marked(l
->search_domains
);
549 dns_search_domain_unlink_all(l
->search_domains
);
553 static int link_is_managed(Link
*l
) {
554 _cleanup_free_
char *state
= NULL
;
559 r
= sd_network_link_get_setup_state(l
->ifindex
, &state
);
565 return !STR_IN_SET(state
, "pending", "unmanaged");
568 static void link_read_settings(Link
*l
) {
573 /* Read settings from networkd, except when networkd is not managing this interface. */
575 r
= link_is_managed(l
);
577 log_warning_errno(r
, "Failed to determine whether interface %s is managed: %m", l
->name
);
582 /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
584 link_flush_settings(l
);
586 l
->is_managed
= false;
590 l
->is_managed
= true;
592 r
= link_update_dns_servers(l
);
594 log_warning_errno(r
, "Failed to read DNS servers for interface %s, ignoring: %m", l
->name
);
596 r
= link_update_llmnr_support(l
);
598 log_warning_errno(r
, "Failed to read LLMNR support for interface %s, ignoring: %m", l
->name
);
600 r
= link_update_mdns_support(l
);
602 log_warning_errno(r
, "Failed to read mDNS support for interface %s, ignoring: %m", l
->name
);
604 r
= link_update_private_dns_mode(l
);
606 log_warning_errno(r
, "Failed to read Private DNS mode for interface %s, ignoring: %m", l
->name
);
608 r
= link_update_dnssec_mode(l
);
610 log_warning_errno(r
, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l
->name
);
612 r
= link_update_dnssec_negative_trust_anchors(l
);
614 log_warning_errno(r
, "Failed to read DNSSEC negative trust anchors for interface %s, ignoring: %m", l
->name
);
616 r
= link_update_search_domains(l
);
618 log_warning_errno(r
, "Failed to read search domains for interface %s, ignoring: %m", l
->name
);
621 int link_update(Link
*l
) {
626 link_read_settings(l
);
629 if (l
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
630 r
= manager_llmnr_start(l
->manager
);
635 if (l
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
636 r
= manager_mdns_start(l
->manager
);
641 link_allocate_scopes(l
);
642 link_add_rrs(l
, false);
647 bool link_relevant(Link
*l
, int family
, bool local_multicast
) {
648 _cleanup_free_
char *state
= NULL
;
653 /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
654 * beat, can do multicast and has at least one link-local (or better) IP address.
656 * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
657 * least one routable address. */
659 if (l
->flags
& (IFF_LOOPBACK
|IFF_DORMANT
))
662 if ((l
->flags
& (IFF_UP
|IFF_LOWER_UP
)) != (IFF_UP
|IFF_LOWER_UP
))
665 if (local_multicast
) {
666 if ((l
->flags
& IFF_MULTICAST
) != IFF_MULTICAST
)
670 /* Check kernel operstate
671 * https://www.kernel.org/doc/Documentation/networking/operstates.txt */
672 if (!IN_SET(l
->operstate
, IF_OPER_UNKNOWN
, IF_OPER_UP
))
675 (void) sd_network_link_get_operational_state(l
->ifindex
, &state
);
676 if (state
&& !STR_IN_SET(state
, "unknown", "degraded", "routable"))
679 LIST_FOREACH(addresses
, a
, l
->addresses
)
680 if ((family
== AF_UNSPEC
|| a
->family
== family
) && link_address_relevant(a
, local_multicast
))
686 LinkAddress
*link_find_address(Link
*l
, int family
, const union in_addr_union
*in_addr
) {
691 LIST_FOREACH(addresses
, a
, l
->addresses
)
692 if (a
->family
== family
&& in_addr_equal(family
, &a
->in_addr
, in_addr
))
698 DnsServer
* link_set_dns_server(Link
*l
, DnsServer
*s
) {
701 if (l
->current_dns_server
== s
)
705 log_debug("Switching to DNS server %s for interface %s.", dns_server_string(s
), l
->name
);
707 dns_server_unref(l
->current_dns_server
);
708 l
->current_dns_server
= dns_server_ref(s
);
710 if (l
->unicast_scope
)
711 dns_cache_flush(&l
->unicast_scope
->cache
);
716 DnsServer
*link_get_dns_server(Link
*l
) {
719 if (!l
->current_dns_server
)
720 link_set_dns_server(l
, l
->dns_servers
);
722 return l
->current_dns_server
;
725 void link_next_dns_server(Link
*l
) {
728 if (!l
->current_dns_server
)
731 /* Change to the next one, but make sure to follow the linked
732 * list only if this server is actually still linked. */
733 if (l
->current_dns_server
->linked
&& l
->current_dns_server
->servers_next
) {
734 link_set_dns_server(l
, l
->current_dns_server
->servers_next
);
738 link_set_dns_server(l
, l
->dns_servers
);
741 PrivateDnsMode
link_get_private_dns_mode(Link
*l
) {
744 if (l
->private_dns_mode
!= _PRIVATE_DNS_MODE_INVALID
)
745 return l
->private_dns_mode
;
747 return manager_get_private_dns_mode(l
->manager
);
750 DnssecMode
link_get_dnssec_mode(Link
*l
) {
753 if (l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
754 return l
->dnssec_mode
;
756 return manager_get_dnssec_mode(l
->manager
);
759 bool link_dnssec_supported(Link
*l
) {
764 if (link_get_dnssec_mode(l
) == DNSSEC_NO
)
767 server
= link_get_dns_server(l
);
769 return dns_server_dnssec_supported(server
);
774 int link_address_new(Link
*l
, LinkAddress
**ret
, int family
, const union in_addr_union
*in_addr
) {
780 a
= new0(LinkAddress
, 1);
785 a
->in_addr
= *in_addr
;
788 LIST_PREPEND(addresses
, l
->addresses
, a
);
797 LinkAddress
*link_address_free(LinkAddress
*a
) {
802 LIST_REMOVE(addresses
, a
->link
->addresses
, a
);
804 assert(a
->link
->n_addresses
> 0);
805 a
->link
->n_addresses
--;
807 if (a
->llmnr_address_rr
) {
808 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
809 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
810 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
811 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
814 if (a
->llmnr_ptr_rr
) {
815 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
816 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
817 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
818 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
821 if (a
->mdns_address_rr
) {
822 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
823 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
824 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
825 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
828 if (a
->mdns_ptr_rr
) {
829 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
830 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
831 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
832 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
836 dns_resource_record_unref(a
->llmnr_address_rr
);
837 dns_resource_record_unref(a
->llmnr_ptr_rr
);
838 dns_resource_record_unref(a
->mdns_address_rr
);
839 dns_resource_record_unref(a
->mdns_ptr_rr
);
844 void link_address_add_rrs(LinkAddress
*a
, bool force_remove
) {
849 if (a
->family
== AF_INET
) {
852 link_address_relevant(a
, true) &&
853 a
->link
->llmnr_ipv4_scope
&&
854 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
855 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
857 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
858 a
->link
->manager
->llmnr_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->llmnr_hostname
);
859 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
865 if (!a
->llmnr_address_rr
) {
866 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv4_key
);
867 if (!a
->llmnr_address_rr
) {
872 a
->llmnr_address_rr
->a
.in_addr
= a
->in_addr
.in
;
873 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
876 if (!a
->llmnr_ptr_rr
) {
877 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
881 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
884 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_address_rr
, true);
886 log_warning_errno(r
, "Failed to add A record to LLMNR zone: %m");
888 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_ptr_rr
, false);
890 log_warning_errno(r
, "Failed to add IPv4 PTR record to LLMNR zone: %m");
892 if (a
->llmnr_address_rr
) {
893 if (a
->link
->llmnr_ipv4_scope
)
894 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
895 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
898 if (a
->llmnr_ptr_rr
) {
899 if (a
->link
->llmnr_ipv4_scope
)
900 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
901 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
906 link_address_relevant(a
, true) &&
907 a
->link
->mdns_ipv4_scope
&&
908 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
909 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
910 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
911 a
->link
->manager
->mdns_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->mdns_hostname
);
912 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
918 if (!a
->mdns_address_rr
) {
919 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv4_key
);
920 if (!a
->mdns_address_rr
) {
925 a
->mdns_address_rr
->a
.in_addr
= a
->in_addr
.in
;
926 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
929 if (!a
->mdns_ptr_rr
) {
930 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
934 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
937 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_address_rr
, true);
939 log_warning_errno(r
, "Failed to add A record to MDNS zone: %m");
941 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_ptr_rr
, false);
943 log_warning_errno(r
, "Failed to add IPv4 PTR record to MDNS zone: %m");
945 if (a
->mdns_address_rr
) {
946 if (a
->link
->mdns_ipv4_scope
)
947 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
948 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
951 if (a
->mdns_ptr_rr
) {
952 if (a
->link
->mdns_ipv4_scope
)
953 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
954 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
959 if (a
->family
== AF_INET6
) {
962 link_address_relevant(a
, true) &&
963 a
->link
->llmnr_ipv6_scope
&&
964 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
965 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
967 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
968 a
->link
->manager
->llmnr_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->llmnr_hostname
);
969 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
975 if (!a
->llmnr_address_rr
) {
976 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv6_key
);
977 if (!a
->llmnr_address_rr
) {
982 a
->llmnr_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
983 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
986 if (!a
->llmnr_ptr_rr
) {
987 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
991 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
994 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_address_rr
, true);
996 log_warning_errno(r
, "Failed to add AAAA record to LLMNR zone: %m");
998 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_ptr_rr
, false);
1000 log_warning_errno(r
, "Failed to add IPv6 PTR record to LLMNR zone: %m");
1002 if (a
->llmnr_address_rr
) {
1003 if (a
->link
->llmnr_ipv6_scope
)
1004 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
1005 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
1008 if (a
->llmnr_ptr_rr
) {
1009 if (a
->link
->llmnr_ipv6_scope
)
1010 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
1011 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
1015 if (!force_remove
&&
1016 link_address_relevant(a
, true) &&
1017 a
->link
->mdns_ipv6_scope
&&
1018 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
1019 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
1021 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
1022 a
->link
->manager
->mdns_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->mdns_hostname
);
1023 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
1029 if (!a
->mdns_address_rr
) {
1030 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv6_key
);
1031 if (!a
->mdns_address_rr
) {
1036 a
->mdns_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
1037 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
1040 if (!a
->mdns_ptr_rr
) {
1041 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
1045 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
1048 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_address_rr
, true);
1050 log_warning_errno(r
, "Failed to add AAAA record to MDNS zone: %m");
1052 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_ptr_rr
, false);
1054 log_warning_errno(r
, "Failed to add IPv6 PTR record to MDNS zone: %m");
1056 if (a
->mdns_address_rr
) {
1057 if (a
->link
->mdns_ipv6_scope
)
1058 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
1059 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
1062 if (a
->mdns_ptr_rr
) {
1063 if (a
->link
->mdns_ipv6_scope
)
1064 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
1065 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
1073 log_debug_errno(r
, "Failed to update address RRs: %m");
1076 int link_address_update_rtnl(LinkAddress
*a
, sd_netlink_message
*m
) {
1081 r
= sd_rtnl_message_addr_get_flags(m
, &a
->flags
);
1085 sd_rtnl_message_addr_get_scope(m
, &a
->scope
);
1087 link_allocate_scopes(a
->link
);
1088 link_add_rrs(a
->link
, false);
1093 bool link_address_relevant(LinkAddress
*a
, bool local_multicast
) {
1096 if (a
->flags
& (IFA_F_DEPRECATED
|IFA_F_TENTATIVE
))
1099 if (a
->scope
>= (local_multicast
? RT_SCOPE_HOST
: RT_SCOPE_LINK
))
1105 static bool link_needs_save(Link
*l
) {
1108 /* Returns true if any of the settings where set different from the default */
1113 if (l
->llmnr_support
!= RESOLVE_SUPPORT_YES
||
1114 l
->mdns_support
!= RESOLVE_SUPPORT_NO
||
1115 l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
1118 if (l
->dns_servers
||
1122 if (!set_isempty(l
->dnssec_negative_trust_anchors
))
1128 int link_save_user(Link
*l
) {
1129 _cleanup_free_
char *temp_path
= NULL
;
1130 _cleanup_fclose_
FILE *f
= NULL
;
1135 assert(l
->state_file
);
1137 if (!link_needs_save(l
)) {
1138 (void) unlink(l
->state_file
);
1142 r
= mkdir_parents(l
->state_file
, 0700);
1146 r
= fopen_temporary(l
->state_file
, &f
, &temp_path
);
1150 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
1151 (void) fchmod(fileno(f
), 0644);
1153 fputs("# This is private data. Do not parse.\n", f
);
1155 v
= resolve_support_to_string(l
->llmnr_support
);
1157 fprintf(f
, "LLMNR=%s\n", v
);
1159 v
= resolve_support_to_string(l
->mdns_support
);
1161 fprintf(f
, "MDNS=%s\n", v
);
1163 v
= dnssec_mode_to_string(l
->dnssec_mode
);
1165 fprintf(f
, "DNSSEC=%s\n", v
);
1167 if (l
->dns_servers
) {
1170 fputs("SERVERS=", f
);
1171 LIST_FOREACH(servers
, server
, l
->dns_servers
) {
1173 if (server
!= l
->dns_servers
)
1176 v
= dns_server_string(server
);
1187 if (l
->search_domains
) {
1188 DnsSearchDomain
*domain
;
1190 fputs("DOMAINS=", f
);
1191 LIST_FOREACH(domains
, domain
, l
->search_domains
) {
1193 if (domain
!= l
->search_domains
)
1196 if (domain
->route_only
)
1199 fputs(DNS_SEARCH_DOMAIN_NAME(domain
), f
);
1204 if (!set_isempty(l
->dnssec_negative_trust_anchors
)) {
1210 SET_FOREACH(nta
, l
->dnssec_negative_trust_anchors
, i
) {
1221 r
= fflush_and_check(f
);
1225 if (rename(temp_path
, l
->state_file
) < 0) {
1233 (void) unlink(l
->state_file
);
1236 (void) unlink(temp_path
);
1238 return log_error_errno(r
, "Failed to save link data %s: %m", l
->state_file
);
1241 int link_load_user(Link
*l
) {
1255 assert(l
->state_file
);
1257 /* Try to load only a single time */
1263 return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */
1265 r
= parse_env_file(NULL
, l
->state_file
, NEWLINE
,
1269 "SERVERS", &servers
,
1270 "DOMAINS", &domains
,
1278 link_flush_settings(l
);
1280 /* If we can't recognize the LLMNR or MDNS setting we don't override the default */
1281 s
= resolve_support_from_string(llmnr
);
1283 l
->llmnr_support
= s
;
1285 s
= resolve_support_from_string(mdns
);
1287 l
->mdns_support
= s
;
1289 /* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
1290 l
->dnssec_mode
= dnssec_mode_from_string(dnssec
);
1292 for (p
= servers
;;) {
1293 _cleanup_free_
char *word
= NULL
;
1295 r
= extract_first_word(&p
, &word
, NULL
, 0);
1301 r
= link_update_dns_server_one(l
, word
);
1303 log_debug_errno(r
, "Failed to load DNS server '%s', ignoring: %m", word
);
1308 for (p
= domains
;;) {
1309 _cleanup_free_
char *word
= NULL
;
1313 r
= extract_first_word(&p
, &word
, NULL
, 0);
1319 is_route
= word
[0] == '~';
1320 n
= is_route
? word
+ 1 : word
;
1322 r
= link_update_search_domain_one(l
, n
, is_route
);
1324 log_debug_errno(r
, "Failed to load search domain '%s', ignoring: %m", word
);
1330 _cleanup_set_free_free_ Set
*ns
= NULL
;
1332 ns
= set_new(&dns_name_hash_ops
);
1338 r
= set_put_strsplit(ns
, ntas
, NULL
, 0);
1342 l
->dnssec_negative_trust_anchors
= TAKE_PTR(ns
);
1348 return log_error_errno(r
, "Failed to load link data %s: %m", l
->state_file
);
1351 void link_remove_user(Link
*l
) {
1353 assert(l
->state_file
);
1355 (void) unlink(l
->state_file
);