2020-11-09 13:23:58 +09:00
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2014-07-16 00:26:02 +02:00
2023-09-08 21:28:26 +02:00
# include <linux/if.h>
2019-04-10 19:55:53 +09:00
# include <unistd.h>
2014-07-16 00:26:02 +02:00
# include "sd-network.h"
2015-10-24 22:58:24 +02:00
2015-10-27 03:01:06 +01:00
# include "alloc-util.h"
2018-11-30 22:08:41 +01:00
# include "env-file.h"
2016-06-15 22:38:23 +02:00
# include "fd-util.h"
# include "fileio.h"
2023-02-22 23:13:31 +01:00
# include "fs-util.h"
2019-04-11 14:16:51 +09:00
# include "log-link.h"
2016-06-15 22:38:23 +02:00
# include "mkdir.h"
2022-01-21 05:05:04 +09:00
# include "netif-util.h"
2015-10-26 16:18:16 +01:00
# include "parse-util.h"
2014-07-16 00:26:02 +02:00
# include "resolved-link.h"
2017-03-16 15:52:34 +09:00
# include "resolved-llmnr.h"
# include "resolved-mdns.h"
2020-07-13 09:29:14 +09:00
# include "socket-netlink.h"
2021-12-08 03:48:46 +09:00
# include "stat-util.h"
2015-10-24 22:58:24 +02:00
# include "string-util.h"
# include "strv.h"
2018-11-30 21:05:27 +01:00
# include "tmpfile-util.h"
2014-07-16 00:26:02 +02:00
int link_new ( Manager * m , Link * * ret , int ifindex ) {
_cleanup_ ( link_freep ) Link * l = NULL ;
int r ;
assert ( m ) ;
assert ( ifindex > 0 ) ;
2018-12-04 12:40:07 +01:00
l = new ( Link , 1 ) ;
2014-07-16 00:26:02 +02:00
if ( ! l )
return - ENOMEM ;
2018-12-04 12:40:07 +01:00
* l = ( Link ) {
. ifindex = ifindex ,
. default_route = - 1 ,
. llmnr_support = RESOLVE_SUPPORT_YES ,
2022-11-04 12:06:21 +09:00
. mdns_support = RESOLVE_SUPPORT_YES ,
2018-12-04 12:40:07 +01:00
. dnssec_mode = _DNSSEC_MODE_INVALID ,
. dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID ,
. operstate = IF_OPER_UNKNOWN ,
} ;
2014-07-16 00:26:02 +02:00
2016-06-15 22:38:23 +02:00
if ( asprintf ( & l - > state_file , " /run/systemd/resolve/netif/%i " , ifindex ) < 0 )
return - ENOMEM ;
2021-01-18 19:05:05 +01:00
r = hashmap_ensure_put ( & m - > links , NULL , INT_TO_PTR ( ifindex ) , l ) ;
2014-07-16 00:26:02 +02:00
if ( r < 0 )
return r ;
l - > manager = m ;
if ( ret )
* ret = l ;
2021-01-18 19:05:05 +01:00
TAKE_PTR ( l ) ;
2014-07-16 00:26:02 +02:00
return 0 ;
}
2016-01-19 17:16:12 +01:00
void link_flush_settings ( Link * l ) {
assert ( l ) ;
2018-12-04 12:40:07 +01:00
l - > default_route = - 1 ;
2016-01-19 17:16:12 +01:00
l - > llmnr_support = RESOLVE_SUPPORT_YES ;
2022-11-04 12:06:21 +09:00
l - > mdns_support = RESOLVE_SUPPORT_YES ;
2016-01-19 17:16:12 +01:00
l - > dnssec_mode = _DNSSEC_MODE_INVALID ;
2018-06-13 20:26:24 +02:00
l - > dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID ;
2016-01-19 17:16:12 +01:00
dns_server_unlink_all ( l - > dns_servers ) ;
dns_search_domain_unlink_all ( l - > search_domains ) ;
l - > dnssec_negative_trust_anchors = set_free_free ( l - > dnssec_negative_trust_anchors ) ;
}
2014-07-16 00:26:02 +02:00
Link * link_free ( Link * l ) {
if ( ! l )
return NULL ;
2016-12-02 15:56:27 +02:00
/* Send goodbye messages. */
dns_scope_announce ( l - > mdns_ipv4_scope , true ) ;
dns_scope_announce ( l - > mdns_ipv6_scope , true ) ;
2016-01-19 17:16:12 +01:00
link_flush_settings ( l ) ;
2015-11-24 17:59:40 +01:00
2014-07-16 00:26:02 +02:00
while ( l - > addresses )
2016-01-19 17:16:12 +01:00
( void ) link_address_free ( l - > addresses ) ;
2014-07-16 00:26:02 +02:00
if ( l - > manager )
hashmap_remove ( l - > manager - > links , INT_TO_PTR ( l - > ifindex ) ) ;
dns_scope_free ( l - > unicast_scope ) ;
2014-07-18 12:34:02 +02:00
dns_scope_free ( l - > llmnr_ipv4_scope ) ;
dns_scope_free ( l - > llmnr_ipv6_scope ) ;
2015-07-11 13:17:51 -04:00
dns_scope_free ( l - > mdns_ipv4_scope ) ;
dns_scope_free ( l - > mdns_ipv6_scope ) ;
2014-07-16 00:26:02 +02:00
2016-06-15 22:38:23 +02:00
free ( l - > state_file ) ;
2019-04-11 14:08:40 +09:00
free ( l - > ifname ) ;
2016-06-15 22:38:23 +02:00
2016-10-16 18:28:30 -04:00
return mfree ( l ) ;
2014-07-18 12:34:02 +02:00
}
2016-01-19 17:16:12 +01:00
void link_allocate_scopes ( Link * l ) {
2017-09-29 21:18:29 +02:00
bool unicast_relevant ;
2014-07-18 12:34:02 +02:00
int r ;
assert ( l ) ;
2017-09-29 21:18:29 +02:00
/* If a link that used to be relevant is no longer, or a link that did not use to be relevant now becomes
* relevant , let ' s reinit the learnt global DNS server information , since we might talk to different servers
* now , even if they have the same addresses as before . */
unicast_relevant = link_relevant ( l , AF_UNSPEC , false ) ;
if ( unicast_relevant ! = l - > unicast_relevant ) {
l - > unicast_relevant = unicast_relevant ;
dns_server_reset_features_all ( l - > manager - > fallback_dns_servers ) ;
dns_server_reset_features_all ( l - > manager - > dns_servers ) ;
2018-06-08 12:04:49 +02:00
/* Also, flush the global unicast scope, to deal with split horizon setups, where talking through one
* interface reveals different DNS zones than through others . */
if ( l - > manager - > unicast_scope )
dns_cache_flush ( & l - > manager - > unicast_scope - > cache ) ;
2017-09-29 21:18:29 +02:00
}
/* And now, allocate all scopes that makes sense now if we didn't have them yet, and drop those which we don't
* need anymore */
if ( unicast_relevant & & l - > dns_servers ) {
2014-07-18 12:34:02 +02:00
if ( ! l - > unicast_scope ) {
2017-09-29 21:18:29 +02:00
dns_server_reset_features_all ( l - > dns_servers ) ;
2014-07-18 12:34:02 +02:00
r = dns_scope_new ( l - > manager , & l - > unicast_scope , l , DNS_PROTOCOL_DNS , AF_UNSPEC ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( l , r , " Failed to allocate DNS scope, ignoring: %m " ) ;
2014-07-18 12:34:02 +02:00
}
} else
l - > unicast_scope = dns_scope_free ( l - > unicast_scope ) ;
2016-01-19 17:13:27 +01:00
if ( link_relevant ( l , AF_INET , true ) & &
2022-11-04 12:53:07 +09:00
link_get_llmnr_support ( l ) ! = RESOLVE_SUPPORT_NO ) {
2014-07-18 12:34:02 +02:00
if ( ! l - > llmnr_ipv4_scope ) {
r = dns_scope_new ( l - > manager , & l - > llmnr_ipv4_scope , l , DNS_PROTOCOL_LLMNR , AF_INET ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( l , r , " Failed to allocate LLMNR IPv4 scope, ignoring: %m " ) ;
2014-07-18 12:34:02 +02:00
}
} else
l - > llmnr_ipv4_scope = dns_scope_free ( l - > llmnr_ipv4_scope ) ;
2016-01-19 17:13:27 +01:00
if ( link_relevant ( l , AF_INET6 , true ) & &
2022-11-04 12:53:07 +09:00
link_get_llmnr_support ( l ) ! = RESOLVE_SUPPORT_NO ) {
2014-07-18 12:34:02 +02:00
if ( ! l - > llmnr_ipv6_scope ) {
r = dns_scope_new ( l - > manager , & l - > llmnr_ipv6_scope , l , DNS_PROTOCOL_LLMNR , AF_INET6 ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( l , r , " Failed to allocate LLMNR IPv6 scope, ignoring: %m " ) ;
2014-07-18 12:34:02 +02:00
}
} else
l - > llmnr_ipv6_scope = dns_scope_free ( l - > llmnr_ipv6_scope ) ;
2015-07-11 13:17:51 -04:00
2016-01-19 17:13:27 +01:00
if ( link_relevant ( l , AF_INET , true ) & &
2022-11-04 12:53:07 +09:00
link_get_mdns_support ( l ) ! = RESOLVE_SUPPORT_NO ) {
2015-07-11 13:17:51 -04:00
if ( ! l - > mdns_ipv4_scope ) {
r = dns_scope_new ( l - > manager , & l - > mdns_ipv4_scope , l , DNS_PROTOCOL_MDNS , AF_INET ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( l , r , " Failed to allocate mDNS IPv4 scope, ignoring: %m " ) ;
2015-07-11 13:17:51 -04:00
}
} else
l - > mdns_ipv4_scope = dns_scope_free ( l - > mdns_ipv4_scope ) ;
2016-01-19 17:13:27 +01:00
if ( link_relevant ( l , AF_INET6 , true ) & &
2022-11-04 12:53:07 +09:00
link_get_mdns_support ( l ) ! = RESOLVE_SUPPORT_NO ) {
2015-07-11 13:17:51 -04:00
if ( ! l - > mdns_ipv6_scope ) {
r = dns_scope_new ( l - > manager , & l - > mdns_ipv6_scope , l , DNS_PROTOCOL_MDNS , AF_INET6 ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( l , r , " Failed to allocate mDNS IPv6 scope, ignoring: %m " ) ;
2015-07-11 13:17:51 -04:00
}
} else
l - > mdns_ipv6_scope = dns_scope_free ( l - > mdns_ipv6_scope ) ;
2014-07-18 12:34:02 +02:00
}
2014-07-16 00:26:02 +02:00
2014-07-31 17:46:40 +02:00
void link_add_rrs ( Link * l , bool force_remove ) {
2017-10-04 11:34:39 +03:00
int r ;
2014-07-29 14:24:02 +02:00
LIST_FOREACH ( addresses , a , l - > addresses )
2014-07-31 17:46:40 +02:00
link_address_add_rrs ( a , force_remove ) ;
2017-10-04 11:34:39 +03:00
if ( ! force_remove & &
2022-11-04 12:53:07 +09:00
link_get_mdns_support ( l ) = = RESOLVE_SUPPORT_YES ) {
2017-10-04 11:34:39 +03:00
if ( l - > mdns_ipv4_scope ) {
r = dns_scope_add_dnssd_services ( l - > mdns_ipv4_scope ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( l , r , " Failed to add IPv4 DNS-SD services, ignoring: %m " ) ;
2017-10-04 11:34:39 +03:00
}
if ( l - > mdns_ipv6_scope ) {
r = dns_scope_add_dnssd_services ( l - > mdns_ipv6_scope ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( l , r , " Failed to add IPv6 DNS-SD services, ignoring: %m " ) ;
2017-10-04 11:34:39 +03:00
}
} else {
if ( l - > mdns_ipv4_scope ) {
r = dns_scope_remove_dnssd_services ( l - > mdns_ipv4_scope ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( l , r , " Failed to remove IPv4 DNS-SD services, ignoring: %m " ) ;
2017-10-04 11:34:39 +03:00
}
if ( l - > mdns_ipv6_scope ) {
r = dns_scope_remove_dnssd_services ( l - > mdns_ipv6_scope ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( l , r , " Failed to remove IPv6 DNS-SD services, ignoring: %m " ) ;
2017-10-04 11:34:39 +03:00
}
}
2014-07-29 14:24:02 +02:00
}
2016-06-15 22:38:23 +02:00
int link_process_rtnl ( Link * l , sd_netlink_message * m ) {
2014-07-18 12:34:02 +02:00
const char * n = NULL ;
2014-07-16 00:26:02 +02:00
int r ;
assert ( l ) ;
assert ( m ) ;
r = sd_rtnl_message_link_get_flags ( m , & l - > flags ) ;
if ( r < 0 )
return r ;
2016-01-20 21:22:26 +01:00
( void ) sd_netlink_message_read_u32 ( m , IFLA_MTU , & l - > mtu ) ;
( void ) sd_netlink_message_read_u8 ( m , IFLA_OPERSTATE , & l - > operstate ) ;
2014-07-18 12:34:02 +02:00
2022-01-21 04:32:38 +09:00
if ( sd_netlink_message_read_string ( m , IFLA_IFNAME , & n ) > = 0 & &
! streq_ptr ( l - > ifname , n ) ) {
if ( l - > ifname )
log_link_debug ( l , " Interface name change detected: %s -> %s " , l - > ifname , n ) ;
2019-04-11 14:08:40 +09:00
r = free_and_strdup ( & l - > ifname , n ) ;
if ( r < 0 )
return r ;
2014-07-18 12:34:02 +02:00
}
2014-07-16 00:26:02 +02:00
return 0 ;
}
2020-07-13 09:29:14 +09:00
static int link_update_dns_server_one ( Link * l , const char * str ) {
_cleanup_free_ char * name = NULL ;
int family , ifindex , r ;
2016-06-15 22:33:27 +02:00
union in_addr_union a ;
DnsServer * s ;
2020-07-13 09:29:14 +09:00
uint16_t port ;
2016-06-15 22:33:27 +02:00
assert ( l ) ;
2020-07-13 09:29:14 +09:00
assert ( str ) ;
2016-06-15 22:33:27 +02:00
2020-07-13 09:29:14 +09:00
r = in_addr_port_ifindex_name_from_string_auto ( str , & family , & a , & port , & ifindex , & name ) ;
2016-06-15 22:33:27 +02:00
if ( r < 0 )
return r ;
2020-07-13 09:29:14 +09:00
if ( ifindex ! = 0 & & ifindex ! = l - > ifindex )
return - EINVAL ;
/* By default, the port number is determined with the transaction feature level.
* See dns_transaction_port ( ) and dns_server_port ( ) . */
if ( IN_SET ( port , 53 , 853 ) )
port = 0 ;
s = dns_server_find ( l - > dns_servers , family , & a , port , 0 , name ) ;
2016-06-15 22:33:27 +02:00
if ( s ) {
dns_server_move_back_and_unmark ( s ) ;
return 0 ;
}
2024-03-08 23:02:19 +00:00
return dns_server_new ( l - > manager , NULL , DNS_SERVER_LINK , l , family , & a , port , 0 , name , RESOLVE_CONFIG_SOURCE_NETWORKD ) ;
2016-06-15 22:33:27 +02:00
}
2014-07-23 23:10:00 +02:00
static int link_update_dns_servers ( Link * l ) {
2014-07-23 23:03:50 +02:00
_cleanup_strv_free_ char * * nameservers = NULL ;
int r ;
2014-07-16 00:26:02 +02:00
assert ( l ) ;
2014-08-13 22:37:45 +02:00
r = sd_network_link_get_dns ( l - > ifindex , & nameservers ) ;
2015-12-18 14:16:48 +01:00
if ( r = = - ENODATA ) {
r = 0 ;
goto clear ;
}
2014-07-23 23:03:50 +02:00
if ( r < 0 )
2014-07-16 00:26:02 +02:00
goto clear ;
2015-11-24 21:27:29 +01:00
dns_server_mark_all ( l - > dns_servers ) ;
2014-08-01 17:03:28 +02:00
2014-07-23 23:03:50 +02:00
STRV_FOREACH ( nameserver , nameservers ) {
2016-06-15 22:33:27 +02:00
r = link_update_dns_server_one ( l , * nameserver ) ;
2014-07-23 23:03:50 +02:00
if ( r < 0 )
goto clear ;
2014-07-16 00:26:02 +02:00
}
2015-11-24 21:27:29 +01:00
dns_server_unlink_marked ( l - > dns_servers ) ;
2014-07-16 00:26:02 +02:00
return 0 ;
clear :
2015-11-24 21:27:29 +01:00
dns_server_unlink_all ( l - > dns_servers ) ;
2014-07-16 00:26:02 +02:00
return r ;
}
2018-12-04 13:48:28 +01:00
static int link_update_default_route ( Link * l ) {
int r ;
assert ( l ) ;
r = sd_network_link_get_dns_default_route ( l - > ifindex ) ;
if ( r = = - ENODATA ) {
r = 0 ;
goto clear ;
}
if ( r < 0 )
goto clear ;
l - > default_route = r > 0 ;
return 0 ;
clear :
l - > default_route = - 1 ;
return r ;
}
2014-08-04 23:08:03 +02:00
static int link_update_llmnr_support ( Link * l ) {
_cleanup_free_ char * b = NULL ;
int r ;
assert ( l ) ;
2019-05-08 10:55:39 +02:00
l - > llmnr_support = RESOLVE_SUPPORT_YES ; /* yes, yes, we set it twice which is ugly */
2014-08-13 22:37:45 +02:00
r = sd_network_link_get_llmnr ( l - > ifindex , & b ) ;
2019-05-08 10:55:39 +02:00
if ( r = = - ENODATA )
return 0 ;
2014-08-04 23:08:03 +02:00
if ( r < 0 )
2019-05-08 10:55:39 +02:00
return r ;
2014-08-04 23:08:03 +02:00
2019-05-08 10:55:39 +02:00
r = resolve_support_from_string ( b ) ;
if ( r < 0 )
return r ;
2014-08-04 23:08:03 +02:00
2019-05-08 10:55:39 +02:00
l - > llmnr_support = r ;
2014-08-04 23:08:03 +02:00
return 0 ;
}
2016-01-05 17:32:25 +01:00
static int link_update_mdns_support ( Link * l ) {
_cleanup_free_ char * b = NULL ;
int r ;
assert ( l ) ;
2022-11-04 12:06:21 +09:00
l - > mdns_support = RESOLVE_SUPPORT_YES ;
2019-05-08 10:55:39 +02:00
2016-01-05 17:32:25 +01:00
r = sd_network_link_get_mdns ( l - > ifindex , & b ) ;
2019-05-08 10:55:39 +02:00
if ( r = = - ENODATA )
return 0 ;
2016-01-05 17:32:25 +01:00
if ( r < 0 )
2019-05-08 10:55:39 +02:00
return r ;
2016-01-05 17:32:25 +01:00
2019-05-08 10:55:39 +02:00
r = resolve_support_from_string ( b ) ;
if ( r < 0 )
return r ;
2016-01-05 17:32:25 +01:00
2019-05-08 10:55:39 +02:00
l - > mdns_support = r ;
2016-01-05 17:32:25 +01:00
return 0 ;
}
2018-06-13 20:26:24 +02:00
void link_set_dns_over_tls_mode ( Link * l , DnsOverTlsMode mode ) {
2018-05-04 17:31:16 +02:00
assert ( l ) ;
2018-06-21 01:29:49 +09:00
# if ! ENABLE_DNS_OVER_TLS
2018-06-13 20:26:24 +02:00
if ( mode ! = DNS_OVER_TLS_NO )
2022-01-21 04:43:37 +09:00
log_link_warning ( l ,
" DNS-over-TLS option for the link cannot be enabled or set to opportunistic "
" when systemd-resolved is built without DNS-over-TLS support. "
" Turning off DNS-over-TLS support. " ) ;
2018-05-04 17:31:16 +02:00
return ;
# endif
2018-06-13 20:26:24 +02:00
l - > dns_over_tls_mode = mode ;
2022-05-08 14:50:39 +09:00
l - > unicast_scope = dns_scope_free ( l - > unicast_scope ) ;
2018-05-04 17:31:16 +02:00
}
2018-06-13 20:26:24 +02:00
static int link_update_dns_over_tls_mode ( Link * l ) {
2018-05-04 17:31:16 +02:00
_cleanup_free_ char * b = NULL ;
int r ;
assert ( l ) ;
2019-05-08 10:55:39 +02:00
l - > dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID ;
2018-06-13 20:26:24 +02:00
r = sd_network_link_get_dns_over_tls ( l - > ifindex , & b ) ;
2019-05-08 10:55:39 +02:00
if ( r = = - ENODATA )
return 0 ;
2018-05-04 17:31:16 +02:00
if ( r < 0 )
2019-05-08 10:55:39 +02:00
return r ;
2018-05-04 17:31:16 +02:00
2019-05-08 10:55:39 +02:00
r = dns_over_tls_mode_from_string ( b ) ;
if ( r < 0 )
return r ;
2018-05-04 17:31:16 +02:00
2019-05-08 10:55:39 +02:00
l - > dns_over_tls_mode = r ;
2018-05-04 17:31:16 +02:00
return 0 ;
}
2016-01-19 17:16:12 +01:00
void link_set_dnssec_mode ( Link * l , DnssecMode mode ) {
assert ( l ) ;
2021-10-27 15:39:48 +02:00
# if !HAVE_OPENSSL_OR_GCRYPT
2017-09-29 00:37:23 +02:00
if ( IN_SET ( mode , DNSSEC_YES , DNSSEC_ALLOW_DOWNGRADE ) )
2022-01-21 04:43:37 +09:00
log_link_warning ( l ,
" DNSSEC option for the link cannot be enabled or set to allow-downgrade "
" when systemd-resolved is built without a cryptographic library. "
" Turning off DNSSEC support. " ) ;
2017-06-18 05:22:32 +09:00
return ;
# endif
2016-01-19 17:16:12 +01:00
if ( l - > dnssec_mode = = mode )
return ;
l - > dnssec_mode = mode ;
2022-05-08 14:50:39 +09:00
l - > unicast_scope = dns_scope_free ( l - > unicast_scope ) ;
2016-01-19 17:16:12 +01:00
}
2016-01-05 19:57:33 +01:00
static int link_update_dnssec_mode ( Link * l ) {
_cleanup_free_ char * m = NULL ;
2016-01-15 21:07:21 +01:00
DnssecMode mode ;
2016-01-05 19:57:33 +01:00
int r ;
assert ( l ) ;
2019-05-08 10:55:39 +02:00
l - > dnssec_mode = _DNSSEC_MODE_INVALID ;
2016-01-05 19:57:33 +01:00
r = sd_network_link_get_dnssec ( l - > ifindex , & m ) ;
2019-05-08 10:55:39 +02:00
if ( r = = - ENODATA )
return 0 ;
2016-01-05 19:57:33 +01:00
if ( r < 0 )
2019-05-08 10:55:39 +02:00
return r ;
2016-01-05 19:57:33 +01:00
2016-01-15 21:07:21 +01:00
mode = dnssec_mode_from_string ( m ) ;
2019-05-08 10:55:39 +02:00
if ( mode < 0 )
return mode ;
2016-01-05 19:57:33 +01:00
2016-01-19 17:16:12 +01:00
link_set_dnssec_mode ( l , mode ) ;
2016-01-05 19:57:33 +01:00
return 0 ;
}
2016-01-06 18:36:32 +01:00
static int link_update_dnssec_negative_trust_anchors ( Link * l ) {
_cleanup_strv_free_ char * * ntas = NULL ;
_cleanup_set_free_free_ Set * ns = NULL ;
int r ;
assert ( l ) ;
2019-05-08 10:55:39 +02:00
l - > dnssec_negative_trust_anchors = set_free_free ( l - > dnssec_negative_trust_anchors ) ;
2016-01-06 18:36:32 +01:00
r = sd_network_link_get_dnssec_negative_trust_anchors ( l - > ifindex , & ntas ) ;
2019-05-08 10:55:39 +02:00
if ( r = = - ENODATA )
2022-09-24 09:31:00 +09:00
return 0 ;
2016-01-06 18:36:32 +01:00
if ( r < 0 )
2019-05-08 10:55:39 +02:00
return r ;
2016-01-06 18:36:32 +01:00
ns = set_new ( & dns_name_hash_ops ) ;
if ( ! ns )
return - ENOMEM ;
2020-04-29 08:47:51 +02:00
r = set_put_strdupv ( & ns , ntas ) ;
2016-06-15 22:32:33 +02:00
if ( r < 0 )
return r ;
2016-01-06 18:36:32 +01:00
2018-03-22 16:53:26 +01:00
l - > dnssec_negative_trust_anchors = TAKE_PTR ( ns ) ;
2016-01-06 18:36:32 +01:00
return 0 ;
}
2016-01-25 23:19:49 +01:00
static int link_update_search_domain_one ( Link * l , const char * name , bool route_only ) {
DnsSearchDomain * d ;
int r ;
2016-06-15 22:32:33 +02:00
assert ( l ) ;
assert ( name ) ;
2016-01-25 23:19:49 +01:00
r = dns_search_domain_find ( l - > search_domains , name , & d ) ;
if ( r < 0 )
return r ;
if ( r > 0 )
dns_search_domain_move_back_and_unmark ( d ) ;
else {
r = dns_search_domain_new ( l - > manager , & d , DNS_SEARCH_DOMAIN_LINK , l , name ) ;
if ( r < 0 )
return r ;
}
d - > route_only = route_only ;
return 0 ;
}
2015-11-24 21:12:51 +01:00
static int link_update_search_domains ( Link * l ) {
2016-01-25 23:19:49 +01:00
_cleanup_strv_free_ char * * sdomains = NULL , * * rdomains = NULL ;
int r , q ;
2014-08-14 22:18:22 +02:00
2015-11-24 21:12:51 +01:00
assert ( l ) ;
2014-08-14 22:18:22 +02:00
2016-01-25 23:19:49 +01:00
r = sd_network_link_get_search_domains ( l - > ifindex , & sdomains ) ;
if ( r < 0 & & r ! = - ENODATA )
goto clear ;
q = sd_network_link_get_route_domains ( l - > ifindex , & rdomains ) ;
if ( q < 0 & & q ! = - ENODATA ) {
r = q ;
goto clear ;
}
if ( r = = - ENODATA & & q = = - ENODATA ) {
2015-12-18 14:16:48 +01:00
/* networkd knows nothing about this interface, and that's fine. */
r = 0 ;
goto clear ;
}
2015-11-24 21:12:51 +01:00
dns_search_domain_mark_all ( l - > search_domains ) ;
2016-01-25 23:19:49 +01:00
STRV_FOREACH ( i , sdomains ) {
r = link_update_search_domain_one ( l , * i , false ) ;
2015-11-24 21:12:51 +01:00
if ( r < 0 )
goto clear ;
2016-01-25 23:19:49 +01:00
}
2015-11-24 21:12:51 +01:00
2016-01-25 23:19:49 +01:00
STRV_FOREACH ( i , rdomains ) {
r = link_update_search_domain_one ( l , * i , true ) ;
if ( r < 0 )
goto clear ;
2015-11-24 21:12:51 +01:00
}
dns_search_domain_unlink_marked ( l - > search_domains ) ;
2014-08-14 22:18:22 +02:00
return 0 ;
2015-11-24 21:12:51 +01:00
clear :
dns_search_domain_unlink_all ( l - > search_domains ) ;
return r ;
2014-08-14 22:18:22 +02:00
}
2016-06-15 22:35:23 +02:00
static int link_is_managed ( Link * l ) {
2016-01-19 17:16:12 +01:00
_cleanup_free_ char * state = NULL ;
2015-11-24 21:12:51 +01:00
int r ;
2014-07-16 00:26:02 +02:00
assert ( l ) ;
2016-01-19 17:16:12 +01:00
r = sd_network_link_get_setup_state ( l - > ifindex , & state ) ;
if ( r = = - ENODATA )
2016-06-15 22:35:23 +02:00
return 0 ;
2016-01-19 17:16:12 +01:00
if ( r < 0 )
return r ;
2021-11-14 15:46:47 +09:00
return ! STR_IN_SET ( state , " pending " , " initialized " , " unmanaged " ) ;
2016-01-19 17:16:12 +01:00
}
2021-12-08 03:48:46 +09:00
static void link_enter_unmanaged ( Link * l ) {
assert ( l ) ;
/* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
if ( l - > is_managed )
link_flush_settings ( l ) ;
l - > is_managed = false ;
}
2016-01-19 17:16:12 +01:00
static void link_read_settings ( Link * l ) {
2021-12-08 03:48:46 +09:00
struct stat st ;
2016-01-19 17:16:12 +01:00
int r ;
assert ( l ) ;
/* Read settings from networkd, except when networkd is not managing this interface. */
2021-12-08 03:48:46 +09:00
r = sd_network_link_get_stat ( l - > ifindex , & st ) ;
if ( r = = - ENOENT )
return link_enter_unmanaged ( l ) ;
if ( r < 0 )
return ( void ) log_link_warning_errno ( l , r , " Failed to stat() networkd's link state file, ignoring: %m " ) ;
if ( stat_inode_unmodified ( & l - > networkd_state_file_stat , & st ) )
/* The state file is unmodified. Not necessary to re-read settings. */
2016-01-19 17:16:12 +01:00
return ;
2021-12-08 03:48:46 +09:00
/* Save the new stat for the next event. */
l - > networkd_state_file_stat = st ;
2016-01-19 17:16:12 +01:00
2021-12-08 03:48:46 +09:00
r = link_is_managed ( l ) ;
if ( r < 0 )
return ( void ) log_link_warning_errno ( l , r , " Failed to determine whether the interface is managed, ignoring: %m " ) ;
if ( r = = 0 )
return link_enter_unmanaged ( l ) ;
2016-01-19 17:16:12 +01:00
l - > is_managed = true ;
2022-01-21 05:22:33 +09:00
r = network_link_get_operational_state ( l - > ifindex , & l - > networkd_operstate ) ;
if ( r < 0 )
log_link_warning_errno ( l , r , " Failed to read networkd's link operational state, ignoring: %m " ) ;
2016-01-05 19:43:51 +01:00
r = link_update_dns_servers ( l ) ;
if ( r < 0 )
2019-04-11 14:16:51 +09:00
log_link_warning_errno ( l , r , " Failed to read DNS servers for the interface, ignoring: %m " ) ;
2016-01-05 19:43:51 +01:00
r = link_update_llmnr_support ( l ) ;
if ( r < 0 )
2019-04-11 14:16:51 +09:00
log_link_warning_errno ( l , r , " Failed to read LLMNR support for the interface, ignoring: %m " ) ;
2016-01-05 19:43:51 +01:00
r = link_update_mdns_support ( l ) ;
if ( r < 0 )
2019-04-11 14:16:51 +09:00
log_link_warning_errno ( l , r , " Failed to read mDNS support for the interface, ignoring: %m " ) ;
2016-01-05 19:43:51 +01:00
2018-06-13 20:26:24 +02:00
r = link_update_dns_over_tls_mode ( l ) ;
2018-05-04 17:31:16 +02:00
if ( r < 0 )
2019-04-11 14:16:51 +09:00
log_link_warning_errno ( l , r , " Failed to read DNS-over-TLS mode for the interface, ignoring: %m " ) ;
2018-05-04 17:31:16 +02:00
2016-01-05 19:57:33 +01:00
r = link_update_dnssec_mode ( l ) ;
if ( r < 0 )
2019-04-11 14:16:51 +09:00
log_link_warning_errno ( l , r , " Failed to read DNSSEC mode for the interface, ignoring: %m " ) ;
2015-11-24 21:12:51 +01:00
2016-01-06 18:36:32 +01:00
r = link_update_dnssec_negative_trust_anchors ( l ) ;
if ( r < 0 )
2019-04-11 14:16:51 +09:00
log_link_warning_errno ( l , r , " Failed to read DNSSEC negative trust anchors for the interface, ignoring: %m " ) ;
2016-01-06 18:36:32 +01:00
2015-11-24 21:12:51 +01:00
r = link_update_search_domains ( l ) ;
if ( r < 0 )
2019-04-11 14:16:51 +09:00
log_link_warning_errno ( l , r , " Failed to read search domains for the interface, ignoring: %m " ) ;
2018-12-04 13:48:28 +01:00
r = link_update_default_route ( l ) ;
if ( r < 0 )
2019-04-11 14:16:51 +09:00
log_link_warning_errno ( l , r , " Failed to read default route setting for the interface, proceeding anyway: %m " ) ;
2016-01-19 17:16:12 +01:00
}
2016-06-15 22:38:23 +02:00
int link_update ( Link * l ) {
2017-03-16 15:52:34 +09:00
int r ;
2016-01-19 17:16:12 +01:00
assert ( l ) ;
2015-11-24 21:12:51 +01:00
2016-01-19 17:16:12 +01:00
link_read_settings ( l ) ;
2020-07-02 10:25:19 +09:00
r = link_load_user ( l ) ;
if ( r < 0 )
return r ;
2017-03-16 15:52:34 +09:00
2022-11-04 12:53:07 +09:00
if ( link_get_llmnr_support ( l ) ! = RESOLVE_SUPPORT_NO ) {
2017-03-16 15:52:34 +09:00
r = manager_llmnr_start ( l - > manager ) ;
if ( r < 0 )
return r ;
}
2022-11-04 12:53:07 +09:00
if ( link_get_mdns_support ( l ) ! = RESOLVE_SUPPORT_NO ) {
2017-03-16 15:52:34 +09:00
r = manager_mdns_start ( l - > manager ) ;
if ( r < 0 )
return r ;
}
2016-01-05 19:57:33 +01:00
link_allocate_scopes ( l ) ;
2014-07-31 17:46:40 +02:00
link_add_rrs ( l , false ) ;
2014-07-16 00:26:02 +02:00
return 0 ;
}
2016-02-01 00:00:01 +01:00
bool link_relevant ( Link * l , int family , bool local_multicast ) {
2014-07-16 00:26:02 +02:00
assert ( l ) ;
2017-07-12 16:01:10 +02:00
/* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
2016-02-01 00:00:01 +01:00
* beat , can do multicast and has at least one link - local ( or better ) IP address .
*
* A link is relevant for non - multicast traffic if it isn ' t a loopback device , has a link beat , and has at
2017-02-24 18:14:02 +01:00
* least one routable address . */
2014-07-31 17:46:40 +02:00
2022-01-21 05:07:28 +09:00
if ( ( l - > flags & ( IFF_LOOPBACK | IFF_DORMANT ) ) ! = 0 )
2014-07-31 17:46:40 +02:00
return false ;
2014-07-16 00:26:02 +02:00
2022-01-21 05:07:28 +09:00
if ( ! FLAGS_SET ( l - > flags , IFF_UP | IFF_LOWER_UP ) )
2014-07-16 00:26:02 +02:00
return false ;
2022-01-21 05:07:28 +09:00
if ( local_multicast & &
! FLAGS_SET ( l - > flags , IFF_MULTICAST ) )
return false ;
2016-01-19 17:13:27 +01:00
2022-01-21 05:05:04 +09:00
if ( ! netif_has_carrier ( l - > operstate , l - > flags ) )
2016-01-20 21:22:26 +01:00
return false ;
2022-01-21 05:22:33 +09:00
if ( l - > is_managed & &
! IN_SET ( l - > networkd_operstate , LINK_OPERSTATE_DEGRADED_CARRIER , LINK_OPERSTATE_DEGRADED , LINK_OPERSTATE_ROUTABLE ) )
2014-07-16 00:26:02 +02:00
return false ;
LIST_FOREACH ( addresses , a , l - > addresses )
2016-02-01 00:00:01 +01:00
if ( ( family = = AF_UNSPEC | | a - > family = = family ) & & link_address_relevant ( a , local_multicast ) )
2014-07-16 00:26:02 +02:00
return true ;
return false ;
}
2014-07-29 14:24:02 +02:00
LinkAddress * link_find_address ( Link * l , int family , const union in_addr_union * in_addr ) {
2014-07-16 00:26:02 +02:00
assert ( l ) ;
2021-02-18 02:50:50 +09:00
if ( ! IN_SET ( family , AF_INET , AF_INET6 ) )
return NULL ;
if ( ! in_addr )
return NULL ;
2014-07-18 12:34:02 +02:00
LIST_FOREACH ( addresses , a , l - > addresses )
if ( a - > family = = family & & in_addr_equal ( family , & a - > in_addr , in_addr ) )
2014-07-16 00:26:02 +02:00
return a ;
return NULL ;
}
2014-08-01 18:09:07 +02:00
DnsServer * link_set_dns_server ( Link * l , DnsServer * s ) {
2014-08-01 16:04:12 +02:00
assert ( l ) ;
if ( l - > current_dns_server = = s )
return s ;
2016-01-08 20:59:03 +01:00
if ( s )
2022-01-21 04:43:37 +09:00
log_link_debug ( l , " Switching to DNS server %s. " , strna ( dns_server_string_full ( s ) ) ) ;
2014-08-01 16:04:12 +02:00
2015-11-24 17:59:40 +01:00
dns_server_unref ( l - > current_dns_server ) ;
l - > current_dns_server = dns_server_ref ( s ) ;
2014-08-01 18:09:07 +02:00
2023-06-08 18:42:11 +05:30
/* Skip flushing the cache if server stale feature is enabled. */
if ( l - > unicast_scope & & l - > manager - > stale_retention_usec = = 0 )
2014-08-01 18:09:07 +02:00
dns_cache_flush ( & l - > unicast_scope - > cache ) ;
2014-08-01 16:04:12 +02:00
return s ;
}
2014-07-16 00:26:02 +02:00
DnsServer * link_get_dns_server ( Link * l ) {
assert ( l ) ;
if ( ! l - > current_dns_server )
2014-08-01 16:04:12 +02:00
link_set_dns_server ( l , l - > dns_servers ) ;
2014-07-16 00:26:02 +02:00
return l - > current_dns_server ;
}
2020-11-05 17:00:20 +01:00
void link_next_dns_server ( Link * l , DnsServer * if_current ) {
2014-07-16 00:26:02 +02:00
assert ( l ) ;
2020-11-05 17:00:20 +01:00
/* If the current server of the transaction is specified, and we already are at a different one,
* don ' t do anything */
if ( if_current & & l - > current_dns_server ! = if_current )
return ;
/* If currently have no DNS server, then don't do anything, we'll pick it lazily the next time a DNS
* server is needed . */
2014-07-16 00:26:02 +02:00
if ( ! l - > current_dns_server )
return ;
2020-11-05 17:00:20 +01:00
/* Change to the next one, but make sure to follow the linked list only if this server is actually
* still linked . */
2015-11-24 17:59:40 +01:00
if ( l - > current_dns_server - > linked & & l - > current_dns_server - > servers_next ) {
2014-08-01 16:04:12 +02:00
link_set_dns_server ( l , l - > current_dns_server - > servers_next ) ;
2014-07-16 00:26:02 +02:00
return ;
}
2020-11-05 17:00:20 +01:00
/* Pick the first one again, after we reached the end */
2014-08-01 16:04:12 +02:00
link_set_dns_server ( l , l - > dns_servers ) ;
2014-07-16 00:26:02 +02:00
}
2018-06-13 20:26:24 +02:00
DnsOverTlsMode link_get_dns_over_tls_mode ( Link * l ) {
2018-05-04 17:31:16 +02:00
assert ( l ) ;
2018-06-13 20:26:24 +02:00
if ( l - > dns_over_tls_mode ! = _DNS_OVER_TLS_MODE_INVALID )
return l - > dns_over_tls_mode ;
2018-05-04 17:31:16 +02:00
2018-06-13 20:26:24 +02:00
return manager_get_dns_over_tls_mode ( l - > manager ) ;
2018-05-04 17:31:16 +02:00
}
2016-01-19 21:48:01 +01:00
DnssecMode link_get_dnssec_mode ( Link * l ) {
assert ( l ) ;
if ( l - > dnssec_mode ! = _DNSSEC_MODE_INVALID )
return l - > dnssec_mode ;
return manager_get_dnssec_mode ( l - > manager ) ;
}
bool link_dnssec_supported ( Link * l ) {
DnsServer * server ;
assert ( l ) ;
if ( link_get_dnssec_mode ( l ) = = DNSSEC_NO )
return false ;
server = link_get_dns_server ( l ) ;
if ( server )
return dns_server_dnssec_supported ( server ) ;
return true ;
}
2022-11-04 12:53:07 +09:00
ResolveSupport link_get_llmnr_support ( Link * link ) {
assert ( link ) ;
assert ( link - > manager ) ;
/* This provides the effective LLMNR support level for the link, instead of the 'internal' per-link setting. */
return MIN ( link - > llmnr_support , link - > manager - > llmnr_support ) ;
}
ResolveSupport link_get_mdns_support ( Link * link ) {
assert ( link ) ;
assert ( link - > manager ) ;
/* This provides the effective mDNS support level for the link, instead of the 'internal' per-link setting. */
return MIN ( link - > mdns_support , link - > manager - > mdns_support ) ;
}
2023-03-27 09:43:58 -07:00
int link_address_new ( Link * l ,
LinkAddress * * ret ,
int family ,
const union in_addr_union * in_addr ,
const union in_addr_union * in_addr_broadcast ) {
2014-07-16 00:26:02 +02:00
LinkAddress * a ;
assert ( l ) ;
assert ( in_addr ) ;
2020-10-27 14:28:25 +01:00
a = new ( LinkAddress , 1 ) ;
2014-07-16 00:26:02 +02:00
if ( ! a )
return - ENOMEM ;
2020-10-27 14:28:25 +01:00
* a = ( LinkAddress ) {
. family = family ,
. in_addr = * in_addr ,
2023-03-27 09:43:58 -07:00
. in_addr_broadcast = * in_addr_broadcast ,
2020-10-27 14:28:25 +01:00
. link = l ,
2020-11-09 22:22:56 +01:00
. prefixlen = UCHAR_MAX ,
2020-10-27 14:28:25 +01:00
} ;
2014-07-16 00:26:02 +02:00
LIST_PREPEND ( addresses , l - > addresses , a ) ;
2017-02-13 20:41:09 +01:00
l - > n_addresses + + ;
2014-07-16 00:26:02 +02:00
if ( ret )
* ret = a ;
return 0 ;
}
LinkAddress * link_address_free ( LinkAddress * a ) {
if ( ! a )
return NULL ;
2014-07-29 14:24:02 +02:00
if ( a - > link ) {
2014-07-16 00:26:02 +02:00
LIST_REMOVE ( addresses , a - > link - > addresses , a ) ;
2017-02-13 20:41:09 +01:00
assert ( a - > link - > n_addresses > 0 ) ;
a - > link - > n_addresses - - ;
2014-07-29 14:24:02 +02:00
if ( a - > llmnr_address_rr ) {
if ( a - > family = = AF_INET & & a - > link - > llmnr_ipv4_scope )
dns_zone_remove_rr ( & a - > link - > llmnr_ipv4_scope - > zone , a - > llmnr_address_rr ) ;
else if ( a - > family = = AF_INET6 & & a - > link - > llmnr_ipv6_scope )
dns_zone_remove_rr ( & a - > link - > llmnr_ipv6_scope - > zone , a - > llmnr_address_rr ) ;
}
if ( a - > llmnr_ptr_rr ) {
if ( a - > family = = AF_INET & & a - > link - > llmnr_ipv4_scope )
dns_zone_remove_rr ( & a - > link - > llmnr_ipv4_scope - > zone , a - > llmnr_ptr_rr ) ;
else if ( a - > family = = AF_INET6 & & a - > link - > llmnr_ipv6_scope )
dns_zone_remove_rr ( & a - > link - > llmnr_ipv6_scope - > zone , a - > llmnr_ptr_rr ) ;
}
2016-12-02 11:58:00 +02:00
if ( a - > mdns_address_rr ) {
if ( a - > family = = AF_INET & & a - > link - > mdns_ipv4_scope )
dns_zone_remove_rr ( & a - > link - > mdns_ipv4_scope - > zone , a - > mdns_address_rr ) ;
else if ( a - > family = = AF_INET6 & & a - > link - > mdns_ipv6_scope )
dns_zone_remove_rr ( & a - > link - > mdns_ipv6_scope - > zone , a - > mdns_address_rr ) ;
}
if ( a - > mdns_ptr_rr ) {
if ( a - > family = = AF_INET & & a - > link - > mdns_ipv4_scope )
dns_zone_remove_rr ( & a - > link - > mdns_ipv4_scope - > zone , a - > mdns_ptr_rr ) ;
else if ( a - > family = = AF_INET6 & & a - > link - > mdns_ipv6_scope )
dns_zone_remove_rr ( & a - > link - > mdns_ipv6_scope - > zone , a - > mdns_ptr_rr ) ;
}
2014-07-29 14:24:02 +02:00
}
2014-07-31 17:46:40 +02:00
dns_resource_record_unref ( a - > llmnr_address_rr ) ;
dns_resource_record_unref ( a - > llmnr_ptr_rr ) ;
2016-12-02 11:58:00 +02:00
dns_resource_record_unref ( a - > mdns_address_rr ) ;
dns_resource_record_unref ( a - > mdns_ptr_rr ) ;
2014-07-31 17:46:40 +02:00
2016-10-16 18:28:30 -04:00
return mfree ( a ) ;
2014-07-16 00:26:02 +02:00
}
2014-07-31 17:46:40 +02:00
void link_address_add_rrs ( LinkAddress * a , bool force_remove ) {
2014-07-29 14:24:02 +02:00
int r ;
assert ( a ) ;
2014-07-31 17:46:40 +02:00
if ( a - > family = = AF_INET ) {
2014-07-29 14:24:02 +02:00
2014-08-01 16:04:12 +02:00
if ( ! force_remove & &
2016-02-01 00:00:01 +01:00
link_address_relevant ( a , true ) & &
2014-08-01 16:04:12 +02:00
a - > link - > llmnr_ipv4_scope & &
2022-11-04 12:53:07 +09:00
link_get_llmnr_support ( a - > link ) = = RESOLVE_SUPPORT_YES ) {
2014-08-01 16:04:12 +02:00
2015-08-17 23:54:08 +02:00
if ( ! a - > link - > manager - > llmnr_host_ipv4_key ) {
a - > link - > manager - > llmnr_host_ipv4_key = dns_resource_key_new ( DNS_CLASS_IN , DNS_TYPE_A , a - > link - > manager - > llmnr_hostname ) ;
if ( ! a - > link - > manager - > llmnr_host_ipv4_key ) {
2014-07-31 17:46:40 +02:00
r = - ENOMEM ;
goto fail ;
}
2014-07-29 14:24:02 +02:00
}
if ( ! a - > llmnr_address_rr ) {
2015-08-17 23:54:08 +02:00
a - > llmnr_address_rr = dns_resource_record_new ( a - > link - > manager - > llmnr_host_ipv4_key ) ;
2014-07-31 17:46:40 +02:00
if ( ! a - > llmnr_address_rr ) {
r = - ENOMEM ;
goto fail ;
}
a - > llmnr_address_rr - > a . in_addr = a - > in_addr . in ;
a - > llmnr_address_rr - > ttl = LLMNR_DEFAULT_TTL ;
2014-07-29 14:24:02 +02:00
}
2014-07-31 17:46:40 +02:00
if ( ! a - > llmnr_ptr_rr ) {
2015-08-17 23:54:08 +02:00
r = dns_resource_record_new_reverse ( & a - > llmnr_ptr_rr , a - > family , & a - > in_addr , a - > link - > manager - > llmnr_hostname ) ;
2014-07-31 17:46:40 +02:00
if ( r < 0 )
goto fail ;
2014-07-29 14:24:02 +02:00
2014-07-31 17:46:40 +02:00
a - > llmnr_ptr_rr - > ttl = LLMNR_DEFAULT_TTL ;
}
2014-07-29 14:24:02 +02:00
2014-07-31 17:46:40 +02:00
r = dns_zone_put ( & a - > link - > llmnr_ipv4_scope - > zone , a - > link - > llmnr_ipv4_scope , a - > llmnr_address_rr , true ) ;
2014-07-29 14:24:02 +02:00
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( a - > link , r , " Failed to add A record to LLMNR zone, ignoring: %m " ) ;
2014-07-29 14:24:02 +02:00
2014-07-31 17:46:40 +02:00
r = dns_zone_put ( & a - > link - > llmnr_ipv4_scope - > zone , a - > link - > llmnr_ipv4_scope , a - > llmnr_ptr_rr , false ) ;
2014-07-29 14:24:02 +02:00
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( a - > link , r , " Failed to add IPv4 PTR record to LLMNR zone, ignoring: %m " ) ;
2014-07-29 14:24:02 +02:00
} else {
2014-07-31 17:46:40 +02:00
if ( a - > llmnr_address_rr ) {
if ( a - > link - > llmnr_ipv4_scope )
dns_zone_remove_rr ( & a - > link - > llmnr_ipv4_scope - > zone , a - > llmnr_address_rr ) ;
a - > llmnr_address_rr = dns_resource_record_unref ( a - > llmnr_address_rr ) ;
}
if ( a - > llmnr_ptr_rr ) {
if ( a - > link - > llmnr_ipv4_scope )
dns_zone_remove_rr ( & a - > link - > llmnr_ipv4_scope - > zone , a - > llmnr_ptr_rr ) ;
a - > llmnr_ptr_rr = dns_resource_record_unref ( a - > llmnr_ptr_rr ) ;
}
2014-07-29 14:24:02 +02:00
}
2016-12-02 11:58:00 +02:00
if ( ! force_remove & &
link_address_relevant ( a , true ) & &
a - > link - > mdns_ipv4_scope & &
2022-11-04 12:53:07 +09:00
link_get_mdns_support ( a - > link ) = = RESOLVE_SUPPORT_YES ) {
2016-12-02 11:58:00 +02:00
if ( ! a - > link - > manager - > mdns_host_ipv4_key ) {
a - > link - > manager - > mdns_host_ipv4_key = dns_resource_key_new ( DNS_CLASS_IN , DNS_TYPE_A , a - > link - > manager - > mdns_hostname ) ;
if ( ! a - > link - > manager - > mdns_host_ipv4_key ) {
r = - ENOMEM ;
goto fail ;
}
}
if ( ! a - > mdns_address_rr ) {
a - > mdns_address_rr = dns_resource_record_new ( a - > link - > manager - > mdns_host_ipv4_key ) ;
if ( ! a - > mdns_address_rr ) {
r = - ENOMEM ;
goto fail ;
}
a - > mdns_address_rr - > a . in_addr = a - > in_addr . in ;
a - > mdns_address_rr - > ttl = MDNS_DEFAULT_TTL ;
}
if ( ! a - > mdns_ptr_rr ) {
r = dns_resource_record_new_reverse ( & a - > mdns_ptr_rr , a - > family , & a - > in_addr , a - > link - > manager - > mdns_hostname ) ;
if ( r < 0 )
goto fail ;
a - > mdns_ptr_rr - > ttl = MDNS_DEFAULT_TTL ;
}
r = dns_zone_put ( & a - > link - > mdns_ipv4_scope - > zone , a - > link - > mdns_ipv4_scope , a - > mdns_address_rr , true ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( a - > link , r , " Failed to add A record to MDNS zone, ignoring: %m " ) ;
2016-12-02 11:58:00 +02:00
r = dns_zone_put ( & a - > link - > mdns_ipv4_scope - > zone , a - > link - > mdns_ipv4_scope , a - > mdns_ptr_rr , false ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( a - > link , r , " Failed to add IPv4 PTR record to MDNS zone, ignoring: %m " ) ;
2016-12-02 11:58:00 +02:00
} else {
if ( a - > mdns_address_rr ) {
if ( a - > link - > mdns_ipv4_scope )
dns_zone_remove_rr ( & a - > link - > mdns_ipv4_scope - > zone , a - > mdns_address_rr ) ;
a - > mdns_address_rr = dns_resource_record_unref ( a - > mdns_address_rr ) ;
}
if ( a - > mdns_ptr_rr ) {
if ( a - > link - > mdns_ipv4_scope )
dns_zone_remove_rr ( & a - > link - > mdns_ipv4_scope - > zone , a - > mdns_ptr_rr ) ;
a - > mdns_ptr_rr = dns_resource_record_unref ( a - > mdns_ptr_rr ) ;
}
}
2014-07-29 14:24:02 +02:00
}
2014-07-31 17:46:40 +02:00
if ( a - > family = = AF_INET6 ) {
2014-07-29 14:24:02 +02:00
2014-08-01 16:04:12 +02:00
if ( ! force_remove & &
2016-02-01 00:00:01 +01:00
link_address_relevant ( a , true ) & &
2014-08-01 16:04:12 +02:00
a - > link - > llmnr_ipv6_scope & &
2022-11-04 12:53:07 +09:00
link_get_llmnr_support ( a - > link ) = = RESOLVE_SUPPORT_YES ) {
2014-08-01 16:04:12 +02:00
2015-08-17 23:54:08 +02:00
if ( ! a - > link - > manager - > llmnr_host_ipv6_key ) {
a - > link - > manager - > llmnr_host_ipv6_key = dns_resource_key_new ( DNS_CLASS_IN , DNS_TYPE_AAAA , a - > link - > manager - > llmnr_hostname ) ;
if ( ! a - > link - > manager - > llmnr_host_ipv6_key ) {
2014-07-31 17:46:40 +02:00
r = - ENOMEM ;
goto fail ;
}
2014-07-29 14:24:02 +02:00
}
if ( ! a - > llmnr_address_rr ) {
2015-08-17 23:54:08 +02:00
a - > llmnr_address_rr = dns_resource_record_new ( a - > link - > manager - > llmnr_host_ipv6_key ) ;
2014-07-31 17:46:40 +02:00
if ( ! a - > llmnr_address_rr ) {
r = - ENOMEM ;
goto fail ;
}
a - > llmnr_address_rr - > aaaa . in6_addr = a - > in_addr . in6 ;
a - > llmnr_address_rr - > ttl = LLMNR_DEFAULT_TTL ;
2014-07-29 14:24:02 +02:00
}
2014-07-31 17:46:40 +02:00
if ( ! a - > llmnr_ptr_rr ) {
2015-08-17 23:54:08 +02:00
r = dns_resource_record_new_reverse ( & a - > llmnr_ptr_rr , a - > family , & a - > in_addr , a - > link - > manager - > llmnr_hostname ) ;
2014-07-31 17:46:40 +02:00
if ( r < 0 )
goto fail ;
2014-07-29 14:24:02 +02:00
2014-07-31 17:46:40 +02:00
a - > llmnr_ptr_rr - > ttl = LLMNR_DEFAULT_TTL ;
}
2014-07-29 14:24:02 +02:00
2014-07-31 17:46:40 +02:00
r = dns_zone_put ( & a - > link - > llmnr_ipv6_scope - > zone , a - > link - > llmnr_ipv6_scope , a - > llmnr_address_rr , true ) ;
2014-07-29 14:24:02 +02:00
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( a - > link , r , " Failed to add AAAA record to LLMNR zone, ignoring: %m " ) ;
2014-07-29 14:24:02 +02:00
2014-07-31 17:46:40 +02:00
r = dns_zone_put ( & a - > link - > llmnr_ipv6_scope - > zone , a - > link - > llmnr_ipv6_scope , a - > llmnr_ptr_rr , false ) ;
2014-07-29 14:24:02 +02:00
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( a - > link , r , " Failed to add IPv6 PTR record to LLMNR zone, ignoring: %m " ) ;
2014-07-29 14:24:02 +02:00
} else {
2014-07-31 17:46:40 +02:00
if ( a - > llmnr_address_rr ) {
if ( a - > link - > llmnr_ipv6_scope )
dns_zone_remove_rr ( & a - > link - > llmnr_ipv6_scope - > zone , a - > llmnr_address_rr ) ;
a - > llmnr_address_rr = dns_resource_record_unref ( a - > llmnr_address_rr ) ;
}
if ( a - > llmnr_ptr_rr ) {
if ( a - > link - > llmnr_ipv6_scope )
dns_zone_remove_rr ( & a - > link - > llmnr_ipv6_scope - > zone , a - > llmnr_ptr_rr ) ;
a - > llmnr_ptr_rr = dns_resource_record_unref ( a - > llmnr_ptr_rr ) ;
}
2014-07-29 14:24:02 +02:00
}
2016-12-02 11:58:00 +02:00
if ( ! force_remove & &
link_address_relevant ( a , true ) & &
a - > link - > mdns_ipv6_scope & &
2022-11-04 12:53:07 +09:00
link_get_mdns_support ( a - > link ) = = RESOLVE_SUPPORT_YES ) {
2016-12-02 11:58:00 +02:00
if ( ! a - > link - > manager - > mdns_host_ipv6_key ) {
a - > link - > manager - > mdns_host_ipv6_key = dns_resource_key_new ( DNS_CLASS_IN , DNS_TYPE_AAAA , a - > link - > manager - > mdns_hostname ) ;
if ( ! a - > link - > manager - > mdns_host_ipv6_key ) {
r = - ENOMEM ;
goto fail ;
}
}
if ( ! a - > mdns_address_rr ) {
a - > mdns_address_rr = dns_resource_record_new ( a - > link - > manager - > mdns_host_ipv6_key ) ;
if ( ! a - > mdns_address_rr ) {
r = - ENOMEM ;
goto fail ;
}
a - > mdns_address_rr - > aaaa . in6_addr = a - > in_addr . in6 ;
a - > mdns_address_rr - > ttl = MDNS_DEFAULT_TTL ;
}
if ( ! a - > mdns_ptr_rr ) {
r = dns_resource_record_new_reverse ( & a - > mdns_ptr_rr , a - > family , & a - > in_addr , a - > link - > manager - > mdns_hostname ) ;
if ( r < 0 )
goto fail ;
a - > mdns_ptr_rr - > ttl = MDNS_DEFAULT_TTL ;
}
r = dns_zone_put ( & a - > link - > mdns_ipv6_scope - > zone , a - > link - > mdns_ipv6_scope , a - > mdns_address_rr , true ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( a - > link , r , " Failed to add AAAA record to MDNS zone, ignoring: %m " ) ;
2016-12-02 11:58:00 +02:00
r = dns_zone_put ( & a - > link - > mdns_ipv6_scope - > zone , a - > link - > mdns_ipv6_scope , a - > mdns_ptr_rr , false ) ;
if ( r < 0 )
2022-01-21 04:43:37 +09:00
log_link_warning_errno ( a - > link , r , " Failed to add IPv6 PTR record to MDNS zone, ignoring: %m " ) ;
2016-12-02 11:58:00 +02:00
} else {
if ( a - > mdns_address_rr ) {
if ( a - > link - > mdns_ipv6_scope )
dns_zone_remove_rr ( & a - > link - > mdns_ipv6_scope - > zone , a - > mdns_address_rr ) ;
a - > mdns_address_rr = dns_resource_record_unref ( a - > mdns_address_rr ) ;
}
if ( a - > mdns_ptr_rr ) {
if ( a - > link - > mdns_ipv6_scope )
dns_zone_remove_rr ( & a - > link - > mdns_ipv6_scope - > zone , a - > mdns_ptr_rr ) ;
a - > mdns_ptr_rr = dns_resource_record_unref ( a - > mdns_ptr_rr ) ;
}
}
2014-07-29 14:24:02 +02:00
}
return ;
fail :
2022-01-21 04:43:37 +09:00
log_link_debug_errno ( a - > link , r , " Failed to update address RRs, ignoring: %m " ) ;
2014-07-29 14:24:02 +02:00
}
2015-06-12 16:31:33 +02:00
int link_address_update_rtnl ( LinkAddress * a , sd_netlink_message * m ) {
2014-07-16 00:26:02 +02:00
int r ;
2020-11-09 22:22:56 +01:00
2014-07-16 00:26:02 +02:00
assert ( a ) ;
assert ( m ) ;
r = sd_rtnl_message_addr_get_flags ( m , & a - > flags ) ;
if ( r < 0 )
return r ;
2020-11-09 22:22:56 +01:00
( void ) sd_rtnl_message_addr_get_prefixlen ( m , & a - > prefixlen ) ;
( void ) sd_rtnl_message_addr_get_scope ( m , & a - > scope ) ;
2014-07-16 00:26:02 +02:00
2014-07-18 12:34:02 +02:00
link_allocate_scopes ( a - > link ) ;
2014-07-31 17:46:40 +02:00
link_add_rrs ( a - > link , false ) ;
2014-07-29 14:24:02 +02:00
2014-07-16 00:26:02 +02:00
return 0 ;
}
2016-02-01 00:00:01 +01:00
bool link_address_relevant ( LinkAddress * a , bool local_multicast ) {
2014-07-16 00:26:02 +02:00
assert ( a ) ;
2014-08-05 04:18:23 +02:00
if ( a - > flags & ( IFA_F_DEPRECATED | IFA_F_TENTATIVE ) )
2014-07-16 00:26:02 +02:00
return false ;
2016-02-01 00:00:01 +01:00
if ( a - > scope > = ( local_multicast ? RT_SCOPE_HOST : RT_SCOPE_LINK ) )
2014-07-16 00:26:02 +02:00
return false ;
return true ;
}
2016-06-15 22:38:23 +02:00
static bool link_needs_save ( Link * l ) {
assert ( l ) ;
/* Returns true if any of the settings where set different from the default */
if ( l - > is_managed )
return false ;
if ( l - > llmnr_support ! = RESOLVE_SUPPORT_YES | |
2022-11-04 12:06:21 +09:00
l - > mdns_support ! = RESOLVE_SUPPORT_YES | |
2018-12-04 13:49:03 +01:00
l - > dnssec_mode ! = _DNSSEC_MODE_INVALID | |
l - > dns_over_tls_mode ! = _DNS_OVER_TLS_MODE_INVALID )
2016-06-15 22:38:23 +02:00
return true ;
if ( l - > dns_servers | |
l - > search_domains )
return true ;
if ( ! set_isempty ( l - > dnssec_negative_trust_anchors ) )
return true ;
2018-12-04 12:40:07 +01:00
if ( l - > default_route > = 0 )
return true ;
2016-06-15 22:38:23 +02:00
return false ;
}
int link_save_user ( Link * l ) {
2023-02-22 23:13:31 +01:00
_cleanup_ ( unlink_and_freep ) char * temp_path = NULL ;
2016-06-15 22:38:23 +02:00
_cleanup_fclose_ FILE * f = NULL ;
const char * v ;
int r ;
assert ( l ) ;
assert ( l - > state_file ) ;
if ( ! link_needs_save ( l ) ) {
( void ) unlink ( l - > state_file ) ;
return 0 ;
}
r = mkdir_parents ( l - > state_file , 0700 ) ;
if ( r < 0 )
goto fail ;
r = fopen_temporary ( l - > state_file , & f , & temp_path ) ;
if ( r < 0 )
goto fail ;
2017-12-11 19:50:30 +01:00
( void ) fchmod ( fileno ( f ) , 0644 ) ;
fputs ( " # This is private data. Do not parse. \n " , f ) ;
2016-06-15 22:38:23 +02:00
v = resolve_support_to_string ( l - > llmnr_support ) ;
if ( v )
fprintf ( f , " LLMNR=%s \n " , v ) ;
v = resolve_support_to_string ( l - > mdns_support ) ;
if ( v )
fprintf ( f , " MDNS=%s \n " , v ) ;
v = dnssec_mode_to_string ( l - > dnssec_mode ) ;
if ( v )
fprintf ( f , " DNSSEC=%s \n " , v ) ;
2022-09-27 21:48:48 +07:00
v = dns_over_tls_mode_to_string ( l - > dns_over_tls_mode ) ;
if ( v )
fprintf ( f , " DNSOVERTLS=%s \n " , v ) ;
2018-12-04 12:40:07 +01:00
if ( l - > default_route > = 0 )
fprintf ( f , " DEFAULT_ROUTE=%s \n " , yes_no ( l - > default_route ) ) ;
2016-06-15 22:38:23 +02:00
if ( l - > dns_servers ) {
2017-12-11 19:50:30 +01:00
fputs ( " SERVERS= " , f ) ;
2016-06-15 22:38:23 +02:00
LIST_FOREACH ( servers , server , l - > dns_servers ) {
if ( server ! = l - > dns_servers )
2017-12-11 19:50:30 +01:00
fputc ( ' ' , f ) ;
2016-06-15 22:38:23 +02:00
2020-07-13 09:29:14 +09:00
v = dns_server_string_full ( server ) ;
2016-06-15 22:38:23 +02:00
if ( ! v ) {
r = - ENOMEM ;
goto fail ;
}
2017-12-11 19:50:30 +01:00
fputs ( v , f ) ;
2016-06-15 22:38:23 +02:00
}
2017-12-11 19:50:30 +01:00
fputc ( ' \n ' , f ) ;
2016-06-15 22:38:23 +02:00
}
if ( l - > search_domains ) {
2017-12-11 19:50:30 +01:00
fputs ( " DOMAINS= " , f ) ;
2016-06-15 22:38:23 +02:00
LIST_FOREACH ( domains , domain , l - > search_domains ) {
if ( domain ! = l - > search_domains )
2017-12-11 19:50:30 +01:00
fputc ( ' ' , f ) ;
2016-06-15 22:38:23 +02:00
if ( domain - > route_only )
2017-12-11 19:50:30 +01:00
fputc ( ' ~ ' , f ) ;
2016-06-15 22:38:23 +02:00
2017-12-11 19:50:30 +01:00
fputs ( DNS_SEARCH_DOMAIN_NAME ( domain ) , f ) ;
2016-06-15 22:38:23 +02:00
}
2017-12-11 19:50:30 +01:00
fputc ( ' \n ' , f ) ;
2016-06-15 22:38:23 +02:00
}
if ( ! set_isempty ( l - > dnssec_negative_trust_anchors ) ) {
bool space = false ;
char * nta ;
2017-12-11 19:50:30 +01:00
fputs ( " NTAS= " , f ) ;
2020-09-08 11:58:29 +02:00
SET_FOREACH ( nta , l - > dnssec_negative_trust_anchors ) {
2016-06-15 22:38:23 +02:00
if ( space )
2017-12-11 19:50:30 +01:00
fputc ( ' ' , f ) ;
2016-06-15 22:38:23 +02:00
2017-12-11 19:50:30 +01:00
fputs ( nta , f ) ;
2016-06-15 22:38:23 +02:00
space = true ;
}
2017-12-11 19:50:30 +01:00
fputc ( ' \n ' , f ) ;
2016-06-15 22:38:23 +02:00
}
r = fflush_and_check ( f ) ;
if ( r < 0 )
goto fail ;
if ( rename ( temp_path , l - > state_file ) < 0 ) {
r = - errno ;
goto fail ;
}
2023-02-22 23:13:31 +01:00
temp_path = mfree ( temp_path ) ;
2016-06-15 22:38:23 +02:00
return 0 ;
fail :
( void ) unlink ( l - > state_file ) ;
2022-01-21 04:43:37 +09:00
return log_link_error_errno ( l , r , " Failed to save link data %s: %m " , l - > state_file ) ;
2016-06-15 22:38:23 +02:00
}
int link_load_user ( Link * l ) {
_cleanup_free_ char
* llmnr = NULL ,
* mdns = NULL ,
* dnssec = NULL ,
2022-09-27 21:48:48 +07:00
* dns_over_tls = NULL ,
2016-06-15 22:38:23 +02:00
* servers = NULL ,
* domains = NULL ,
2018-12-04 12:40:07 +01:00
* ntas = NULL ,
* default_route = NULL ;
2016-06-15 22:38:23 +02:00
ResolveSupport s ;
2016-11-11 12:58:41 -05:00
const char * p ;
2016-06-15 22:38:23 +02:00
int r ;
assert ( l ) ;
assert ( l - > state_file ) ;
/* Try to load only a single time */
if ( l - > loaded )
return 0 ;
l - > loaded = true ;
if ( l - > is_managed )
return 0 ; /* if the device is managed, then networkd is our configuration source, not the bus API */
2018-11-12 14:04:47 +01:00
r = parse_env_file ( NULL , l - > state_file ,
2016-06-15 22:38:23 +02:00
" LLMNR " , & llmnr ,
" MDNS " , & mdns ,
" DNSSEC " , & dnssec ,
2022-09-27 21:48:48 +07:00
" DNSOVERTLS " , & dns_over_tls ,
2016-06-15 22:38:23 +02:00
" SERVERS " , & servers ,
" DOMAINS " , & domains ,
2018-12-04 12:40:07 +01:00
" NTAS " , & ntas ,
" DEFAULT_ROUTE " , & default_route ) ;
2016-06-15 22:38:23 +02:00
if ( r = = - ENOENT )
return 0 ;
if ( r < 0 )
goto fail ;
link_flush_settings ( l ) ;
/* If we can't recognize the LLMNR or MDNS setting we don't override the default */
s = resolve_support_from_string ( llmnr ) ;
if ( s > = 0 )
l - > llmnr_support = s ;
s = resolve_support_from_string ( mdns ) ;
if ( s > = 0 )
l - > mdns_support = s ;
2018-12-04 12:40:07 +01:00
r = parse_boolean ( default_route ) ;
if ( r > = 0 )
l - > default_route = r ;
2016-06-15 22:38:23 +02:00
/* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
l - > dnssec_mode = dnssec_mode_from_string ( dnssec ) ;
2022-09-27 21:48:48 +07:00
/* Same for DNSOverTLS */
l - > dns_over_tls_mode = dns_over_tls_mode_from_string ( dns_over_tls ) ;
2016-11-11 12:58:41 -05:00
for ( p = servers ; ; ) {
_cleanup_free_ char * word = NULL ;
2016-06-15 22:38:23 +02:00
2016-11-11 12:58:41 -05:00
r = extract_first_word ( & p , & word , NULL , 0 ) ;
if ( r < 0 )
goto fail ;
if ( r = = 0 )
break ;
2016-06-15 22:38:23 +02:00
2016-11-11 12:58:41 -05:00
r = link_update_dns_server_one ( l , word ) ;
if ( r < 0 ) {
2022-01-21 04:43:37 +09:00
log_link_debug_errno ( l , r , " Failed to load DNS server '%s', ignoring: %m " , word ) ;
2016-11-11 12:58:41 -05:00
continue ;
2016-06-15 22:38:23 +02:00
}
}
2016-11-11 12:58:41 -05:00
for ( p = domains ; ; ) {
_cleanup_free_ char * word = NULL ;
const char * n ;
bool is_route ;
2016-06-15 22:38:23 +02:00
2016-11-11 12:58:41 -05:00
r = extract_first_word ( & p , & word , NULL , 0 ) ;
if ( r < 0 )
goto fail ;
if ( r = = 0 )
break ;
2016-06-15 22:38:23 +02:00
2016-11-11 12:58:41 -05:00
is_route = word [ 0 ] = = ' ~ ' ;
n = is_route ? word + 1 : word ;
2016-06-15 22:38:23 +02:00
2016-11-11 12:58:41 -05:00
r = link_update_search_domain_one ( l , n , is_route ) ;
if ( r < 0 ) {
2022-01-21 04:43:37 +09:00
log_link_debug_errno ( l , r , " Failed to load search domain '%s', ignoring: %m " , word ) ;
2016-11-11 12:58:41 -05:00
continue ;
2016-06-15 22:38:23 +02:00
}
}
if ( ntas ) {
_cleanup_set_free_free_ Set * ns = NULL ;
ns = set_new ( & dns_name_hash_ops ) ;
if ( ! ns ) {
r = - ENOMEM ;
goto fail ;
}
r = set_put_strsplit ( ns , ntas , NULL , 0 ) ;
if ( r < 0 )
goto fail ;
2018-03-22 16:53:26 +01:00
l - > dnssec_negative_trust_anchors = TAKE_PTR ( ns ) ;
2016-06-15 22:38:23 +02:00
}
return 0 ;
fail :
2022-01-21 04:43:37 +09:00
return log_link_error_errno ( l , r , " Failed to load link data %s: %m " , l - > state_file ) ;
2016-06-15 22:38:23 +02:00
}
void link_remove_user ( Link * l ) {
assert ( l ) ;
assert ( l - > state_file ) ;
( void ) unlink ( l - > state_file ) ;
}
2020-11-17 18:31:53 +01:00
bool link_negative_trust_anchor_lookup ( Link * l , const char * name ) {
int r ;
assert ( l ) ;
assert ( name ) ;
/* Checks whether the specified domain (or any of its parent domains) are listed as per-link NTA. */
for ( ; ; ) {
if ( set_contains ( l - > dnssec_negative_trust_anchors , name ) )
return true ;
/* And now, let's look at the parent, and check that too */
r = dns_name_parent ( & name ) ;
if ( r < 0 )
return r ;
if ( r = = 0 )
break ;
}
return false ;
}