2 This file is part of systemd.
4 Copyright 2014 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "sd-network.h"
24 #include "alloc-util.h"
29 #include "parse-util.h"
30 #include "resolved-link.h"
31 #include "resolved-llmnr.h"
32 #include "resolved-mdns.h"
33 #include "string-util.h"
36 int link_new(Manager
*m
, Link
**ret
, int ifindex
) {
37 _cleanup_(link_freep
) Link
*l
= NULL
;
43 r
= hashmap_ensure_allocated(&m
->links
, NULL
);
52 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
53 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
54 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
55 l
->operstate
= IF_OPER_UNKNOWN
;
57 if (asprintf(&l
->state_file
, "/run/systemd/resolve/netif/%i", ifindex
) < 0)
60 r
= hashmap_put(m
->links
, INT_TO_PTR(ifindex
), l
);
73 void link_flush_settings(Link
*l
) {
76 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
77 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
78 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
80 dns_server_unlink_all(l
->dns_servers
);
81 dns_search_domain_unlink_all(l
->search_domains
);
83 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
86 Link
*link_free(Link
*l
) {
90 /* Send goodbye messages. */
91 dns_scope_announce(l
->mdns_ipv4_scope
, true);
92 dns_scope_announce(l
->mdns_ipv6_scope
, true);
94 link_flush_settings(l
);
97 (void) link_address_free(l
->addresses
);
100 hashmap_remove(l
->manager
->links
, INT_TO_PTR(l
->ifindex
));
102 dns_scope_free(l
->unicast_scope
);
103 dns_scope_free(l
->llmnr_ipv4_scope
);
104 dns_scope_free(l
->llmnr_ipv6_scope
);
105 dns_scope_free(l
->mdns_ipv4_scope
);
106 dns_scope_free(l
->mdns_ipv6_scope
);
113 void link_allocate_scopes(Link
*l
) {
114 bool unicast_relevant
;
119 /* If a link that used to be relevant is no longer, or a link that did not use to be relevant now becomes
120 * relevant, let's reinit the learnt global DNS server information, since we might talk to different servers
121 * now, even if they have the same addresses as before. */
123 unicast_relevant
= link_relevant(l
, AF_UNSPEC
, false);
124 if (unicast_relevant
!= l
->unicast_relevant
) {
125 l
->unicast_relevant
= unicast_relevant
;
127 dns_server_reset_features_all(l
->manager
->fallback_dns_servers
);
128 dns_server_reset_features_all(l
->manager
->dns_servers
);
131 /* And now, allocate all scopes that makes sense now if we didn't have them yet, and drop those which we don't
134 if (unicast_relevant
&& l
->dns_servers
) {
135 if (!l
->unicast_scope
) {
136 dns_server_reset_features_all(l
->dns_servers
);
138 r
= dns_scope_new(l
->manager
, &l
->unicast_scope
, l
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
140 log_warning_errno(r
, "Failed to allocate DNS scope: %m");
143 l
->unicast_scope
= dns_scope_free(l
->unicast_scope
);
145 if (link_relevant(l
, AF_INET
, true) &&
146 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
147 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
148 if (!l
->llmnr_ipv4_scope
) {
149 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv4_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET
);
151 log_warning_errno(r
, "Failed to allocate LLMNR IPv4 scope: %m");
154 l
->llmnr_ipv4_scope
= dns_scope_free(l
->llmnr_ipv4_scope
);
156 if (link_relevant(l
, AF_INET6
, true) &&
157 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
158 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
159 socket_ipv6_is_supported()) {
160 if (!l
->llmnr_ipv6_scope
) {
161 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv6_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET6
);
163 log_warning_errno(r
, "Failed to allocate LLMNR IPv6 scope: %m");
166 l
->llmnr_ipv6_scope
= dns_scope_free(l
->llmnr_ipv6_scope
);
168 if (link_relevant(l
, AF_INET
, true) &&
169 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
170 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
171 if (!l
->mdns_ipv4_scope
) {
172 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv4_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET
);
174 log_warning_errno(r
, "Failed to allocate mDNS IPv4 scope: %m");
177 l
->mdns_ipv4_scope
= dns_scope_free(l
->mdns_ipv4_scope
);
179 if (link_relevant(l
, AF_INET6
, true) &&
180 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
181 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
182 if (!l
->mdns_ipv6_scope
) {
183 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv6_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET6
);
185 log_warning_errno(r
, "Failed to allocate mDNS IPv6 scope: %m");
188 l
->mdns_ipv6_scope
= dns_scope_free(l
->mdns_ipv6_scope
);
191 void link_add_rrs(Link
*l
, bool force_remove
) {
194 LIST_FOREACH(addresses
, a
, l
->addresses
)
195 link_address_add_rrs(a
, force_remove
);
198 int link_process_rtnl(Link
*l
, sd_netlink_message
*m
) {
199 const char *n
= NULL
;
205 r
= sd_rtnl_message_link_get_flags(m
, &l
->flags
);
209 (void) sd_netlink_message_read_u32(m
, IFLA_MTU
, &l
->mtu
);
210 (void) sd_netlink_message_read_u8(m
, IFLA_OPERSTATE
, &l
->operstate
);
212 if (sd_netlink_message_read_string(m
, IFLA_IFNAME
, &n
) >= 0) {
213 strncpy(l
->name
, n
, sizeof(l
->name
)-1);
214 char_array_0(l
->name
);
217 link_allocate_scopes(l
);
218 link_add_rrs(l
, false);
223 static int link_update_dns_server_one(Link
*l
, const char *name
) {
224 union in_addr_union a
;
231 r
= in_addr_from_string_auto(name
, &family
, &a
);
235 s
= dns_server_find(l
->dns_servers
, family
, &a
, 0);
237 dns_server_move_back_and_unmark(s
);
241 return dns_server_new(l
->manager
, NULL
, DNS_SERVER_LINK
, l
, family
, &a
, 0);
244 static int link_update_dns_servers(Link
*l
) {
245 _cleanup_strv_free_
char **nameservers
= NULL
;
251 r
= sd_network_link_get_dns(l
->ifindex
, &nameservers
);
259 dns_server_mark_all(l
->dns_servers
);
261 STRV_FOREACH(nameserver
, nameservers
) {
262 r
= link_update_dns_server_one(l
, *nameserver
);
267 dns_server_unlink_marked(l
->dns_servers
);
271 dns_server_unlink_all(l
->dns_servers
);
275 static int link_update_llmnr_support(Link
*l
) {
276 _cleanup_free_
char *b
= NULL
;
281 r
= sd_network_link_get_llmnr(l
->ifindex
, &b
);
289 l
->llmnr_support
= resolve_support_from_string(b
);
290 if (l
->llmnr_support
< 0) {
298 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
302 static int link_update_mdns_support(Link
*l
) {
303 _cleanup_free_
char *b
= NULL
;
308 r
= sd_network_link_get_mdns(l
->ifindex
, &b
);
316 l
->mdns_support
= resolve_support_from_string(b
);
317 if (l
->mdns_support
< 0) {
325 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
329 void link_set_dnssec_mode(Link
*l
, DnssecMode mode
) {
334 if (IN_SET(mode
, DNSSEC_YES
, DNSSEC_ALLOW_DOWNGRADE
))
335 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.");
339 if (l
->dnssec_mode
== mode
)
342 if ((l
->dnssec_mode
== _DNSSEC_MODE_INVALID
) ||
343 (l
->dnssec_mode
== DNSSEC_NO
&& mode
!= DNSSEC_NO
) ||
344 (l
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
&& mode
== DNSSEC_YES
)) {
346 /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
347 * allow-downgrade mode to full DNSSEC mode, flush it too. */
348 if (l
->unicast_scope
)
349 dns_cache_flush(&l
->unicast_scope
->cache
);
352 l
->dnssec_mode
= mode
;
355 static int link_update_dnssec_mode(Link
*l
) {
356 _cleanup_free_
char *m
= NULL
;
362 r
= sd_network_link_get_dnssec(l
->ifindex
, &m
);
370 mode
= dnssec_mode_from_string(m
);
376 link_set_dnssec_mode(l
, mode
);
381 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
385 static int link_update_dnssec_negative_trust_anchors(Link
*l
) {
386 _cleanup_strv_free_
char **ntas
= NULL
;
387 _cleanup_set_free_free_ Set
*ns
= NULL
;
392 r
= sd_network_link_get_dnssec_negative_trust_anchors(l
->ifindex
, &ntas
);
400 ns
= set_new(&dns_name_hash_ops
);
404 r
= set_put_strdupv(ns
, ntas
);
408 set_free_free(l
->dnssec_negative_trust_anchors
);
409 l
->dnssec_negative_trust_anchors
= ns
;
415 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
419 static int link_update_search_domain_one(Link
*l
, const char *name
, bool route_only
) {
426 r
= dns_search_domain_find(l
->search_domains
, name
, &d
);
430 dns_search_domain_move_back_and_unmark(d
);
432 r
= dns_search_domain_new(l
->manager
, &d
, DNS_SEARCH_DOMAIN_LINK
, l
, name
);
437 d
->route_only
= route_only
;
441 static int link_update_search_domains(Link
*l
) {
442 _cleanup_strv_free_
char **sdomains
= NULL
, **rdomains
= NULL
;
448 r
= sd_network_link_get_search_domains(l
->ifindex
, &sdomains
);
449 if (r
< 0 && r
!= -ENODATA
)
452 q
= sd_network_link_get_route_domains(l
->ifindex
, &rdomains
);
453 if (q
< 0 && q
!= -ENODATA
) {
458 if (r
== -ENODATA
&& q
== -ENODATA
) {
459 /* networkd knows nothing about this interface, and that's fine. */
464 dns_search_domain_mark_all(l
->search_domains
);
466 STRV_FOREACH(i
, sdomains
) {
467 r
= link_update_search_domain_one(l
, *i
, false);
472 STRV_FOREACH(i
, rdomains
) {
473 r
= link_update_search_domain_one(l
, *i
, true);
478 dns_search_domain_unlink_marked(l
->search_domains
);
482 dns_search_domain_unlink_all(l
->search_domains
);
486 static int link_is_managed(Link
*l
) {
487 _cleanup_free_
char *state
= NULL
;
492 r
= sd_network_link_get_setup_state(l
->ifindex
, &state
);
498 return !STR_IN_SET(state
, "pending", "unmanaged");
501 static void link_read_settings(Link
*l
) {
506 /* Read settings from networkd, except when networkd is not managing this interface. */
508 r
= link_is_managed(l
);
510 log_warning_errno(r
, "Failed to determine whether interface %s is managed: %m", l
->name
);
515 /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
517 link_flush_settings(l
);
519 l
->is_managed
= false;
523 l
->is_managed
= true;
525 r
= link_update_dns_servers(l
);
527 log_warning_errno(r
, "Failed to read DNS servers for interface %s, ignoring: %m", l
->name
);
529 r
= link_update_llmnr_support(l
);
531 log_warning_errno(r
, "Failed to read LLMNR support for interface %s, ignoring: %m", l
->name
);
533 r
= link_update_mdns_support(l
);
535 log_warning_errno(r
, "Failed to read mDNS support for interface %s, ignoring: %m", l
->name
);
537 r
= link_update_dnssec_mode(l
);
539 log_warning_errno(r
, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l
->name
);
541 r
= link_update_dnssec_negative_trust_anchors(l
);
543 log_warning_errno(r
, "Failed to read DNSSEC negative trust anchors for interface %s, ignoring: %m", l
->name
);
545 r
= link_update_search_domains(l
);
547 log_warning_errno(r
, "Failed to read search domains for interface %s, ignoring: %m", l
->name
);
550 int link_update(Link
*l
) {
555 link_read_settings(l
);
558 if (l
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
559 r
= manager_llmnr_start(l
->manager
);
564 if (l
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
565 r
= manager_mdns_start(l
->manager
);
570 link_allocate_scopes(l
);
571 link_add_rrs(l
, false);
576 bool link_relevant(Link
*l
, int family
, bool local_multicast
) {
577 _cleanup_free_
char *state
= NULL
;
582 /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
583 * beat, can do multicast and has at least one link-local (or better) IP address.
585 * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
586 * least one routable address. */
588 if (l
->flags
& (IFF_LOOPBACK
|IFF_DORMANT
))
591 if ((l
->flags
& (IFF_UP
|IFF_LOWER_UP
)) != (IFF_UP
|IFF_LOWER_UP
))
594 if (local_multicast
) {
595 if ((l
->flags
& IFF_MULTICAST
) != IFF_MULTICAST
)
599 /* Check kernel operstate
600 * https://www.kernel.org/doc/Documentation/networking/operstates.txt */
601 if (!IN_SET(l
->operstate
, IF_OPER_UNKNOWN
, IF_OPER_UP
))
604 (void) sd_network_link_get_operational_state(l
->ifindex
, &state
);
605 if (state
&& !STR_IN_SET(state
, "unknown", "degraded", "routable"))
608 LIST_FOREACH(addresses
, a
, l
->addresses
)
609 if ((family
== AF_UNSPEC
|| a
->family
== family
) && link_address_relevant(a
, local_multicast
))
615 LinkAddress
*link_find_address(Link
*l
, int family
, const union in_addr_union
*in_addr
) {
620 LIST_FOREACH(addresses
, a
, l
->addresses
)
621 if (a
->family
== family
&& in_addr_equal(family
, &a
->in_addr
, in_addr
))
627 DnsServer
* link_set_dns_server(Link
*l
, DnsServer
*s
) {
630 if (l
->current_dns_server
== s
)
634 log_debug("Switching to DNS server %s for interface %s.", dns_server_string(s
), l
->name
);
636 dns_server_unref(l
->current_dns_server
);
637 l
->current_dns_server
= dns_server_ref(s
);
639 if (l
->unicast_scope
)
640 dns_cache_flush(&l
->unicast_scope
->cache
);
645 DnsServer
*link_get_dns_server(Link
*l
) {
648 if (!l
->current_dns_server
)
649 link_set_dns_server(l
, l
->dns_servers
);
651 return l
->current_dns_server
;
654 void link_next_dns_server(Link
*l
) {
657 if (!l
->current_dns_server
)
660 /* Change to the next one, but make sure to follow the linked
661 * list only if this server is actually still linked. */
662 if (l
->current_dns_server
->linked
&& l
->current_dns_server
->servers_next
) {
663 link_set_dns_server(l
, l
->current_dns_server
->servers_next
);
667 link_set_dns_server(l
, l
->dns_servers
);
670 DnssecMode
link_get_dnssec_mode(Link
*l
) {
673 if (l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
674 return l
->dnssec_mode
;
676 return manager_get_dnssec_mode(l
->manager
);
679 bool link_dnssec_supported(Link
*l
) {
684 if (link_get_dnssec_mode(l
) == DNSSEC_NO
)
687 server
= link_get_dns_server(l
);
689 return dns_server_dnssec_supported(server
);
694 int link_address_new(Link
*l
, LinkAddress
**ret
, int family
, const union in_addr_union
*in_addr
) {
700 a
= new0(LinkAddress
, 1);
705 a
->in_addr
= *in_addr
;
708 LIST_PREPEND(addresses
, l
->addresses
, a
);
717 LinkAddress
*link_address_free(LinkAddress
*a
) {
722 LIST_REMOVE(addresses
, a
->link
->addresses
, a
);
724 assert(a
->link
->n_addresses
> 0);
725 a
->link
->n_addresses
--;
727 if (a
->llmnr_address_rr
) {
728 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
729 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
730 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
731 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
734 if (a
->llmnr_ptr_rr
) {
735 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
736 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
737 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
738 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
741 if (a
->mdns_address_rr
) {
742 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
743 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
744 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
745 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
748 if (a
->mdns_ptr_rr
) {
749 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
750 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
751 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
752 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
756 dns_resource_record_unref(a
->llmnr_address_rr
);
757 dns_resource_record_unref(a
->llmnr_ptr_rr
);
758 dns_resource_record_unref(a
->mdns_address_rr
);
759 dns_resource_record_unref(a
->mdns_ptr_rr
);
764 void link_address_add_rrs(LinkAddress
*a
, bool force_remove
) {
769 if (a
->family
== AF_INET
) {
772 link_address_relevant(a
, true) &&
773 a
->link
->llmnr_ipv4_scope
&&
774 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
775 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
777 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
778 a
->link
->manager
->llmnr_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->llmnr_hostname
);
779 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
785 if (!a
->llmnr_address_rr
) {
786 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv4_key
);
787 if (!a
->llmnr_address_rr
) {
792 a
->llmnr_address_rr
->a
.in_addr
= a
->in_addr
.in
;
793 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
796 if (!a
->llmnr_ptr_rr
) {
797 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
801 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
804 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_address_rr
, true);
806 log_warning_errno(r
, "Failed to add A record to LLMNR zone: %m");
808 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_ptr_rr
, false);
810 log_warning_errno(r
, "Failed to add IPv4 PTR record to LLMNR zone: %m");
812 if (a
->llmnr_address_rr
) {
813 if (a
->link
->llmnr_ipv4_scope
)
814 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
815 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
818 if (a
->llmnr_ptr_rr
) {
819 if (a
->link
->llmnr_ipv4_scope
)
820 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
821 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
826 link_address_relevant(a
, true) &&
827 a
->link
->mdns_ipv4_scope
&&
828 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
829 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
830 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
831 a
->link
->manager
->mdns_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->mdns_hostname
);
832 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
838 if (!a
->mdns_address_rr
) {
839 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv4_key
);
840 if (!a
->mdns_address_rr
) {
845 a
->mdns_address_rr
->a
.in_addr
= a
->in_addr
.in
;
846 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
849 if (!a
->mdns_ptr_rr
) {
850 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
854 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
857 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_address_rr
, true);
859 log_warning_errno(r
, "Failed to add A record to MDNS zone: %m");
861 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_ptr_rr
, false);
863 log_warning_errno(r
, "Failed to add IPv4 PTR record to MDNS zone: %m");
865 if (a
->mdns_address_rr
) {
866 if (a
->link
->mdns_ipv4_scope
)
867 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
868 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
871 if (a
->mdns_ptr_rr
) {
872 if (a
->link
->mdns_ipv4_scope
)
873 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
874 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
879 if (a
->family
== AF_INET6
) {
882 link_address_relevant(a
, true) &&
883 a
->link
->llmnr_ipv6_scope
&&
884 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
885 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
887 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
888 a
->link
->manager
->llmnr_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->llmnr_hostname
);
889 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
895 if (!a
->llmnr_address_rr
) {
896 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv6_key
);
897 if (!a
->llmnr_address_rr
) {
902 a
->llmnr_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
903 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
906 if (!a
->llmnr_ptr_rr
) {
907 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
911 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
914 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_address_rr
, true);
916 log_warning_errno(r
, "Failed to add AAAA record to LLMNR zone: %m");
918 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_ptr_rr
, false);
920 log_warning_errno(r
, "Failed to add IPv6 PTR record to LLMNR zone: %m");
922 if (a
->llmnr_address_rr
) {
923 if (a
->link
->llmnr_ipv6_scope
)
924 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
925 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
928 if (a
->llmnr_ptr_rr
) {
929 if (a
->link
->llmnr_ipv6_scope
)
930 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
931 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
936 link_address_relevant(a
, true) &&
937 a
->link
->mdns_ipv6_scope
&&
938 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
939 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
941 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
942 a
->link
->manager
->mdns_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->mdns_hostname
);
943 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
949 if (!a
->mdns_address_rr
) {
950 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv6_key
);
951 if (!a
->mdns_address_rr
) {
956 a
->mdns_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
957 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
960 if (!a
->mdns_ptr_rr
) {
961 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
965 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
968 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_address_rr
, true);
970 log_warning_errno(r
, "Failed to add AAAA record to MDNS zone: %m");
972 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_ptr_rr
, false);
974 log_warning_errno(r
, "Failed to add IPv6 PTR record to MDNS zone: %m");
976 if (a
->mdns_address_rr
) {
977 if (a
->link
->mdns_ipv6_scope
)
978 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
979 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
982 if (a
->mdns_ptr_rr
) {
983 if (a
->link
->mdns_ipv6_scope
)
984 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
985 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
993 log_debug_errno(r
, "Failed to update address RRs: %m");
996 int link_address_update_rtnl(LinkAddress
*a
, sd_netlink_message
*m
) {
1001 r
= sd_rtnl_message_addr_get_flags(m
, &a
->flags
);
1005 sd_rtnl_message_addr_get_scope(m
, &a
->scope
);
1007 link_allocate_scopes(a
->link
);
1008 link_add_rrs(a
->link
, false);
1013 bool link_address_relevant(LinkAddress
*a
, bool local_multicast
) {
1016 if (a
->flags
& (IFA_F_DEPRECATED
|IFA_F_TENTATIVE
))
1019 if (a
->scope
>= (local_multicast
? RT_SCOPE_HOST
: RT_SCOPE_LINK
))
1025 static bool link_needs_save(Link
*l
) {
1028 /* Returns true if any of the settings where set different from the default */
1033 if (l
->llmnr_support
!= RESOLVE_SUPPORT_YES
||
1034 l
->mdns_support
!= RESOLVE_SUPPORT_NO
||
1035 l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
1038 if (l
->dns_servers
||
1042 if (!set_isempty(l
->dnssec_negative_trust_anchors
))
1048 int link_save_user(Link
*l
) {
1049 _cleanup_free_
char *temp_path
= NULL
;
1050 _cleanup_fclose_
FILE *f
= NULL
;
1055 assert(l
->state_file
);
1057 if (!link_needs_save(l
)) {
1058 (void) unlink(l
->state_file
);
1062 r
= mkdir_parents(l
->state_file
, 0700);
1066 r
= fopen_temporary(l
->state_file
, &f
, &temp_path
);
1070 fputs_unlocked("# This is private data. Do not parse.\n", f
);
1072 v
= resolve_support_to_string(l
->llmnr_support
);
1074 fprintf(f
, "LLMNR=%s\n", v
);
1076 v
= resolve_support_to_string(l
->mdns_support
);
1078 fprintf(f
, "MDNS=%s\n", v
);
1080 v
= dnssec_mode_to_string(l
->dnssec_mode
);
1082 fprintf(f
, "DNSSEC=%s\n", v
);
1084 if (l
->dns_servers
) {
1087 fputs_unlocked("SERVERS=", f
);
1088 LIST_FOREACH(servers
, server
, l
->dns_servers
) {
1090 if (server
!= l
->dns_servers
)
1091 fputc_unlocked(' ', f
);
1093 v
= dns_server_string(server
);
1099 fputs_unlocked(v
, f
);
1101 fputc_unlocked('\n', f
);
1104 if (l
->search_domains
) {
1105 DnsSearchDomain
*domain
;
1107 fputs_unlocked("DOMAINS=", f
);
1108 LIST_FOREACH(domains
, domain
, l
->search_domains
) {
1110 if (domain
!= l
->search_domains
)
1111 fputc_unlocked(' ', f
);
1113 if (domain
->route_only
)
1114 fputc_unlocked('~', f
);
1116 fputs_unlocked(DNS_SEARCH_DOMAIN_NAME(domain
), f
);
1118 fputc_unlocked('\n', f
);
1121 if (!set_isempty(l
->dnssec_negative_trust_anchors
)) {
1126 fputs_unlocked("NTAS=", f
);
1127 SET_FOREACH(nta
, l
->dnssec_negative_trust_anchors
, i
) {
1130 fputc_unlocked(' ', f
);
1132 fputs_unlocked(nta
, f
);
1135 fputc_unlocked('\n', f
);
1138 r
= fflush_and_check(f
);
1142 if (rename(temp_path
, l
->state_file
) < 0) {
1150 (void) unlink(l
->state_file
);
1153 (void) unlink(temp_path
);
1155 return log_error_errno(r
, "Failed to save link data %s: %m", l
->state_file
);
1158 int link_load_user(Link
*l
) {
1172 assert(l
->state_file
);
1174 /* Try to load only a single time */
1180 return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */
1182 r
= parse_env_file(l
->state_file
, NEWLINE
,
1186 "SERVERS", &servers
,
1187 "DOMAINS", &domains
,
1195 link_flush_settings(l
);
1197 /* If we can't recognize the LLMNR or MDNS setting we don't override the default */
1198 s
= resolve_support_from_string(llmnr
);
1200 l
->llmnr_support
= s
;
1202 s
= resolve_support_from_string(mdns
);
1204 l
->mdns_support
= s
;
1206 /* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
1207 l
->dnssec_mode
= dnssec_mode_from_string(dnssec
);
1209 for (p
= servers
;;) {
1210 _cleanup_free_
char *word
= NULL
;
1212 r
= extract_first_word(&p
, &word
, NULL
, 0);
1218 r
= link_update_dns_server_one(l
, word
);
1220 log_debug_errno(r
, "Failed to load DNS server '%s', ignoring: %m", word
);
1225 for (p
= domains
;;) {
1226 _cleanup_free_
char *word
= NULL
;
1230 r
= extract_first_word(&p
, &word
, NULL
, 0);
1236 is_route
= word
[0] == '~';
1237 n
= is_route
? word
+ 1 : word
;
1239 r
= link_update_search_domain_one(l
, n
, is_route
);
1241 log_debug_errno(r
, "Failed to load search domain '%s', ignoring: %m", word
);
1247 _cleanup_set_free_free_ Set
*ns
= NULL
;
1249 ns
= set_new(&dns_name_hash_ops
);
1255 r
= set_put_strsplit(ns
, ntas
, NULL
, 0);
1259 l
->dnssec_negative_trust_anchors
= ns
;
1266 return log_error_errno(r
, "Failed to load link data %s: %m", l
->state_file
);
1269 void link_remove_user(Link
*l
) {
1271 assert(l
->state_file
);
1273 (void) unlink(l
->state_file
);