From: Yu Watanabe Date: Mon, 15 Apr 2024 06:15:09 +0000 (+0900) Subject: network: move DNS related conf parsers to networkd-dns.[ch] X-Git-Tag: v256-rc1~122^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=54bb2c0e61ef85a1be53f0e74b18411d18080ea0;p=thirdparty%2Fsystemd.git network: move DNS related conf parsers to networkd-dns.[ch] No functional change, just refactoring. --- diff --git a/src/network/meson.build b/src/network/meson.build index 14810ddb75f..75a7dfdf5bd 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -47,6 +47,7 @@ sources = files( 'networkd-dhcp4.c', 'networkd-dhcp6-bus.c', 'networkd-dhcp6.c', + 'networkd-dns.c', 'networkd-ipv4acd.c', 'networkd-ipv4ll.c', 'networkd-ipv6-proxy-ndp.c', diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index fb578fe7145..ec52ab93c44 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -530,107 +530,6 @@ int config_parse_dhcp_send_hostname( return 0; } -int config_parse_dhcp_use_dns( - const char* unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *network = userdata; - int r; - - assert(filename); - assert(lvalue); - assert(IN_SET(ltype, AF_UNSPEC, AF_INET, AF_INET6)); - assert(rvalue); - assert(data); - - r = parse_boolean(rvalue); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to parse UseDNS=%s, ignoring assignment: %m", rvalue); - return 0; - } - - switch (ltype) { - case AF_INET: - network->dhcp_use_dns = r; - network->dhcp_use_dns_set = true; - break; - case AF_INET6: - network->dhcp6_use_dns = r; - network->dhcp6_use_dns_set = true; - break; - case AF_UNSPEC: - /* For backward compatibility. */ - if (!network->dhcp_use_dns_set) - network->dhcp_use_dns = r; - if (!network->dhcp6_use_dns_set) - network->dhcp6_use_dns = r; - break; - default: - assert_not_reached(); - } - - return 0; -} - -int config_parse_dhcp_use_domains( - const char* unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *network = userdata; - UseDomains d; - - assert(filename); - assert(lvalue); - assert(IN_SET(ltype, AF_UNSPEC, AF_INET, AF_INET6)); - assert(rvalue); - assert(data); - - d = use_domains_from_string(rvalue); - if (d < 0) { - log_syntax(unit, LOG_WARNING, filename, line, d, - "Failed to parse %s=%s, ignoring assignment: %m", lvalue, rvalue); - return 0; - } - - switch (ltype) { - case AF_INET: - network->dhcp_use_domains = d; - network->dhcp_use_domains_set = true; - break; - case AF_INET6: - network->dhcp6_use_domains = d; - network->dhcp6_use_domains_set = true; - break; - case AF_UNSPEC: - /* For backward compatibility. */ - if (!network->dhcp_use_domains_set) - network->dhcp_use_domains = d; - if (!network->dhcp6_use_domains_set) - network->dhcp6_use_domains = d; - break; - default: - assert_not_reached(); - } - - return 0; -} int config_parse_dhcp_use_ntp( const char* unit, @@ -1137,15 +1036,6 @@ int config_parse_dhcp_request_options( } } -static const char* const use_domains_table[_USE_DOMAINS_MAX] = { - [USE_DOMAINS_NO] = "no", - [USE_DOMAINS_ROUTE] = "route", - [USE_DOMAINS_YES] = "yes", -}; - -DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(use_domains, UseDomains, USE_DOMAINS_YES); -DEFINE_CONFIG_PARSE_ENUM(config_parse_use_domains, use_domains, UseDomains, "Failed to parse UseDomains=") - static const char * const dhcp_option_data_type_table[_DHCP_OPTION_DATA_MAX] = { [DHCP_OPTION_DATA_UINT8] = "uint8", [DHCP_OPTION_DATA_UINT16] = "uint16", diff --git a/src/network/networkd-dhcp-common.h b/src/network/networkd-dhcp-common.h index 880429960a7..79c18f998e0 100644 --- a/src/network/networkd-dhcp-common.h +++ b/src/network/networkd-dhcp-common.h @@ -24,14 +24,6 @@ typedef struct Link Link; typedef struct Manager Manager; typedef struct Network Network; -typedef enum UseDomains { - USE_DOMAINS_NO, - USE_DOMAINS_YES, - USE_DOMAINS_ROUTE, - _USE_DOMAINS_MAX, - _USE_DOMAINS_INVALID = -EINVAL, -} UseDomains; - typedef enum DHCPOptionDataType { DHCP_OPTION_DATA_UINT8, DHCP_OPTION_DATA_UINT16, @@ -87,9 +79,6 @@ static inline bool in6_prefix_is_filtered(const struct in6_addr *prefix, uint8_t int link_get_captive_portal(Link *link, const char **ret); -const char* use_domains_to_string(UseDomains p) _const_; -UseDomains use_domains_from_string(const char *s) _pure_; - const char *dhcp_option_data_type_to_string(DHCPOptionDataType d) _const_; DHCPOptionDataType dhcp_option_data_type_from_string(const char *d) _pure_; @@ -97,9 +86,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_route_metric); CONFIG_PARSER_PROTOTYPE(config_parse_ndisc_route_metric); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_hostname); -CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_dns); -CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_domains); -CONFIG_PARSER_PROTOTYPE(config_parse_use_domains); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_iaid); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_or_ra_route_table); diff --git a/src/network/networkd-dns.c b/src/network/networkd-dns.c new file mode 100644 index 00000000000..9fa330a452b --- /dev/null +++ b/src/network/networkd-dns.c @@ -0,0 +1,309 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "dns-domain.h" +#include "hostname-util.h" +#include "networkd-dns.h" +#include "networkd-network.h" +#include "parse-util.h" +#include "string-table.h" + +int config_parse_domains( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *n = ASSERT_PTR(userdata); + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + n->search_domains = ordered_set_free(n->search_domains); + n->route_domains = ordered_set_free(n->route_domains); + return 0; + } + + for (const char *p = rvalue;;) { + _cleanup_free_ char *w = NULL, *normalized = NULL; + const char *domain; + bool is_route; + + r = extract_first_word(&p, &w, NULL, 0); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to extract search or route domain, ignoring: %s", rvalue); + return 0; + } + if (r == 0) + return 0; + + is_route = w[0] == '~'; + domain = is_route ? w + 1 : w; + + if (dns_name_is_root(domain) || streq(domain, "*")) { + /* If the root domain appears as is, or the special token "*" is found, we'll + * consider this as routing domain, unconditionally. */ + is_route = true; + domain = "."; /* make sure we don't allow empty strings, thus write the root + * domain as "." */ + } else { + r = dns_name_normalize(domain, 0, &normalized); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "'%s' is not a valid domain name, ignoring.", domain); + continue; + } + + domain = normalized; + + if (is_localhost(domain)) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s", + domain); + continue; + } + } + + OrderedSet **set = is_route ? &n->route_domains : &n->search_domains; + r = ordered_set_put_strdup(set, domain); + if (r == -EEXIST) + continue; + if (r < 0) + return log_oom(); + } +} + +int config_parse_dns( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *n = ASSERT_PTR(userdata); + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + for (unsigned i = 0; i < n->n_dns; i++) + in_addr_full_free(n->dns[i]); + n->dns = mfree(n->dns); + n->n_dns = 0; + return 0; + } + + for (const char *p = rvalue;;) { + _cleanup_(in_addr_full_freep) struct in_addr_full *dns = NULL; + _cleanup_free_ char *w = NULL; + struct in_addr_full **m; + + r = extract_first_word(&p, &w, NULL, 0); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Invalid syntax, ignoring: %s", rvalue); + return 0; + } + if (r == 0) + return 0; + + r = in_addr_full_new_from_string(w, &dns); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to parse dns server address, ignoring: %s", w); + continue; + } + + if (IN_SET(dns->port, 53, 853)) + dns->port = 0; + + m = reallocarray(n->dns, n->n_dns + 1, sizeof(struct in_addr_full*)); + if (!m) + return log_oom(); + + m[n->n_dns++] = TAKE_PTR(dns); + n->dns = m; + } +} + +int config_parse_dnssec_negative_trust_anchors( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Set **nta = ASSERT_PTR(data); + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + *nta = set_free_free(*nta); + return 0; + } + + for (const char *p = rvalue;;) { + _cleanup_free_ char *w = NULL; + + r = extract_first_word(&p, &w, NULL, 0); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to extract negative trust anchor domain, ignoring: %s", rvalue); + return 0; + } + if (r == 0) + return 0; + + r = dns_name_is_valid(w); + if (r <= 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "%s is not a valid domain name, ignoring.", w); + continue; + } + + r = set_ensure_consume(nta, &dns_name_hash_ops, TAKE_PTR(w)); + if (r < 0) + return log_oom(); + } +} + +int config_parse_dhcp_use_dns( + const char* unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = userdata; + int r; + + assert(filename); + assert(lvalue); + assert(IN_SET(ltype, AF_UNSPEC, AF_INET, AF_INET6)); + assert(rvalue); + assert(data); + + r = parse_boolean(rvalue); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to parse UseDNS=%s, ignoring assignment: %m", rvalue); + return 0; + } + + switch (ltype) { + case AF_INET: + network->dhcp_use_dns = r; + network->dhcp_use_dns_set = true; + break; + case AF_INET6: + network->dhcp6_use_dns = r; + network->dhcp6_use_dns_set = true; + break; + case AF_UNSPEC: + /* For backward compatibility. */ + if (!network->dhcp_use_dns_set) + network->dhcp_use_dns = r; + if (!network->dhcp6_use_dns_set) + network->dhcp6_use_dns = r; + break; + default: + assert_not_reached(); + } + + return 0; +} + +int config_parse_dhcp_use_domains( + const char* unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = userdata; + UseDomains d; + + assert(filename); + assert(lvalue); + assert(IN_SET(ltype, AF_UNSPEC, AF_INET, AF_INET6)); + assert(rvalue); + assert(data); + + d = use_domains_from_string(rvalue); + if (d < 0) { + log_syntax(unit, LOG_WARNING, filename, line, d, + "Failed to parse %s=%s, ignoring assignment: %m", lvalue, rvalue); + return 0; + } + + switch (ltype) { + case AF_INET: + network->dhcp_use_domains = d; + network->dhcp_use_domains_set = true; + break; + case AF_INET6: + network->dhcp6_use_domains = d; + network->dhcp6_use_domains_set = true; + break; + case AF_UNSPEC: + /* For backward compatibility. */ + if (!network->dhcp_use_domains_set) + network->dhcp_use_domains = d; + if (!network->dhcp6_use_domains_set) + network->dhcp6_use_domains = d; + break; + default: + assert_not_reached(); + } + + return 0; +} + +static const char* const use_domains_table[_USE_DOMAINS_MAX] = { + [USE_DOMAINS_NO] = "no", + [USE_DOMAINS_ROUTE] = "route", + [USE_DOMAINS_YES] = "yes", +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(use_domains, UseDomains, USE_DOMAINS_YES); +DEFINE_CONFIG_PARSE_ENUM(config_parse_use_domains, use_domains, UseDomains, "Failed to parse UseDomains=") diff --git a/src/network/networkd-dns.h b/src/network/networkd-dns.h new file mode 100644 index 00000000000..f458aa86c7b --- /dev/null +++ b/src/network/networkd-dns.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "conf-parser.h" +#include "macro.h" + +typedef enum UseDomains { + USE_DOMAINS_NO, + USE_DOMAINS_YES, + USE_DOMAINS_ROUTE, + _USE_DOMAINS_MAX, + _USE_DOMAINS_INVALID = -EINVAL, +} UseDomains; + +const char* use_domains_to_string(UseDomains p) _const_; +UseDomains use_domains_from_string(const char *s) _pure_; + +CONFIG_PARSER_PROTOTYPE(config_parse_domains); +CONFIG_PARSER_PROTOTYPE(config_parse_dns); +CONFIG_PARSER_PROTOTYPE(config_parse_dnssec_negative_trust_anchors); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_dns); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_domains); +CONFIG_PARSER_PROTOTYPE(config_parse_use_domains); diff --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf index 8bd75d9e3bc..b2d116e98de 100644 --- a/src/network/networkd-gperf.gperf +++ b/src/network/networkd-gperf.gperf @@ -7,6 +7,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") #include "conf-parser.h" #include "networkd-conf.h" #include "networkd-dhcp-common.h" +#include "networkd-dns.h" #include "networkd-manager.h" #include "networkd-route-util.h" %} diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 79d577b3b5d..5261482212d 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -20,6 +20,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") #include "networkd-dhcp-server.h" #include "networkd-dhcp4.h" #include "networkd-dhcp6.h" +#include "networkd-dns.h" #include "networkd-ipv4ll.h" #include "networkd-ipv6-proxy-ndp.h" #include "networkd-ipv6ll.h" diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 833f1bd059c..7020741aa1d 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -922,83 +922,6 @@ int config_parse_stacked_netdev( return 0; } -int config_parse_domains( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *n = ASSERT_PTR(userdata); - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - - if (isempty(rvalue)) { - n->search_domains = ordered_set_free(n->search_domains); - n->route_domains = ordered_set_free(n->route_domains); - return 0; - } - - for (const char *p = rvalue;;) { - _cleanup_free_ char *w = NULL, *normalized = NULL; - const char *domain; - bool is_route; - - r = extract_first_word(&p, &w, NULL, 0); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to extract search or route domain, ignoring: %s", rvalue); - return 0; - } - if (r == 0) - return 0; - - is_route = w[0] == '~'; - domain = is_route ? w + 1 : w; - - if (dns_name_is_root(domain) || streq(domain, "*")) { - /* If the root domain appears as is, or the special token "*" is found, we'll - * consider this as routing domain, unconditionally. */ - is_route = true; - domain = "."; /* make sure we don't allow empty strings, thus write the root - * domain as "." */ - } else { - r = dns_name_normalize(domain, 0, &normalized); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "'%s' is not a valid domain name, ignoring.", domain); - continue; - } - - domain = normalized; - - if (is_localhost(domain)) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s", - domain); - continue; - } - } - - OrderedSet **set = is_route ? &n->route_domains : &n->search_domains; - r = ordered_set_put_strdup(set, domain); - if (r == -EEXIST) - continue; - if (r < 0) - return log_oom(); - } -} - int config_parse_timezone( const char *unit, const char *filename, @@ -1033,119 +956,6 @@ int config_parse_timezone( return free_and_strdup_warn(tz, rvalue); } -int config_parse_dns( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *n = ASSERT_PTR(userdata); - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - - if (isempty(rvalue)) { - for (unsigned i = 0; i < n->n_dns; i++) - in_addr_full_free(n->dns[i]); - n->dns = mfree(n->dns); - n->n_dns = 0; - return 0; - } - - for (const char *p = rvalue;;) { - _cleanup_(in_addr_full_freep) struct in_addr_full *dns = NULL; - _cleanup_free_ char *w = NULL; - struct in_addr_full **m; - - r = extract_first_word(&p, &w, NULL, 0); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Invalid syntax, ignoring: %s", rvalue); - return 0; - } - if (r == 0) - return 0; - - r = in_addr_full_new_from_string(w, &dns); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to parse dns server address, ignoring: %s", w); - continue; - } - - if (IN_SET(dns->port, 53, 853)) - dns->port = 0; - - m = reallocarray(n->dns, n->n_dns + 1, sizeof(struct in_addr_full*)); - if (!m) - return log_oom(); - - m[n->n_dns++] = TAKE_PTR(dns); - n->dns = m; - } -} - -int config_parse_dnssec_negative_trust_anchors( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Set **nta = ASSERT_PTR(data); - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - - if (isempty(rvalue)) { - *nta = set_free_free(*nta); - return 0; - } - - for (const char *p = rvalue;;) { - _cleanup_free_ char *w = NULL; - - r = extract_first_word(&p, &w, NULL, 0); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to extract negative trust anchor domain, ignoring: %s", rvalue); - return 0; - } - if (r == 0) - return 0; - - r = dns_name_is_valid(w); - if (r <= 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "%s is not a valid domain name, ignoring.", w); - continue; - } - - r = set_ensure_consume(nta, &dns_name_hash_ops, TAKE_PTR(w)); - if (r < 0) - return log_oom(); - } -} - int config_parse_ntp( const char *unit, const char *filename, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 807aa48bb68..5b30b8e056a 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -20,6 +20,7 @@ #include "networkd-dhcp-common.h" #include "networkd-dhcp4.h" #include "networkd-dhcp6.h" +#include "networkd-dns.h" #include "networkd-ipv6ll.h" #include "networkd-lldp-rx.h" #include "networkd-ndisc.h" @@ -424,10 +425,7 @@ bool network_has_static_ipv6_configurations(Network *network); CONFIG_PARSER_PROTOTYPE(config_parse_stacked_netdev); CONFIG_PARSER_PROTOTYPE(config_parse_tunnel); -CONFIG_PARSER_PROTOTYPE(config_parse_domains); -CONFIG_PARSER_PROTOTYPE(config_parse_dns); CONFIG_PARSER_PROTOTYPE(config_parse_timezone); -CONFIG_PARSER_PROTOTYPE(config_parse_dnssec_negative_trust_anchors); CONFIG_PARSER_PROTOTYPE(config_parse_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online); CONFIG_PARSER_PROTOTYPE(config_parse_required_family_for_online);