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"
20 int link_new(Manager
*m
, Link
**ret
, int ifindex
) {
21 _cleanup_(link_freep
) Link
*l
= NULL
;
27 r
= hashmap_ensure_allocated(&m
->links
, NULL
);
36 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
37 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
38 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
39 l
->dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
;
40 l
->operstate
= IF_OPER_UNKNOWN
;
42 if (asprintf(&l
->state_file
, "/run/systemd/resolve/netif/%i", ifindex
) < 0)
45 r
= hashmap_put(m
->links
, INT_TO_PTR(ifindex
), l
);
58 void link_flush_settings(Link
*l
) {
61 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
62 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
63 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
64 l
->dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
;
66 dns_server_unlink_all(l
->dns_servers
);
67 dns_search_domain_unlink_all(l
->search_domains
);
69 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
72 Link
*link_free(Link
*l
) {
76 /* Send goodbye messages. */
77 dns_scope_announce(l
->mdns_ipv4_scope
, true);
78 dns_scope_announce(l
->mdns_ipv6_scope
, true);
80 link_flush_settings(l
);
83 (void) link_address_free(l
->addresses
);
86 hashmap_remove(l
->manager
->links
, INT_TO_PTR(l
->ifindex
));
88 dns_scope_free(l
->unicast_scope
);
89 dns_scope_free(l
->llmnr_ipv4_scope
);
90 dns_scope_free(l
->llmnr_ipv6_scope
);
91 dns_scope_free(l
->mdns_ipv4_scope
);
92 dns_scope_free(l
->mdns_ipv6_scope
);
99 void link_allocate_scopes(Link
*l
) {
100 bool unicast_relevant
;
105 /* If a link that used to be relevant is no longer, or a link that did not use to be relevant now becomes
106 * relevant, let's reinit the learnt global DNS server information, since we might talk to different servers
107 * now, even if they have the same addresses as before. */
109 unicast_relevant
= link_relevant(l
, AF_UNSPEC
, false);
110 if (unicast_relevant
!= l
->unicast_relevant
) {
111 l
->unicast_relevant
= unicast_relevant
;
113 dns_server_reset_features_all(l
->manager
->fallback_dns_servers
);
114 dns_server_reset_features_all(l
->manager
->dns_servers
);
116 /* Also, flush the global unicast scope, to deal with split horizon setups, where talking through one
117 * interface reveals different DNS zones than through others. */
118 if (l
->manager
->unicast_scope
)
119 dns_cache_flush(&l
->manager
->unicast_scope
->cache
);
122 /* And now, allocate all scopes that makes sense now if we didn't have them yet, and drop those which we don't
125 if (unicast_relevant
&& l
->dns_servers
) {
126 if (!l
->unicast_scope
) {
127 dns_server_reset_features_all(l
->dns_servers
);
129 r
= dns_scope_new(l
->manager
, &l
->unicast_scope
, l
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
131 log_warning_errno(r
, "Failed to allocate DNS scope: %m");
134 l
->unicast_scope
= dns_scope_free(l
->unicast_scope
);
136 if (link_relevant(l
, AF_INET
, true) &&
137 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
138 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
139 if (!l
->llmnr_ipv4_scope
) {
140 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv4_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET
);
142 log_warning_errno(r
, "Failed to allocate LLMNR IPv4 scope: %m");
145 l
->llmnr_ipv4_scope
= dns_scope_free(l
->llmnr_ipv4_scope
);
147 if (link_relevant(l
, AF_INET6
, true) &&
148 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
149 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
150 socket_ipv6_is_supported()) {
151 if (!l
->llmnr_ipv6_scope
) {
152 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv6_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET6
);
154 log_warning_errno(r
, "Failed to allocate LLMNR IPv6 scope: %m");
157 l
->llmnr_ipv6_scope
= dns_scope_free(l
->llmnr_ipv6_scope
);
159 if (link_relevant(l
, AF_INET
, true) &&
160 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
161 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
162 if (!l
->mdns_ipv4_scope
) {
163 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv4_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET
);
165 log_warning_errno(r
, "Failed to allocate mDNS IPv4 scope: %m");
168 l
->mdns_ipv4_scope
= dns_scope_free(l
->mdns_ipv4_scope
);
170 if (link_relevant(l
, AF_INET6
, true) &&
171 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
172 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
173 if (!l
->mdns_ipv6_scope
) {
174 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv6_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET6
);
176 log_warning_errno(r
, "Failed to allocate mDNS IPv6 scope: %m");
179 l
->mdns_ipv6_scope
= dns_scope_free(l
->mdns_ipv6_scope
);
182 void link_add_rrs(Link
*l
, bool force_remove
) {
186 LIST_FOREACH(addresses
, a
, l
->addresses
)
187 link_address_add_rrs(a
, force_remove
);
190 l
->mdns_support
== RESOLVE_SUPPORT_YES
&&
191 l
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
193 if (l
->mdns_ipv4_scope
) {
194 r
= dns_scope_add_dnssd_services(l
->mdns_ipv4_scope
);
196 log_warning_errno(r
, "Failed to add IPv4 DNS-SD services: %m");
199 if (l
->mdns_ipv6_scope
) {
200 r
= dns_scope_add_dnssd_services(l
->mdns_ipv6_scope
);
202 log_warning_errno(r
, "Failed to add IPv6 DNS-SD services: %m");
207 if (l
->mdns_ipv4_scope
) {
208 r
= dns_scope_remove_dnssd_services(l
->mdns_ipv4_scope
);
210 log_warning_errno(r
, "Failed to remove IPv4 DNS-SD services: %m");
213 if (l
->mdns_ipv6_scope
) {
214 r
= dns_scope_remove_dnssd_services(l
->mdns_ipv6_scope
);
216 log_warning_errno(r
, "Failed to remove IPv6 DNS-SD services: %m");
221 int link_process_rtnl(Link
*l
, sd_netlink_message
*m
) {
222 const char *n
= NULL
;
228 r
= sd_rtnl_message_link_get_flags(m
, &l
->flags
);
232 (void) sd_netlink_message_read_u32(m
, IFLA_MTU
, &l
->mtu
);
233 (void) sd_netlink_message_read_u8(m
, IFLA_OPERSTATE
, &l
->operstate
);
235 if (sd_netlink_message_read_string(m
, IFLA_IFNAME
, &n
) >= 0) {
236 strncpy(l
->name
, n
, sizeof(l
->name
)-1);
237 char_array_0(l
->name
);
240 link_allocate_scopes(l
);
241 link_add_rrs(l
, false);
246 static int link_update_dns_server_one(Link
*l
, const char *name
) {
247 union in_addr_union a
;
254 r
= in_addr_from_string_auto(name
, &family
, &a
);
258 s
= dns_server_find(l
->dns_servers
, family
, &a
, 0);
260 dns_server_move_back_and_unmark(s
);
264 return dns_server_new(l
->manager
, NULL
, DNS_SERVER_LINK
, l
, family
, &a
, 0);
267 static int link_update_dns_servers(Link
*l
) {
268 _cleanup_strv_free_
char **nameservers
= NULL
;
274 r
= sd_network_link_get_dns(l
->ifindex
, &nameservers
);
282 dns_server_mark_all(l
->dns_servers
);
284 STRV_FOREACH(nameserver
, nameservers
) {
285 r
= link_update_dns_server_one(l
, *nameserver
);
290 dns_server_unlink_marked(l
->dns_servers
);
294 dns_server_unlink_all(l
->dns_servers
);
298 static int link_update_llmnr_support(Link
*l
) {
299 _cleanup_free_
char *b
= NULL
;
304 r
= sd_network_link_get_llmnr(l
->ifindex
, &b
);
312 l
->llmnr_support
= resolve_support_from_string(b
);
313 if (l
->llmnr_support
< 0) {
321 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
325 static int link_update_mdns_support(Link
*l
) {
326 _cleanup_free_
char *b
= NULL
;
331 r
= sd_network_link_get_mdns(l
->ifindex
, &b
);
339 l
->mdns_support
= resolve_support_from_string(b
);
340 if (l
->mdns_support
< 0) {
348 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
352 void link_set_dns_over_tls_mode(Link
*l
, DnsOverTlsMode mode
) {
356 #if ! ENABLE_DNS_OVER_TLS
357 if (mode
!= DNS_OVER_TLS_NO
)
358 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.");
362 l
->dns_over_tls_mode
= mode
;
365 static int link_update_dns_over_tls_mode(Link
*l
) {
366 _cleanup_free_
char *b
= NULL
;
371 r
= sd_network_link_get_dns_over_tls(l
->ifindex
, &b
);
379 l
->dns_over_tls_mode
= dns_over_tls_mode_from_string(b
);
380 if (l
->dns_over_tls_mode
< 0) {
388 l
->dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
;
392 void link_set_dnssec_mode(Link
*l
, DnssecMode mode
) {
397 if (IN_SET(mode
, DNSSEC_YES
, DNSSEC_ALLOW_DOWNGRADE
))
398 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.");
402 if (l
->dnssec_mode
== mode
)
405 if ((l
->dnssec_mode
== _DNSSEC_MODE_INVALID
) ||
406 (l
->dnssec_mode
== DNSSEC_NO
&& mode
!= DNSSEC_NO
) ||
407 (l
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
&& mode
== DNSSEC_YES
)) {
409 /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
410 * allow-downgrade mode to full DNSSEC mode, flush it too. */
411 if (l
->unicast_scope
)
412 dns_cache_flush(&l
->unicast_scope
->cache
);
415 l
->dnssec_mode
= mode
;
418 static int link_update_dnssec_mode(Link
*l
) {
419 _cleanup_free_
char *m
= NULL
;
425 r
= sd_network_link_get_dnssec(l
->ifindex
, &m
);
433 mode
= dnssec_mode_from_string(m
);
439 link_set_dnssec_mode(l
, mode
);
444 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
448 static int link_update_dnssec_negative_trust_anchors(Link
*l
) {
449 _cleanup_strv_free_
char **ntas
= NULL
;
450 _cleanup_set_free_free_ Set
*ns
= NULL
;
455 r
= sd_network_link_get_dnssec_negative_trust_anchors(l
->ifindex
, &ntas
);
463 ns
= set_new(&dns_name_hash_ops
);
467 r
= set_put_strdupv(ns
, ntas
);
471 set_free_free(l
->dnssec_negative_trust_anchors
);
472 l
->dnssec_negative_trust_anchors
= TAKE_PTR(ns
);
477 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
481 static int link_update_search_domain_one(Link
*l
, const char *name
, bool route_only
) {
488 r
= dns_search_domain_find(l
->search_domains
, name
, &d
);
492 dns_search_domain_move_back_and_unmark(d
);
494 r
= dns_search_domain_new(l
->manager
, &d
, DNS_SEARCH_DOMAIN_LINK
, l
, name
);
499 d
->route_only
= route_only
;
503 static int link_update_search_domains(Link
*l
) {
504 _cleanup_strv_free_
char **sdomains
= NULL
, **rdomains
= NULL
;
510 r
= sd_network_link_get_search_domains(l
->ifindex
, &sdomains
);
511 if (r
< 0 && r
!= -ENODATA
)
514 q
= sd_network_link_get_route_domains(l
->ifindex
, &rdomains
);
515 if (q
< 0 && q
!= -ENODATA
) {
520 if (r
== -ENODATA
&& q
== -ENODATA
) {
521 /* networkd knows nothing about this interface, and that's fine. */
526 dns_search_domain_mark_all(l
->search_domains
);
528 STRV_FOREACH(i
, sdomains
) {
529 r
= link_update_search_domain_one(l
, *i
, false);
534 STRV_FOREACH(i
, rdomains
) {
535 r
= link_update_search_domain_one(l
, *i
, true);
540 dns_search_domain_unlink_marked(l
->search_domains
);
544 dns_search_domain_unlink_all(l
->search_domains
);
548 static int link_is_managed(Link
*l
) {
549 _cleanup_free_
char *state
= NULL
;
554 r
= sd_network_link_get_setup_state(l
->ifindex
, &state
);
560 return !STR_IN_SET(state
, "pending", "unmanaged");
563 static void link_read_settings(Link
*l
) {
568 /* Read settings from networkd, except when networkd is not managing this interface. */
570 r
= link_is_managed(l
);
572 log_warning_errno(r
, "Failed to determine whether interface %s is managed: %m", l
->name
);
577 /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
579 link_flush_settings(l
);
581 l
->is_managed
= false;
585 l
->is_managed
= true;
587 r
= link_update_dns_servers(l
);
589 log_warning_errno(r
, "Failed to read DNS servers for interface %s, ignoring: %m", l
->name
);
591 r
= link_update_llmnr_support(l
);
593 log_warning_errno(r
, "Failed to read LLMNR support for interface %s, ignoring: %m", l
->name
);
595 r
= link_update_mdns_support(l
);
597 log_warning_errno(r
, "Failed to read mDNS support for interface %s, ignoring: %m", l
->name
);
599 r
= link_update_dns_over_tls_mode(l
);
601 log_warning_errno(r
, "Failed to read DNS-over-TLS mode for interface %s, ignoring: %m", l
->name
);
603 r
= link_update_dnssec_mode(l
);
605 log_warning_errno(r
, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l
->name
);
607 r
= link_update_dnssec_negative_trust_anchors(l
);
609 log_warning_errno(r
, "Failed to read DNSSEC negative trust anchors for interface %s, ignoring: %m", l
->name
);
611 r
= link_update_search_domains(l
);
613 log_warning_errno(r
, "Failed to read search domains for interface %s, ignoring: %m", l
->name
);
616 int link_update(Link
*l
) {
621 link_read_settings(l
);
624 if (l
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
625 r
= manager_llmnr_start(l
->manager
);
630 if (l
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
631 r
= manager_mdns_start(l
->manager
);
636 link_allocate_scopes(l
);
637 link_add_rrs(l
, false);
642 bool link_relevant(Link
*l
, int family
, bool local_multicast
) {
643 _cleanup_free_
char *state
= NULL
;
648 /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
649 * beat, can do multicast and has at least one link-local (or better) IP address.
651 * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
652 * least one routable address. */
654 if (l
->flags
& (IFF_LOOPBACK
|IFF_DORMANT
))
657 if ((l
->flags
& (IFF_UP
|IFF_LOWER_UP
)) != (IFF_UP
|IFF_LOWER_UP
))
660 if (local_multicast
) {
661 if ((l
->flags
& IFF_MULTICAST
) != IFF_MULTICAST
)
665 /* Check kernel operstate
666 * https://www.kernel.org/doc/Documentation/networking/operstates.txt */
667 if (!IN_SET(l
->operstate
, IF_OPER_UNKNOWN
, IF_OPER_UP
))
670 (void) sd_network_link_get_operational_state(l
->ifindex
, &state
);
671 if (state
&& !STR_IN_SET(state
, "unknown", "degraded", "routable"))
674 LIST_FOREACH(addresses
, a
, l
->addresses
)
675 if ((family
== AF_UNSPEC
|| a
->family
== family
) && link_address_relevant(a
, local_multicast
))
681 LinkAddress
*link_find_address(Link
*l
, int family
, const union in_addr_union
*in_addr
) {
686 LIST_FOREACH(addresses
, a
, l
->addresses
)
687 if (a
->family
== family
&& in_addr_equal(family
, &a
->in_addr
, in_addr
))
693 DnsServer
* link_set_dns_server(Link
*l
, DnsServer
*s
) {
696 if (l
->current_dns_server
== s
)
700 log_debug("Switching to DNS server %s for interface %s.", dns_server_string(s
), l
->name
);
702 dns_server_unref(l
->current_dns_server
);
703 l
->current_dns_server
= dns_server_ref(s
);
705 if (l
->unicast_scope
)
706 dns_cache_flush(&l
->unicast_scope
->cache
);
711 DnsServer
*link_get_dns_server(Link
*l
) {
714 if (!l
->current_dns_server
)
715 link_set_dns_server(l
, l
->dns_servers
);
717 return l
->current_dns_server
;
720 void link_next_dns_server(Link
*l
) {
723 if (!l
->current_dns_server
)
726 /* Change to the next one, but make sure to follow the linked
727 * list only if this server is actually still linked. */
728 if (l
->current_dns_server
->linked
&& l
->current_dns_server
->servers_next
) {
729 link_set_dns_server(l
, l
->current_dns_server
->servers_next
);
733 link_set_dns_server(l
, l
->dns_servers
);
736 DnsOverTlsMode
link_get_dns_over_tls_mode(Link
*l
) {
739 if (l
->dns_over_tls_mode
!= _DNS_OVER_TLS_MODE_INVALID
)
740 return l
->dns_over_tls_mode
;
742 return manager_get_dns_over_tls_mode(l
->manager
);
745 DnssecMode
link_get_dnssec_mode(Link
*l
) {
748 if (l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
749 return l
->dnssec_mode
;
751 return manager_get_dnssec_mode(l
->manager
);
754 bool link_dnssec_supported(Link
*l
) {
759 if (link_get_dnssec_mode(l
) == DNSSEC_NO
)
762 server
= link_get_dns_server(l
);
764 return dns_server_dnssec_supported(server
);
769 int link_address_new(Link
*l
, LinkAddress
**ret
, int family
, const union in_addr_union
*in_addr
) {
775 a
= new0(LinkAddress
, 1);
780 a
->in_addr
= *in_addr
;
783 LIST_PREPEND(addresses
, l
->addresses
, a
);
792 LinkAddress
*link_address_free(LinkAddress
*a
) {
797 LIST_REMOVE(addresses
, a
->link
->addresses
, a
);
799 assert(a
->link
->n_addresses
> 0);
800 a
->link
->n_addresses
--;
802 if (a
->llmnr_address_rr
) {
803 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
804 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
805 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
806 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
809 if (a
->llmnr_ptr_rr
) {
810 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
811 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
812 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
813 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
816 if (a
->mdns_address_rr
) {
817 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
818 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
819 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
820 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
823 if (a
->mdns_ptr_rr
) {
824 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
825 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
826 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
827 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
831 dns_resource_record_unref(a
->llmnr_address_rr
);
832 dns_resource_record_unref(a
->llmnr_ptr_rr
);
833 dns_resource_record_unref(a
->mdns_address_rr
);
834 dns_resource_record_unref(a
->mdns_ptr_rr
);
839 void link_address_add_rrs(LinkAddress
*a
, bool force_remove
) {
844 if (a
->family
== AF_INET
) {
847 link_address_relevant(a
, true) &&
848 a
->link
->llmnr_ipv4_scope
&&
849 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
850 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
852 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
853 a
->link
->manager
->llmnr_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->llmnr_hostname
);
854 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
860 if (!a
->llmnr_address_rr
) {
861 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv4_key
);
862 if (!a
->llmnr_address_rr
) {
867 a
->llmnr_address_rr
->a
.in_addr
= a
->in_addr
.in
;
868 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
871 if (!a
->llmnr_ptr_rr
) {
872 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
876 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
879 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_address_rr
, true);
881 log_warning_errno(r
, "Failed to add A record to LLMNR zone: %m");
883 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_ptr_rr
, false);
885 log_warning_errno(r
, "Failed to add IPv4 PTR record to LLMNR zone: %m");
887 if (a
->llmnr_address_rr
) {
888 if (a
->link
->llmnr_ipv4_scope
)
889 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
890 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
893 if (a
->llmnr_ptr_rr
) {
894 if (a
->link
->llmnr_ipv4_scope
)
895 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
896 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
901 link_address_relevant(a
, true) &&
902 a
->link
->mdns_ipv4_scope
&&
903 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
904 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
905 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
906 a
->link
->manager
->mdns_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->mdns_hostname
);
907 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
913 if (!a
->mdns_address_rr
) {
914 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv4_key
);
915 if (!a
->mdns_address_rr
) {
920 a
->mdns_address_rr
->a
.in_addr
= a
->in_addr
.in
;
921 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
924 if (!a
->mdns_ptr_rr
) {
925 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
929 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
932 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_address_rr
, true);
934 log_warning_errno(r
, "Failed to add A record to MDNS zone: %m");
936 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_ptr_rr
, false);
938 log_warning_errno(r
, "Failed to add IPv4 PTR record to MDNS zone: %m");
940 if (a
->mdns_address_rr
) {
941 if (a
->link
->mdns_ipv4_scope
)
942 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
943 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
946 if (a
->mdns_ptr_rr
) {
947 if (a
->link
->mdns_ipv4_scope
)
948 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
949 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
954 if (a
->family
== AF_INET6
) {
957 link_address_relevant(a
, true) &&
958 a
->link
->llmnr_ipv6_scope
&&
959 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
960 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
962 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
963 a
->link
->manager
->llmnr_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->llmnr_hostname
);
964 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
970 if (!a
->llmnr_address_rr
) {
971 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv6_key
);
972 if (!a
->llmnr_address_rr
) {
977 a
->llmnr_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
978 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
981 if (!a
->llmnr_ptr_rr
) {
982 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
986 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
989 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_address_rr
, true);
991 log_warning_errno(r
, "Failed to add AAAA record to LLMNR zone: %m");
993 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_ptr_rr
, false);
995 log_warning_errno(r
, "Failed to add IPv6 PTR record to LLMNR zone: %m");
997 if (a
->llmnr_address_rr
) {
998 if (a
->link
->llmnr_ipv6_scope
)
999 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
1000 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
1003 if (a
->llmnr_ptr_rr
) {
1004 if (a
->link
->llmnr_ipv6_scope
)
1005 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
1006 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
1010 if (!force_remove
&&
1011 link_address_relevant(a
, true) &&
1012 a
->link
->mdns_ipv6_scope
&&
1013 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
1014 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
1016 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
1017 a
->link
->manager
->mdns_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->mdns_hostname
);
1018 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
1024 if (!a
->mdns_address_rr
) {
1025 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv6_key
);
1026 if (!a
->mdns_address_rr
) {
1031 a
->mdns_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
1032 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
1035 if (!a
->mdns_ptr_rr
) {
1036 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
1040 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
1043 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_address_rr
, true);
1045 log_warning_errno(r
, "Failed to add AAAA record to MDNS zone: %m");
1047 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_ptr_rr
, false);
1049 log_warning_errno(r
, "Failed to add IPv6 PTR record to MDNS zone: %m");
1051 if (a
->mdns_address_rr
) {
1052 if (a
->link
->mdns_ipv6_scope
)
1053 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
1054 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
1057 if (a
->mdns_ptr_rr
) {
1058 if (a
->link
->mdns_ipv6_scope
)
1059 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
1060 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
1068 log_debug_errno(r
, "Failed to update address RRs: %m");
1071 int link_address_update_rtnl(LinkAddress
*a
, sd_netlink_message
*m
) {
1076 r
= sd_rtnl_message_addr_get_flags(m
, &a
->flags
);
1080 sd_rtnl_message_addr_get_scope(m
, &a
->scope
);
1082 link_allocate_scopes(a
->link
);
1083 link_add_rrs(a
->link
, false);
1088 bool link_address_relevant(LinkAddress
*a
, bool local_multicast
) {
1091 if (a
->flags
& (IFA_F_DEPRECATED
|IFA_F_TENTATIVE
))
1094 if (a
->scope
>= (local_multicast
? RT_SCOPE_HOST
: RT_SCOPE_LINK
))
1100 static bool link_needs_save(Link
*l
) {
1103 /* Returns true if any of the settings where set different from the default */
1108 if (l
->llmnr_support
!= RESOLVE_SUPPORT_YES
||
1109 l
->mdns_support
!= RESOLVE_SUPPORT_NO
||
1110 l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
1113 if (l
->dns_servers
||
1117 if (!set_isempty(l
->dnssec_negative_trust_anchors
))
1123 int link_save_user(Link
*l
) {
1124 _cleanup_free_
char *temp_path
= NULL
;
1125 _cleanup_fclose_
FILE *f
= NULL
;
1130 assert(l
->state_file
);
1132 if (!link_needs_save(l
)) {
1133 (void) unlink(l
->state_file
);
1137 r
= mkdir_parents(l
->state_file
, 0700);
1141 r
= fopen_temporary(l
->state_file
, &f
, &temp_path
);
1145 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
1146 (void) fchmod(fileno(f
), 0644);
1148 fputs("# This is private data. Do not parse.\n", f
);
1150 v
= resolve_support_to_string(l
->llmnr_support
);
1152 fprintf(f
, "LLMNR=%s\n", v
);
1154 v
= resolve_support_to_string(l
->mdns_support
);
1156 fprintf(f
, "MDNS=%s\n", v
);
1158 v
= dnssec_mode_to_string(l
->dnssec_mode
);
1160 fprintf(f
, "DNSSEC=%s\n", v
);
1162 if (l
->dns_servers
) {
1165 fputs("SERVERS=", f
);
1166 LIST_FOREACH(servers
, server
, l
->dns_servers
) {
1168 if (server
!= l
->dns_servers
)
1171 v
= dns_server_string(server
);
1182 if (l
->search_domains
) {
1183 DnsSearchDomain
*domain
;
1185 fputs("DOMAINS=", f
);
1186 LIST_FOREACH(domains
, domain
, l
->search_domains
) {
1188 if (domain
!= l
->search_domains
)
1191 if (domain
->route_only
)
1194 fputs(DNS_SEARCH_DOMAIN_NAME(domain
), f
);
1199 if (!set_isempty(l
->dnssec_negative_trust_anchors
)) {
1205 SET_FOREACH(nta
, l
->dnssec_negative_trust_anchors
, i
) {
1216 r
= fflush_and_check(f
);
1220 if (rename(temp_path
, l
->state_file
) < 0) {
1228 (void) unlink(l
->state_file
);
1231 (void) unlink(temp_path
);
1233 return log_error_errno(r
, "Failed to save link data %s: %m", l
->state_file
);
1236 int link_load_user(Link
*l
) {
1250 assert(l
->state_file
);
1252 /* Try to load only a single time */
1258 return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */
1260 r
= parse_env_file(NULL
, l
->state_file
,
1264 "SERVERS", &servers
,
1265 "DOMAINS", &domains
,
1272 link_flush_settings(l
);
1274 /* If we can't recognize the LLMNR or MDNS setting we don't override the default */
1275 s
= resolve_support_from_string(llmnr
);
1277 l
->llmnr_support
= s
;
1279 s
= resolve_support_from_string(mdns
);
1281 l
->mdns_support
= s
;
1283 /* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
1284 l
->dnssec_mode
= dnssec_mode_from_string(dnssec
);
1286 for (p
= servers
;;) {
1287 _cleanup_free_
char *word
= NULL
;
1289 r
= extract_first_word(&p
, &word
, NULL
, 0);
1295 r
= link_update_dns_server_one(l
, word
);
1297 log_debug_errno(r
, "Failed to load DNS server '%s', ignoring: %m", word
);
1302 for (p
= domains
;;) {
1303 _cleanup_free_
char *word
= NULL
;
1307 r
= extract_first_word(&p
, &word
, NULL
, 0);
1313 is_route
= word
[0] == '~';
1314 n
= is_route
? word
+ 1 : word
;
1316 r
= link_update_search_domain_one(l
, n
, is_route
);
1318 log_debug_errno(r
, "Failed to load search domain '%s', ignoring: %m", word
);
1324 _cleanup_set_free_free_ Set
*ns
= NULL
;
1326 ns
= set_new(&dns_name_hash_ops
);
1332 r
= set_put_strsplit(ns
, ntas
, NULL
, 0);
1336 l
->dnssec_negative_trust_anchors
= TAKE_PTR(ns
);
1342 return log_error_errno(r
, "Failed to load link data %s: %m", l
->state_file
);
1345 void link_remove_user(Link
*l
) {
1347 assert(l
->state_file
);
1349 (void) unlink(l
->state_file
);