1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #include "sd-network.h"
8 #include "alloc-util.h"
13 #include "parse-util.h"
14 #include "resolved-link.h"
15 #include "resolved-llmnr.h"
16 #include "resolved-mdns.h"
17 #include "string-util.h"
19 #include "tmpfile-util.h"
21 int link_new(Manager
*m
, Link
**ret
, int ifindex
) {
22 _cleanup_(link_freep
) Link
*l
= NULL
;
28 r
= hashmap_ensure_allocated(&m
->links
, NULL
);
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
,
46 if (asprintf(&l
->state_file
, "/run/systemd/resolve/netif/%i", ifindex
) < 0)
49 r
= hashmap_put(m
->links
, INT_TO_PTR(ifindex
), l
);
62 void link_flush_settings(Link
*l
) {
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
;
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
);
105 void link_allocate_scopes(Link
*l
) {
106 bool unicast_relevant
;
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. */
115 unicast_relevant
= link_relevant(l
, AF_UNSPEC
, false);
116 if (unicast_relevant
!= l
->unicast_relevant
) {
117 l
->unicast_relevant
= unicast_relevant
;
119 dns_server_reset_features_all(l
->manager
->fallback_dns_servers
);
120 dns_server_reset_features_all(l
->manager
->dns_servers
);
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
);
128 /* And now, allocate all scopes that makes sense now if we didn't have them yet, and drop those which we don't
131 if (unicast_relevant
&& l
->dns_servers
) {
132 if (!l
->unicast_scope
) {
133 dns_server_reset_features_all(l
->dns_servers
);
135 r
= dns_scope_new(l
->manager
, &l
->unicast_scope
, l
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
137 log_warning_errno(r
, "Failed to allocate DNS scope: %m");
140 l
->unicast_scope
= dns_scope_free(l
->unicast_scope
);
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
);
148 log_warning_errno(r
, "Failed to allocate LLMNR IPv4 scope: %m");
151 l
->llmnr_ipv4_scope
= dns_scope_free(l
->llmnr_ipv4_scope
);
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
);
160 log_warning_errno(r
, "Failed to allocate LLMNR IPv6 scope: %m");
163 l
->llmnr_ipv6_scope
= dns_scope_free(l
->llmnr_ipv6_scope
);
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
);
171 log_warning_errno(r
, "Failed to allocate mDNS IPv4 scope: %m");
174 l
->mdns_ipv4_scope
= dns_scope_free(l
->mdns_ipv4_scope
);
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
);
182 log_warning_errno(r
, "Failed to allocate mDNS IPv6 scope: %m");
185 l
->mdns_ipv6_scope
= dns_scope_free(l
->mdns_ipv6_scope
);
188 void link_add_rrs(Link
*l
, bool force_remove
) {
192 LIST_FOREACH(addresses
, a
, l
->addresses
)
193 link_address_add_rrs(a
, force_remove
);
196 l
->mdns_support
== RESOLVE_SUPPORT_YES
&&
197 l
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
199 if (l
->mdns_ipv4_scope
) {
200 r
= dns_scope_add_dnssd_services(l
->mdns_ipv4_scope
);
202 log_warning_errno(r
, "Failed to add IPv4 DNS-SD services: %m");
205 if (l
->mdns_ipv6_scope
) {
206 r
= dns_scope_add_dnssd_services(l
->mdns_ipv6_scope
);
208 log_warning_errno(r
, "Failed to add IPv6 DNS-SD services: %m");
213 if (l
->mdns_ipv4_scope
) {
214 r
= dns_scope_remove_dnssd_services(l
->mdns_ipv4_scope
);
216 log_warning_errno(r
, "Failed to remove IPv4 DNS-SD services: %m");
219 if (l
->mdns_ipv6_scope
) {
220 r
= dns_scope_remove_dnssd_services(l
->mdns_ipv6_scope
);
222 log_warning_errno(r
, "Failed to remove IPv6 DNS-SD services: %m");
227 int link_process_rtnl(Link
*l
, sd_netlink_message
*m
) {
228 const char *n
= NULL
;
234 r
= sd_rtnl_message_link_get_flags(m
, &l
->flags
);
238 (void) sd_netlink_message_read_u32(m
, IFLA_MTU
, &l
->mtu
);
239 (void) sd_netlink_message_read_u8(m
, IFLA_OPERSTATE
, &l
->operstate
);
241 if (sd_netlink_message_read_string(m
, IFLA_IFNAME
, &n
) >= 0) {
242 r
= free_and_strdup(&l
->ifname
, n
);
247 link_allocate_scopes(l
);
248 link_add_rrs(l
, false);
253 static int link_update_dns_server_one(Link
*l
, const char *name
) {
254 union in_addr_union a
;
261 r
= in_addr_from_string_auto(name
, &family
, &a
);
265 s
= dns_server_find(l
->dns_servers
, family
, &a
, 0);
267 dns_server_move_back_and_unmark(s
);
271 return dns_server_new(l
->manager
, NULL
, DNS_SERVER_LINK
, l
, family
, &a
, 0);
274 static int link_update_dns_servers(Link
*l
) {
275 _cleanup_strv_free_
char **nameservers
= NULL
;
281 r
= sd_network_link_get_dns(l
->ifindex
, &nameservers
);
289 dns_server_mark_all(l
->dns_servers
);
291 STRV_FOREACH(nameserver
, nameservers
) {
292 r
= link_update_dns_server_one(l
, *nameserver
);
297 dns_server_unlink_marked(l
->dns_servers
);
301 dns_server_unlink_all(l
->dns_servers
);
305 static int link_update_default_route(Link
*l
) {
310 r
= sd_network_link_get_dns_default_route(l
->ifindex
);
318 l
->default_route
= r
> 0;
322 l
->default_route
= -1;
326 static int link_update_llmnr_support(Link
*l
) {
327 _cleanup_free_
char *b
= NULL
;
332 r
= sd_network_link_get_llmnr(l
->ifindex
, &b
);
340 l
->llmnr_support
= resolve_support_from_string(b
);
341 if (l
->llmnr_support
< 0) {
349 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
353 static int link_update_mdns_support(Link
*l
) {
354 _cleanup_free_
char *b
= NULL
;
359 r
= sd_network_link_get_mdns(l
->ifindex
, &b
);
367 l
->mdns_support
= resolve_support_from_string(b
);
368 if (l
->mdns_support
< 0) {
376 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
380 void link_set_dns_over_tls_mode(Link
*l
, DnsOverTlsMode mode
) {
384 #if ! ENABLE_DNS_OVER_TLS
385 if (mode
!= DNS_OVER_TLS_NO
)
386 log_warning("DNS-over-TLS option for the link cannot be set to opportunistic when systemd-resolved is built without DNS-over-TLS support. Turning off DNS-over-TLS support.");
390 l
->dns_over_tls_mode
= mode
;
393 static int link_update_dns_over_tls_mode(Link
*l
) {
394 _cleanup_free_
char *b
= NULL
;
399 r
= sd_network_link_get_dns_over_tls(l
->ifindex
, &b
);
407 l
->dns_over_tls_mode
= dns_over_tls_mode_from_string(b
);
408 if (l
->dns_over_tls_mode
< 0) {
416 l
->dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
;
420 void link_set_dnssec_mode(Link
*l
, DnssecMode mode
) {
425 if (IN_SET(mode
, DNSSEC_YES
, DNSSEC_ALLOW_DOWNGRADE
))
426 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.");
430 if (l
->dnssec_mode
== mode
)
433 if ((l
->dnssec_mode
== _DNSSEC_MODE_INVALID
) ||
434 (l
->dnssec_mode
== DNSSEC_NO
&& mode
!= DNSSEC_NO
) ||
435 (l
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
&& mode
== DNSSEC_YES
)) {
437 /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
438 * allow-downgrade mode to full DNSSEC mode, flush it too. */
439 if (l
->unicast_scope
)
440 dns_cache_flush(&l
->unicast_scope
->cache
);
443 l
->dnssec_mode
= mode
;
446 static int link_update_dnssec_mode(Link
*l
) {
447 _cleanup_free_
char *m
= NULL
;
453 r
= sd_network_link_get_dnssec(l
->ifindex
, &m
);
461 mode
= dnssec_mode_from_string(m
);
467 link_set_dnssec_mode(l
, mode
);
472 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
476 static int link_update_dnssec_negative_trust_anchors(Link
*l
) {
477 _cleanup_strv_free_
char **ntas
= NULL
;
478 _cleanup_set_free_free_ Set
*ns
= NULL
;
483 r
= sd_network_link_get_dnssec_negative_trust_anchors(l
->ifindex
, &ntas
);
491 ns
= set_new(&dns_name_hash_ops
);
495 r
= set_put_strdupv(ns
, ntas
);
499 set_free_free(l
->dnssec_negative_trust_anchors
);
500 l
->dnssec_negative_trust_anchors
= TAKE_PTR(ns
);
505 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
509 static int link_update_search_domain_one(Link
*l
, const char *name
, bool route_only
) {
516 r
= dns_search_domain_find(l
->search_domains
, name
, &d
);
520 dns_search_domain_move_back_and_unmark(d
);
522 r
= dns_search_domain_new(l
->manager
, &d
, DNS_SEARCH_DOMAIN_LINK
, l
, name
);
527 d
->route_only
= route_only
;
531 static int link_update_search_domains(Link
*l
) {
532 _cleanup_strv_free_
char **sdomains
= NULL
, **rdomains
= NULL
;
538 r
= sd_network_link_get_search_domains(l
->ifindex
, &sdomains
);
539 if (r
< 0 && r
!= -ENODATA
)
542 q
= sd_network_link_get_route_domains(l
->ifindex
, &rdomains
);
543 if (q
< 0 && q
!= -ENODATA
) {
548 if (r
== -ENODATA
&& q
== -ENODATA
) {
549 /* networkd knows nothing about this interface, and that's fine. */
554 dns_search_domain_mark_all(l
->search_domains
);
556 STRV_FOREACH(i
, sdomains
) {
557 r
= link_update_search_domain_one(l
, *i
, false);
562 STRV_FOREACH(i
, rdomains
) {
563 r
= link_update_search_domain_one(l
, *i
, true);
568 dns_search_domain_unlink_marked(l
->search_domains
);
572 dns_search_domain_unlink_all(l
->search_domains
);
576 static int link_is_managed(Link
*l
) {
577 _cleanup_free_
char *state
= NULL
;
582 r
= sd_network_link_get_setup_state(l
->ifindex
, &state
);
588 return !STR_IN_SET(state
, "pending", "unmanaged");
591 static void link_read_settings(Link
*l
) {
596 /* Read settings from networkd, except when networkd is not managing this interface. */
598 r
= link_is_managed(l
);
600 log_warning_errno(r
, "Failed to determine whether interface %s is managed: %m", l
->ifname
);
605 /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
607 link_flush_settings(l
);
609 l
->is_managed
= false;
613 l
->is_managed
= true;
615 r
= link_update_dns_servers(l
);
617 log_warning_errno(r
, "Failed to read DNS servers for interface %s, ignoring: %m", l
->ifname
);
619 r
= link_update_llmnr_support(l
);
621 log_warning_errno(r
, "Failed to read LLMNR support for interface %s, ignoring: %m", l
->ifname
);
623 r
= link_update_mdns_support(l
);
625 log_warning_errno(r
, "Failed to read mDNS support for interface %s, ignoring: %m", l
->ifname
);
627 r
= link_update_dns_over_tls_mode(l
);
629 log_warning_errno(r
, "Failed to read DNS-over-TLS mode for interface %s, ignoring: %m", l
->ifname
);
631 r
= link_update_dnssec_mode(l
);
633 log_warning_errno(r
, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l
->ifname
);
635 r
= link_update_dnssec_negative_trust_anchors(l
);
637 log_warning_errno(r
, "Failed to read DNSSEC negative trust anchors for interface %s, ignoring: %m", l
->ifname
);
639 r
= link_update_search_domains(l
);
641 log_warning_errno(r
, "Failed to read search domains for interface %s, ignoring: %m", l
->ifname
);
643 r
= link_update_default_route(l
);
645 log_warning_errno(r
, "Failed to read default route setting for interface %s, proceeding anyway: %m", l
->ifname
);
648 int link_update(Link
*l
) {
653 link_read_settings(l
);
656 if (l
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
657 r
= manager_llmnr_start(l
->manager
);
662 if (l
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
663 r
= manager_mdns_start(l
->manager
);
668 link_allocate_scopes(l
);
669 link_add_rrs(l
, false);
674 bool link_relevant(Link
*l
, int family
, bool local_multicast
) {
675 _cleanup_free_
char *state
= NULL
;
680 /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
681 * beat, can do multicast and has at least one link-local (or better) IP address.
683 * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
684 * least one routable address. */
686 if (l
->flags
& (IFF_LOOPBACK
|IFF_DORMANT
))
689 if ((l
->flags
& (IFF_UP
|IFF_LOWER_UP
)) != (IFF_UP
|IFF_LOWER_UP
))
692 if (local_multicast
) {
693 if ((l
->flags
& IFF_MULTICAST
) != IFF_MULTICAST
)
697 /* Check kernel operstate
698 * https://www.kernel.org/doc/Documentation/networking/operstates.txt */
699 if (!IN_SET(l
->operstate
, IF_OPER_UNKNOWN
, IF_OPER_UP
))
702 (void) sd_network_link_get_operational_state(l
->ifindex
, &state
);
703 if (state
&& !STR_IN_SET(state
, "unknown", "degraded", "routable"))
706 LIST_FOREACH(addresses
, a
, l
->addresses
)
707 if ((family
== AF_UNSPEC
|| a
->family
== family
) && link_address_relevant(a
, local_multicast
))
713 LinkAddress
*link_find_address(Link
*l
, int family
, const union in_addr_union
*in_addr
) {
718 LIST_FOREACH(addresses
, a
, l
->addresses
)
719 if (a
->family
== family
&& in_addr_equal(family
, &a
->in_addr
, in_addr
))
725 DnsServer
* link_set_dns_server(Link
*l
, DnsServer
*s
) {
728 if (l
->current_dns_server
== s
)
732 log_debug("Switching to DNS server %s for interface %s.", dns_server_string(s
), l
->ifname
);
734 dns_server_unref(l
->current_dns_server
);
735 l
->current_dns_server
= dns_server_ref(s
);
737 if (l
->unicast_scope
)
738 dns_cache_flush(&l
->unicast_scope
->cache
);
743 DnsServer
*link_get_dns_server(Link
*l
) {
746 if (!l
->current_dns_server
)
747 link_set_dns_server(l
, l
->dns_servers
);
749 return l
->current_dns_server
;
752 void link_next_dns_server(Link
*l
) {
755 if (!l
->current_dns_server
)
758 /* Change to the next one, but make sure to follow the linked
759 * list only if this server is actually still linked. */
760 if (l
->current_dns_server
->linked
&& l
->current_dns_server
->servers_next
) {
761 link_set_dns_server(l
, l
->current_dns_server
->servers_next
);
765 link_set_dns_server(l
, l
->dns_servers
);
768 DnsOverTlsMode
link_get_dns_over_tls_mode(Link
*l
) {
771 if (l
->dns_over_tls_mode
!= _DNS_OVER_TLS_MODE_INVALID
)
772 return l
->dns_over_tls_mode
;
774 return manager_get_dns_over_tls_mode(l
->manager
);
777 DnssecMode
link_get_dnssec_mode(Link
*l
) {
780 if (l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
781 return l
->dnssec_mode
;
783 return manager_get_dnssec_mode(l
->manager
);
786 bool link_dnssec_supported(Link
*l
) {
791 if (link_get_dnssec_mode(l
) == DNSSEC_NO
)
794 server
= link_get_dns_server(l
);
796 return dns_server_dnssec_supported(server
);
801 int link_address_new(Link
*l
, LinkAddress
**ret
, int family
, const union in_addr_union
*in_addr
) {
807 a
= new0(LinkAddress
, 1);
812 a
->in_addr
= *in_addr
;
815 LIST_PREPEND(addresses
, l
->addresses
, a
);
824 LinkAddress
*link_address_free(LinkAddress
*a
) {
829 LIST_REMOVE(addresses
, a
->link
->addresses
, a
);
831 assert(a
->link
->n_addresses
> 0);
832 a
->link
->n_addresses
--;
834 if (a
->llmnr_address_rr
) {
835 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
836 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
837 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
838 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
841 if (a
->llmnr_ptr_rr
) {
842 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
843 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
844 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
845 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
848 if (a
->mdns_address_rr
) {
849 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
850 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
851 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
852 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
855 if (a
->mdns_ptr_rr
) {
856 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
857 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
858 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
859 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
863 dns_resource_record_unref(a
->llmnr_address_rr
);
864 dns_resource_record_unref(a
->llmnr_ptr_rr
);
865 dns_resource_record_unref(a
->mdns_address_rr
);
866 dns_resource_record_unref(a
->mdns_ptr_rr
);
871 void link_address_add_rrs(LinkAddress
*a
, bool force_remove
) {
876 if (a
->family
== AF_INET
) {
879 link_address_relevant(a
, true) &&
880 a
->link
->llmnr_ipv4_scope
&&
881 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
882 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
884 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
885 a
->link
->manager
->llmnr_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->llmnr_hostname
);
886 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
892 if (!a
->llmnr_address_rr
) {
893 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv4_key
);
894 if (!a
->llmnr_address_rr
) {
899 a
->llmnr_address_rr
->a
.in_addr
= a
->in_addr
.in
;
900 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
903 if (!a
->llmnr_ptr_rr
) {
904 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
908 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
911 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_address_rr
, true);
913 log_warning_errno(r
, "Failed to add A record to LLMNR zone: %m");
915 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_ptr_rr
, false);
917 log_warning_errno(r
, "Failed to add IPv4 PTR record to LLMNR zone: %m");
919 if (a
->llmnr_address_rr
) {
920 if (a
->link
->llmnr_ipv4_scope
)
921 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
922 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
925 if (a
->llmnr_ptr_rr
) {
926 if (a
->link
->llmnr_ipv4_scope
)
927 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
928 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
933 link_address_relevant(a
, true) &&
934 a
->link
->mdns_ipv4_scope
&&
935 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
936 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
937 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
938 a
->link
->manager
->mdns_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->mdns_hostname
);
939 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
945 if (!a
->mdns_address_rr
) {
946 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv4_key
);
947 if (!a
->mdns_address_rr
) {
952 a
->mdns_address_rr
->a
.in_addr
= a
->in_addr
.in
;
953 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
956 if (!a
->mdns_ptr_rr
) {
957 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
961 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
964 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_address_rr
, true);
966 log_warning_errno(r
, "Failed to add A record to MDNS zone: %m");
968 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_ptr_rr
, false);
970 log_warning_errno(r
, "Failed to add IPv4 PTR record to MDNS zone: %m");
972 if (a
->mdns_address_rr
) {
973 if (a
->link
->mdns_ipv4_scope
)
974 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
975 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
978 if (a
->mdns_ptr_rr
) {
979 if (a
->link
->mdns_ipv4_scope
)
980 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
981 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
986 if (a
->family
== AF_INET6
) {
989 link_address_relevant(a
, true) &&
990 a
->link
->llmnr_ipv6_scope
&&
991 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
992 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
994 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
995 a
->link
->manager
->llmnr_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->llmnr_hostname
);
996 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
1002 if (!a
->llmnr_address_rr
) {
1003 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv6_key
);
1004 if (!a
->llmnr_address_rr
) {
1009 a
->llmnr_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
1010 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
1013 if (!a
->llmnr_ptr_rr
) {
1014 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
1018 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
1021 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_address_rr
, true);
1023 log_warning_errno(r
, "Failed to add AAAA record to LLMNR zone: %m");
1025 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_ptr_rr
, false);
1027 log_warning_errno(r
, "Failed to add IPv6 PTR record to LLMNR zone: %m");
1029 if (a
->llmnr_address_rr
) {
1030 if (a
->link
->llmnr_ipv6_scope
)
1031 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
1032 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
1035 if (a
->llmnr_ptr_rr
) {
1036 if (a
->link
->llmnr_ipv6_scope
)
1037 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
1038 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
1042 if (!force_remove
&&
1043 link_address_relevant(a
, true) &&
1044 a
->link
->mdns_ipv6_scope
&&
1045 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
1046 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
1048 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
1049 a
->link
->manager
->mdns_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->mdns_hostname
);
1050 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
1056 if (!a
->mdns_address_rr
) {
1057 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv6_key
);
1058 if (!a
->mdns_address_rr
) {
1063 a
->mdns_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
1064 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
1067 if (!a
->mdns_ptr_rr
) {
1068 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
1072 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
1075 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_address_rr
, true);
1077 log_warning_errno(r
, "Failed to add AAAA record to MDNS zone: %m");
1079 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_ptr_rr
, false);
1081 log_warning_errno(r
, "Failed to add IPv6 PTR record to MDNS zone: %m");
1083 if (a
->mdns_address_rr
) {
1084 if (a
->link
->mdns_ipv6_scope
)
1085 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
1086 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
1089 if (a
->mdns_ptr_rr
) {
1090 if (a
->link
->mdns_ipv6_scope
)
1091 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
1092 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
1100 log_debug_errno(r
, "Failed to update address RRs: %m");
1103 int link_address_update_rtnl(LinkAddress
*a
, sd_netlink_message
*m
) {
1108 r
= sd_rtnl_message_addr_get_flags(m
, &a
->flags
);
1112 sd_rtnl_message_addr_get_scope(m
, &a
->scope
);
1114 link_allocate_scopes(a
->link
);
1115 link_add_rrs(a
->link
, false);
1120 bool link_address_relevant(LinkAddress
*a
, bool local_multicast
) {
1123 if (a
->flags
& (IFA_F_DEPRECATED
|IFA_F_TENTATIVE
))
1126 if (a
->scope
>= (local_multicast
? RT_SCOPE_HOST
: RT_SCOPE_LINK
))
1132 static bool link_needs_save(Link
*l
) {
1135 /* Returns true if any of the settings where set different from the default */
1140 if (l
->llmnr_support
!= RESOLVE_SUPPORT_YES
||
1141 l
->mdns_support
!= RESOLVE_SUPPORT_NO
||
1142 l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
||
1143 l
->dns_over_tls_mode
!= _DNS_OVER_TLS_MODE_INVALID
)
1146 if (l
->dns_servers
||
1150 if (!set_isempty(l
->dnssec_negative_trust_anchors
))
1153 if (l
->default_route
>= 0)
1159 int link_save_user(Link
*l
) {
1160 _cleanup_free_
char *temp_path
= NULL
;
1161 _cleanup_fclose_
FILE *f
= NULL
;
1166 assert(l
->state_file
);
1168 if (!link_needs_save(l
)) {
1169 (void) unlink(l
->state_file
);
1173 r
= mkdir_parents(l
->state_file
, 0700);
1177 r
= fopen_temporary(l
->state_file
, &f
, &temp_path
);
1181 (void) fchmod(fileno(f
), 0644);
1183 fputs("# This is private data. Do not parse.\n", f
);
1185 v
= resolve_support_to_string(l
->llmnr_support
);
1187 fprintf(f
, "LLMNR=%s\n", v
);
1189 v
= resolve_support_to_string(l
->mdns_support
);
1191 fprintf(f
, "MDNS=%s\n", v
);
1193 v
= dnssec_mode_to_string(l
->dnssec_mode
);
1195 fprintf(f
, "DNSSEC=%s\n", v
);
1197 if (l
->default_route
>= 0)
1198 fprintf(f
, "DEFAULT_ROUTE=%s\n", yes_no(l
->default_route
));
1200 if (l
->dns_servers
) {
1203 fputs("SERVERS=", f
);
1204 LIST_FOREACH(servers
, server
, l
->dns_servers
) {
1206 if (server
!= l
->dns_servers
)
1209 v
= dns_server_string(server
);
1220 if (l
->search_domains
) {
1221 DnsSearchDomain
*domain
;
1223 fputs("DOMAINS=", f
);
1224 LIST_FOREACH(domains
, domain
, l
->search_domains
) {
1226 if (domain
!= l
->search_domains
)
1229 if (domain
->route_only
)
1232 fputs(DNS_SEARCH_DOMAIN_NAME(domain
), f
);
1237 if (!set_isempty(l
->dnssec_negative_trust_anchors
)) {
1243 SET_FOREACH(nta
, l
->dnssec_negative_trust_anchors
, i
) {
1254 r
= fflush_and_check(f
);
1258 if (rename(temp_path
, l
->state_file
) < 0) {
1266 (void) unlink(l
->state_file
);
1269 (void) unlink(temp_path
);
1271 return log_error_errno(r
, "Failed to save link data %s: %m", l
->state_file
);
1274 int link_load_user(Link
*l
) {
1282 *default_route
= NULL
;
1289 assert(l
->state_file
);
1291 /* Try to load only a single time */
1297 return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */
1299 r
= parse_env_file(NULL
, l
->state_file
,
1303 "SERVERS", &servers
,
1304 "DOMAINS", &domains
,
1306 "DEFAULT_ROUTE", &default_route
);
1312 link_flush_settings(l
);
1314 /* If we can't recognize the LLMNR or MDNS setting we don't override the default */
1315 s
= resolve_support_from_string(llmnr
);
1317 l
->llmnr_support
= s
;
1319 s
= resolve_support_from_string(mdns
);
1321 l
->mdns_support
= s
;
1323 r
= parse_boolean(default_route
);
1325 l
->default_route
= r
;
1327 /* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
1328 l
->dnssec_mode
= dnssec_mode_from_string(dnssec
);
1330 for (p
= servers
;;) {
1331 _cleanup_free_
char *word
= NULL
;
1333 r
= extract_first_word(&p
, &word
, NULL
, 0);
1339 r
= link_update_dns_server_one(l
, word
);
1341 log_debug_errno(r
, "Failed to load DNS server '%s', ignoring: %m", word
);
1346 for (p
= domains
;;) {
1347 _cleanup_free_
char *word
= NULL
;
1351 r
= extract_first_word(&p
, &word
, NULL
, 0);
1357 is_route
= word
[0] == '~';
1358 n
= is_route
? word
+ 1 : word
;
1360 r
= link_update_search_domain_one(l
, n
, is_route
);
1362 log_debug_errno(r
, "Failed to load search domain '%s', ignoring: %m", word
);
1368 _cleanup_set_free_free_ Set
*ns
= NULL
;
1370 ns
= set_new(&dns_name_hash_ops
);
1376 r
= set_put_strsplit(ns
, ntas
, NULL
, 0);
1380 l
->dnssec_negative_trust_anchors
= TAKE_PTR(ns
);
1386 return log_error_errno(r
, "Failed to load link data %s: %m", l
->state_file
);
1389 void link_remove_user(Link
*l
) {
1391 assert(l
->state_file
);
1393 (void) unlink(l
->state_file
);