mirror of
https://github.com/systemd/systemd.git
synced 2024-12-26 03:22:00 +03:00
Merge pull request #11776 from keszybz/networkd-ordered-sets
Store domains lists in OrderedSets in networkd
This commit is contained in:
commit
953a1af082
@ -1536,7 +1536,6 @@ void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **r
|
||||
}
|
||||
|
||||
unsigned internal_hashmap_size(HashmapBase *h) {
|
||||
|
||||
if (!h)
|
||||
return 0;
|
||||
|
||||
@ -1544,7 +1543,6 @@ unsigned internal_hashmap_size(HashmapBase *h) {
|
||||
}
|
||||
|
||||
unsigned internal_hashmap_buckets(HashmapBase *h) {
|
||||
|
||||
if (!h)
|
||||
return 0;
|
||||
|
||||
@ -1904,8 +1902,7 @@ IteratedCache *iterated_cache_free(IteratedCache *cache) {
|
||||
if (cache) {
|
||||
free(cache->keys.ptr);
|
||||
free(cache->values.ptr);
|
||||
free(cache);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return mfree(cache);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include "fileio.h"
|
||||
#include "ordered-set.h"
|
||||
#include "strv.h"
|
||||
|
||||
@ -45,3 +46,37 @@ int ordered_set_put_strdupv(OrderedSet *s, char **l) {
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int ordered_set_put_string_set(OrderedSet *s, OrderedSet *l) {
|
||||
int n = 0, r;
|
||||
Iterator i;
|
||||
char *p;
|
||||
|
||||
/* Like ordered_set_put_strv, but for an OrderedSet of strings */
|
||||
|
||||
ORDERED_SET_FOREACH(p, l, i) {
|
||||
r = ordered_set_put_strdup(s, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n += r;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void ordered_set_print(FILE *f, const char *field, OrderedSet *s) {
|
||||
bool space = false;
|
||||
Iterator i;
|
||||
char *p;
|
||||
|
||||
if (ordered_set_isempty(s))
|
||||
return;
|
||||
|
||||
fputs(field, f);
|
||||
|
||||
ORDERED_SET_FOREACH(p, s, i)
|
||||
fputs_with_space(f, p, NULL, &space);
|
||||
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hashmap.h"
|
||||
|
||||
typedef struct OrderedSet OrderedSet;
|
||||
@ -48,9 +50,15 @@ static inline void* ordered_set_steal_first(OrderedSet *s) {
|
||||
return ordered_hashmap_steal_first((OrderedHashmap*) s);
|
||||
}
|
||||
|
||||
static inline char **ordered_set_get_strv(OrderedSet *s) {
|
||||
return internal_hashmap_get_strv(HASHMAP_BASE((OrderedHashmap*) s));
|
||||
}
|
||||
|
||||
int ordered_set_consume(OrderedSet *s, void *p);
|
||||
int ordered_set_put_strdup(OrderedSet *s, const char *p);
|
||||
int ordered_set_put_strdupv(OrderedSet *s, char **l);
|
||||
int ordered_set_put_string_set(OrderedSet *s, OrderedSet *l);
|
||||
void ordered_set_print(FILE *f, const char *field, OrderedSet *s);
|
||||
|
||||
#define ORDERED_SET_FOREACH(e, s, i) \
|
||||
for ((i) = ITERATOR_FIRST; ordered_set_iterate((s), &(i), (void**)&(e)); )
|
||||
|
@ -4057,9 +4057,7 @@ int link_save(Link *link) {
|
||||
(void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
|
||||
}
|
||||
|
||||
fputs("DOMAINS=", f);
|
||||
space = false;
|
||||
fputstrv(f, link->network->search_domains, NULL, &space);
|
||||
ordered_set_print(f, "DOMAINS=", link->network->search_domains);
|
||||
|
||||
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) {
|
||||
NDiscDNSSL *dd;
|
||||
@ -4077,9 +4075,7 @@ int link_save(Link *link) {
|
||||
|
||||
fputc('\n', f);
|
||||
|
||||
fputs("ROUTE_DOMAINS=", f);
|
||||
space = false;
|
||||
fputstrv(f, link->network->route_domains, NULL, &space);
|
||||
ordered_set_print(f, "ROUTE_DOMAINS=", link->network->route_domains);
|
||||
|
||||
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE) {
|
||||
NDiscDNSSL *dd;
|
||||
|
@ -1060,22 +1060,6 @@ static int ordered_set_put_in4_addrv(OrderedSet *s,
|
||||
return c;
|
||||
}
|
||||
|
||||
static void print_string_set(FILE *f, const char *field, OrderedSet *s) {
|
||||
bool space = false;
|
||||
Iterator i;
|
||||
char *p;
|
||||
|
||||
if (ordered_set_isempty(s))
|
||||
return;
|
||||
|
||||
fputs(field, f);
|
||||
|
||||
ORDERED_SET_FOREACH(p, s, i)
|
||||
fputs_with_space(f, p, NULL, &space);
|
||||
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
static int manager_save(Manager *m) {
|
||||
_cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *search_domains = NULL, *route_domains = NULL;
|
||||
Link *link;
|
||||
@ -1125,11 +1109,11 @@ static int manager_save(Manager *m) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_set_put_strdupv(search_domains, link->network->search_domains);
|
||||
r = ordered_set_put_string_set(search_domains, link->network->search_domains);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_set_put_strdupv(route_domains, link->network->route_domains);
|
||||
r = ordered_set_put_string_set(route_domains, link->network->route_domains);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1198,10 +1182,10 @@ static int manager_save(Manager *m) {
|
||||
"# This is private data. Do not parse.\n"
|
||||
"OPER_STATE=%s\n", operstate_str);
|
||||
|
||||
print_string_set(f, "DNS=", dns);
|
||||
print_string_set(f, "NTP=", ntp);
|
||||
print_string_set(f, "DOMAINS=", search_domains);
|
||||
print_string_set(f, "ROUTE_DOMAINS=", route_domains);
|
||||
ordered_set_print(f, "DNS=", dns);
|
||||
ordered_set_print(f, "NTP=", ntp);
|
||||
ordered_set_print(f, "DOMAINS=", search_domains);
|
||||
ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);
|
||||
|
||||
r = routing_policy_serialize_rules(m->rules, f);
|
||||
if (r < 0)
|
||||
|
@ -107,28 +107,34 @@ static int network_verify(Network *network) {
|
||||
if (network->bond) {
|
||||
/* Bonding slave does not support addressing. */
|
||||
if (network->ipv6_accept_ra > 0) {
|
||||
log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.", network->filename);
|
||||
log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
|
||||
network->filename);
|
||||
network->ipv6_accept_ra = 0;
|
||||
}
|
||||
if (network->link_local >= 0 && network->link_local != ADDRESS_FAMILY_NO) {
|
||||
log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.", network->filename);
|
||||
log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
|
||||
network->filename);
|
||||
network->link_local = ADDRESS_FAMILY_NO;
|
||||
}
|
||||
if (network->dhcp != ADDRESS_FAMILY_NO) {
|
||||
log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.", network->filename);
|
||||
log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
|
||||
network->filename);
|
||||
network->dhcp = ADDRESS_FAMILY_NO;
|
||||
}
|
||||
if (network->dhcp_server) {
|
||||
log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.", network->filename);
|
||||
log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
|
||||
network->filename);
|
||||
network->dhcp_server = false;
|
||||
}
|
||||
if (network->n_static_addresses > 0) {
|
||||
log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.", network->filename);
|
||||
log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
|
||||
network->filename);
|
||||
while ((address = network->static_addresses))
|
||||
address_free(address);
|
||||
}
|
||||
if (network->n_static_routes > 0) {
|
||||
log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.", network->filename);
|
||||
log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
|
||||
network->filename);
|
||||
while ((route = network->static_routes))
|
||||
route_free(route);
|
||||
}
|
||||
@ -379,11 +385,11 @@ void network_free(Network *network) {
|
||||
|
||||
strv_free(network->ntp);
|
||||
free(network->dns);
|
||||
strv_free(network->search_domains);
|
||||
strv_free(network->route_domains);
|
||||
ordered_set_free_free(network->search_domains);
|
||||
ordered_set_free_free(network->route_domains);
|
||||
strv_free(network->bind_carrier);
|
||||
|
||||
strv_free(network->router_search_domains);
|
||||
ordered_set_free_free(network->router_search_domains);
|
||||
free(network->router_dns);
|
||||
|
||||
netdev_unref(network->bridge);
|
||||
@ -547,8 +553,8 @@ int network_apply(Network *network, Link *link) {
|
||||
|
||||
if (network->n_dns > 0 ||
|
||||
!strv_isempty(network->ntp) ||
|
||||
!strv_isempty(network->search_domains) ||
|
||||
!strv_isempty(network->route_domains))
|
||||
!ordered_set_isempty(network->search_domains) ||
|
||||
!ordered_set_isempty(network->route_domains))
|
||||
link_dirty(link);
|
||||
|
||||
return 0;
|
||||
@ -599,18 +605,21 @@ int config_parse_netdev(const char *unit,
|
||||
|
||||
kind = netdev_kind_from_string(kind_string);
|
||||
if (kind == _NETDEV_KIND_INVALID) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid NetDev kind: %s", lvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Invalid NetDev kind: %s", lvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = netdev_get(network->manager, rvalue, &netdev);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "%s could not be found, ignoring assignment: %s", lvalue, rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"%s could not be found, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (netdev->kind != kind) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "NetDev is not a %s, ignoring assignment: %s", lvalue, rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"NetDev is not a %s, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -677,8 +686,8 @@ int config_parse_domains(
|
||||
assert(rvalue);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
n->search_domains = strv_free(n->search_domains);
|
||||
n->route_domains = strv_free(n->route_domains);
|
||||
n->search_domains = ordered_set_free_free(n->search_domains);
|
||||
n->route_domains = ordered_set_free_free(n->route_domains);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -690,7 +699,8 @@ int config_parse_domains(
|
||||
|
||||
r = extract_first_word(&p, &w, NULL, 0);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract search or route domain, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to extract search or route domain, ignoring: %s", rvalue);
|
||||
break;
|
||||
}
|
||||
if (r == 0)
|
||||
@ -700,36 +710,39 @@ int config_parse_domains(
|
||||
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. */
|
||||
/* 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 "." */
|
||||
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_ERR, filename, line, r, "'%s' is not a valid domain name, ignoring.", domain);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"'%s' is not a valid domain name, ignoring.", domain);
|
||||
continue;
|
||||
}
|
||||
|
||||
domain = normalized;
|
||||
|
||||
if (is_localhost(domain)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "'localhost' domain names may not be configure as search or route domains, ignoring assignment: %s", domain);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
|
||||
domain);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_route)
|
||||
r = strv_extend(&n->route_domains, domain);
|
||||
else
|
||||
r = strv_extend(&n->search_domains, domain);
|
||||
OrderedSet **set = is_route ? &n->route_domains : &n->search_domains;
|
||||
r = ordered_set_ensure_allocated(set, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_set_put_strdup(*set, domain);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
strv_uniq(n->route_domains);
|
||||
strv_uniq(n->search_domains);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -754,7 +767,8 @@ int config_parse_tunnel(const char *unit,
|
||||
|
||||
r = netdev_get(network->manager, rvalue, &netdev);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Tunnel is invalid, ignoring assignment: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Tunnel is invalid, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -779,7 +793,8 @@ int config_parse_tunnel(const char *unit,
|
||||
|
||||
r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Cannot add VLAN '%s' to network, ignoring: %m", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Cannot add VLAN '%s' to network, ignoring: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -854,7 +869,8 @@ int config_parse_dhcp(
|
||||
else if (streq(rvalue, "both"))
|
||||
s = ADDRESS_FAMILY_YES;
|
||||
else {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse DHCP option, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Failed to parse DHCP option, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -874,7 +890,8 @@ static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
|
||||
};
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier, DHCPClientIdentifier);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier, dhcp_client_identifier, DHCPClientIdentifier, "Failed to parse client identifier type");
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier, dhcp_client_identifier, DHCPClientIdentifier,
|
||||
"Failed to parse client identifier type");
|
||||
|
||||
int config_parse_ipv6token(
|
||||
const char* unit,
|
||||
@ -899,17 +916,20 @@ int config_parse_ipv6token(
|
||||
|
||||
r = in_addr_from_string(AF_INET6, rvalue, &buffer);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse IPv6 token, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse IPv6 token, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in_addr_is_null(AF_INET6, &buffer)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "IPv6 token cannot be the ANY address, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"IPv6 token cannot be the ANY address, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((buffer.in6.s6_addr32[0] | buffer.in6.s6_addr32[1]) != 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -963,7 +983,8 @@ int config_parse_ipv6_privacy_extensions(
|
||||
if (streq(rvalue, "kernel"))
|
||||
s = _IPV6_PRIVACY_EXTENSIONS_INVALID;
|
||||
else {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -999,17 +1020,20 @@ int config_parse_hostname(
|
||||
return r;
|
||||
|
||||
if (!hostname_is_valid(hn, false)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Hostname is not valid, ignoring assignment: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Hostname is not valid, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = dns_name_is_valid(hn);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1041,7 +1065,8 @@ int config_parse_timezone(
|
||||
return r;
|
||||
|
||||
if (!timezone_is_valid(tz, LOG_ERR)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Timezone is not valid, ignoring assignment: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Timezone is not valid, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1076,14 +1101,16 @@ int config_parse_dhcp_server_dns(
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to extract word, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (inet_pton(AF_INET, w, &a) <= 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse DNS server address, ignoring: %s", w);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Failed to parse DNS server address, ignoring: %s", w);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1126,7 +1153,8 @@ int config_parse_radv_dns(
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to extract word, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0)
|
||||
@ -1143,8 +1171,8 @@ int config_parse_radv_dns(
|
||||
n->router_dns = m;
|
||||
|
||||
} else
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse DNS server address, ignoring: %s", w);
|
||||
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Failed to parse DNS server address, ignoring: %s", w);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1177,7 +1205,8 @@ int config_parse_radv_search_domains(
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to extract word, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0)
|
||||
@ -1185,18 +1214,20 @@ int config_parse_radv_search_domains(
|
||||
|
||||
r = dns_name_apply_idna(w, &idna);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to apply IDNA to domain name '%s', ignoring: %m", w);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to apply IDNA to domain name '%s', ignoring: %m", w);
|
||||
continue;
|
||||
}
|
||||
if (r > 0) {
|
||||
r = strv_push(&n->router_search_domains, idna);
|
||||
if (r >= 0)
|
||||
idna = NULL;
|
||||
} else {
|
||||
r = strv_push(&n->router_search_domains, w);
|
||||
if (r >= 0)
|
||||
w = NULL;
|
||||
}
|
||||
} else if (r == 0)
|
||||
/* transfer ownership to simplify subsequent operations */
|
||||
idna = TAKE_PTR(w);
|
||||
|
||||
r = ordered_set_ensure_allocated(&n->router_search_domains, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_set_consume(n->router_search_domains, TAKE_PTR(idna));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1230,14 +1261,16 @@ int config_parse_dhcp_server_ntp(
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to extract word, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
if (inet_pton(AF_INET, w, &a) <= 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse NTP server address, ignoring: %s", w);
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Failed to parse NTP server address, ignoring: %s", w);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1279,7 +1312,8 @@ int config_parse_dns(
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Invalid syntax, ignoring: %s", rvalue);
|
||||
break;
|
||||
}
|
||||
if (r == 0)
|
||||
@ -1287,7 +1321,8 @@ int config_parse_dns(
|
||||
|
||||
r = in_addr_from_string_auto(w, &family, &a);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse dns server address, ignoring: %s", w);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse dns server address, ignoring: %s", w);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1336,7 +1371,8 @@ int config_parse_dnssec_negative_trust_anchors(
|
||||
|
||||
r = extract_first_word(&p, &w, NULL, 0);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract negative trust anchor domain, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to extract negative trust anchor domain, ignoring: %s", rvalue);
|
||||
break;
|
||||
}
|
||||
if (r == 0)
|
||||
@ -1344,7 +1380,8 @@ int config_parse_dnssec_negative_trust_anchors(
|
||||
|
||||
r = dns_name_is_valid(w);
|
||||
if (r <= 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "%s is not a valid domain name, ignoring.", w);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"%s is not a valid domain name, ignoring.", w);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1393,7 +1430,8 @@ int config_parse_ntp(
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract NTP server name, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to extract NTP server name, ignoring: %s", rvalue);
|
||||
break;
|
||||
}
|
||||
if (r == 0)
|
||||
@ -1401,7 +1439,8 @@ int config_parse_ntp(
|
||||
|
||||
r = dns_name_is_valid_or_address(w);
|
||||
if (r <= 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "%s is not a valid domain name or IP address, ignoring.", w);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"%s is not a valid domain name or IP address, ignoring.", w);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1446,14 +1485,16 @@ int config_parse_dhcp_user_class(
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to split user classes option, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to split user classes option, ignoring: %s", rvalue);
|
||||
break;
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (strlen(w) > 255) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "%s length is not in the range 1-255, ignoring.", w);
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"%s length is not in the range 1-255, ignoring.", w);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1506,7 +1547,8 @@ int config_parse_section_route_table(
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains, "Failed to parse DHCP use domains setting");
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains,
|
||||
"Failed to parse DHCP use domains setting");
|
||||
|
||||
static const char* const dhcp_use_domains_table[_DHCP_USE_DOMAINS_MAX] = {
|
||||
[DHCP_USE_DOMAINS_NO] = "no",
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "networkd-route.h"
|
||||
#include "networkd-routing-policy-rule.h"
|
||||
#include "networkd-util.h"
|
||||
#include "ordered-set.h"
|
||||
#include "resolve-util.h"
|
||||
|
||||
#define DHCP_ROUTE_METRIC 1024
|
||||
@ -173,7 +174,7 @@ struct Network {
|
||||
usec_t router_dns_lifetime_usec;
|
||||
struct in6_addr *router_dns;
|
||||
unsigned n_router_dns;
|
||||
char **router_search_domains;
|
||||
OrderedSet *router_search_domains;
|
||||
bool dhcp6_force_pd_other_information; /* Start DHCPv6 PD also when 'O'
|
||||
RA flag is set, see RFC 7084,
|
||||
WPD-4 */
|
||||
@ -267,7 +268,8 @@ struct Network {
|
||||
/* All kinds of DNS configuration */
|
||||
struct in_addr_data *dns;
|
||||
unsigned n_dns;
|
||||
char **search_domains, **route_domains;
|
||||
OrderedSet *search_domains, *route_domains;
|
||||
|
||||
int dns_default_route;
|
||||
ResolveSupport llmnr;
|
||||
ResolveSupport mdns;
|
||||
|
@ -391,8 +391,9 @@ static int radv_set_dns(Link *link, Link *uplink) {
|
||||
}
|
||||
|
||||
static int radv_set_domains(Link *link, Link *uplink) {
|
||||
char **search_domains;
|
||||
OrderedSet *search_domains;
|
||||
usec_t lifetime_usec;
|
||||
_cleanup_free_ char **s = NULL; /* just free() because the strings are owned by the set */
|
||||
|
||||
if (!link->network->router_emit_domains)
|
||||
return 0;
|
||||
@ -423,9 +424,13 @@ static int radv_set_domains(Link *link, Link *uplink) {
|
||||
return 0;
|
||||
|
||||
set_domains:
|
||||
s = ordered_set_get_strv(search_domains);
|
||||
if (!s)
|
||||
return log_oom();
|
||||
|
||||
return sd_radv_set_dnssl(link->radv,
|
||||
DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
|
||||
search_domains);
|
||||
s);
|
||||
|
||||
}
|
||||
|
||||
|
@ -440,6 +440,10 @@ tests += [
|
||||
[],
|
||||
[]],
|
||||
|
||||
[['src/test/test-ordered-set.c'],
|
||||
[],
|
||||
[]],
|
||||
|
||||
[['src/test/test-set-disable-mempool.c'],
|
||||
[],
|
||||
[threads]],
|
||||
|
121
src/test/test-ordered-set.c
Normal file
121
src/test/test-ordered-set.c
Normal file
@ -0,0 +1,121 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ordered-set.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
static void test_set_steal_first(void) {
|
||||
_cleanup_ordered_set_free_ OrderedSet *m = NULL;
|
||||
int seen[3] = {};
|
||||
char *val;
|
||||
|
||||
m = ordered_set_new(&string_hash_ops);
|
||||
assert_se(m);
|
||||
|
||||
assert_se(ordered_set_put(m, (void*) "1") == 1);
|
||||
assert_se(ordered_set_put(m, (void*) "22") == 1);
|
||||
assert_se(ordered_set_put(m, (void*) "333") == 1);
|
||||
|
||||
ordered_set_print(stdout, "SET=", m);
|
||||
|
||||
while ((val = ordered_set_steal_first(m)))
|
||||
seen[strlen(val) - 1]++;
|
||||
|
||||
assert_se(seen[0] == 1 && seen[1] == 1 && seen[2] == 1);
|
||||
|
||||
assert_se(ordered_set_isempty(m));
|
||||
|
||||
ordered_set_print(stdout, "SET=", m);
|
||||
}
|
||||
|
||||
typedef struct Item {
|
||||
int seen;
|
||||
} Item;
|
||||
static void item_seen(Item *item) {
|
||||
item->seen++;
|
||||
}
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(item_hash_ops, void, trivial_hash_func, trivial_compare_func, Item, item_seen);
|
||||
|
||||
static void test_set_free_with_hash_ops(void) {
|
||||
OrderedSet *m;
|
||||
struct Item items[4] = {};
|
||||
unsigned i;
|
||||
|
||||
assert_se(m = ordered_set_new(&item_hash_ops));
|
||||
for (i = 0; i < ELEMENTSOF(items) - 1; i++)
|
||||
assert_se(ordered_set_put(m, items + i) == 1);
|
||||
|
||||
m = ordered_set_free(m);
|
||||
assert_se(items[0].seen == 1);
|
||||
assert_se(items[1].seen == 1);
|
||||
assert_se(items[2].seen == 1);
|
||||
assert_se(items[3].seen == 0);
|
||||
}
|
||||
|
||||
static void test_set_put(void) {
|
||||
_cleanup_ordered_set_free_ OrderedSet *m = NULL;
|
||||
_cleanup_free_ char **t = NULL;
|
||||
|
||||
m = ordered_set_new(&string_hash_ops);
|
||||
assert_se(m);
|
||||
|
||||
assert_se(ordered_set_put(m, (void*) "1") == 1);
|
||||
assert_se(ordered_set_put(m, (void*) "22") == 1);
|
||||
assert_se(ordered_set_put(m, (void*) "333") == 1);
|
||||
assert_se(ordered_set_put(m, (void*) "333") == 0);
|
||||
assert_se(ordered_set_remove(m, (void*) "333"));
|
||||
assert_se(ordered_set_put(m, (void*) "333") == 1);
|
||||
assert_se(ordered_set_put(m, (void*) "333") == 0);
|
||||
assert_se(ordered_set_put(m, (void*) "22") == 0);
|
||||
|
||||
assert_se(t = ordered_set_get_strv(m));
|
||||
assert_se(streq(t[0], "1"));
|
||||
assert_se(streq(t[1], "22"));
|
||||
assert_se(streq(t[2], "333"));
|
||||
assert_se(!t[3]);
|
||||
|
||||
ordered_set_print(stdout, "FOO=", m);
|
||||
}
|
||||
|
||||
static void test_set_put_string_set(void) {
|
||||
_cleanup_ordered_set_free_free_ OrderedSet *m = NULL;
|
||||
_cleanup_ordered_set_free_ OrderedSet *q = NULL;
|
||||
_cleanup_free_ char **final = NULL; /* "just free" because the strings are in the set */
|
||||
void *t;
|
||||
|
||||
m = ordered_set_new(&string_hash_ops);
|
||||
assert_se(m);
|
||||
|
||||
q = ordered_set_new(&string_hash_ops);
|
||||
assert_se(q);
|
||||
|
||||
assert_se(t = strdup("1"));
|
||||
assert_se(ordered_set_put(m, t) == 1);
|
||||
assert_se(t = strdup("22"));
|
||||
assert_se(ordered_set_put(m, t) == 1);
|
||||
assert_se(t = strdup("333"));
|
||||
assert_se(ordered_set_put(m, t) == 1);
|
||||
|
||||
assert_se(ordered_set_put(q, (void*) "11") == 1);
|
||||
assert_se(ordered_set_put(q, (void*) "22") == 1);
|
||||
assert_se(ordered_set_put(q, (void*) "33") == 1);
|
||||
|
||||
assert_se(ordered_set_put_string_set(m, q) == 2);
|
||||
|
||||
assert_se(final = ordered_set_get_strv(m));
|
||||
assert_se(strv_equal(final, STRV_MAKE("1", "22", "333", "11", "33")));
|
||||
|
||||
ordered_set_print(stdout, "BAR=", m);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
test_set_steal_first();
|
||||
test_set_free_with_hash_ops();
|
||||
test_set_put();
|
||||
test_set_put_string_set();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include "set.h"
|
||||
#include "strv.h"
|
||||
|
||||
static void test_set_steal_first(void) {
|
||||
_cleanup_set_free_ Set *m = NULL;
|
||||
@ -77,6 +78,12 @@ static void test_set_put(void) {
|
||||
assert_se(set_put(m, (void*) "333") == 1);
|
||||
assert_se(set_put(m, (void*) "333") == 0);
|
||||
assert_se(set_put(m, (void*) "22") == 0);
|
||||
|
||||
_cleanup_free_ char **t = set_get_strv(m);
|
||||
assert_se(strv_contains(t, "1"));
|
||||
assert_se(strv_contains(t, "22"));
|
||||
assert_se(strv_contains(t, "333"));
|
||||
assert_se(strv_length(t) == 3);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
|
BIN
test/fuzz/fuzz-network-parser/oss-fuzz-13059
Normal file
BIN
test/fuzz/fuzz-network-parser/oss-fuzz-13059
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user