diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-10-01 09:22:18 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-10-04 18:17:38 +0900 |
commit | 50783f91d44b1978c0e4ba62283131fac75d3745 (patch) | |
tree | 8be16d173c3cdce0a208425d453591cce6d2ea4e /src | |
parent | 5b43c2c84312d399784b61fd44a00dc8d987f248 (diff) | |
download | systemd-50783f91d44b1978c0e4ba62283131fac75d3745.tar.gz |
network: drop and warn duplicated Address= settings
Fixes #20891.
Diffstat (limited to 'src')
-rw-r--r-- | src/network/networkd-address.c | 43 | ||||
-rw-r--r-- | src/network/networkd-address.h | 2 | ||||
-rw-r--r-- | src/network/networkd-network.c | 6 |
3 files changed, 46 insertions, 5 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index f162fd5334..002827eb78 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -314,6 +314,12 @@ int address_compare_func(const Address *a1, const Address *a2) { } } +DEFINE_PRIVATE_HASH_OPS( + address_hash_ops, + Address, + address_hash_func, + address_compare_func); + DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR( address_hash_ops_free, Address, @@ -1910,12 +1916,43 @@ static int address_section_verify(Address *address) { return 0; } -void network_drop_invalid_addresses(Network *network) { +int network_drop_invalid_addresses(Network *network) { + _cleanup_set_free_ Set *addresses = NULL; Address *address; + int r; assert(network); - ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section) - if (address_section_verify(address) < 0) + ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section) { + Address *dup; + + if (address_section_verify(address) < 0) { + /* Drop invalid [Address] sections or Address= settings in [Network]. + * Note that address_free() will drop the address from addresses_by_section. */ address_free(address); + continue; + } + + /* Always use the setting specified later. So, remove the previously assigned setting. */ + dup = set_remove(addresses, address); + if (dup) { + _cleanup_free_ char *buf = NULL; + + (void) in_addr_prefix_to_string(address->family, &address->in_addr, address->prefixlen, &buf); + log_warning("%s: Duplicated address %s is specified at line %u and %u, " + "dropping the address setting specified at line %u.", + dup->section->filename, strna(buf), address->section->line, + dup->section->line, dup->section->line); + /* address_free() will drop the address from addresses_by_section. */ + address_free(dup); + } + + /* Do not use address_hash_ops_free here. Otherwise, all address settings will be freed. */ + r = set_ensure_put(&addresses, &address_hash_ops, address); + if (r < 0) + return log_oom(); + assert(r > 0); + } + + return 0; } diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index 80ceda9427..0fd3163fc4 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -93,7 +93,7 @@ int request_process_address(Request *req); int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, Manager *m); -void network_drop_invalid_addresses(Network *network); +int network_drop_invalid_addresses(Network *network); void address_hash_func(const Address *a, struct siphash *state); int address_compare_func(const Address *a1, const Address *a2); diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 9c01d1cb89..bb7c1defe7 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -121,6 +121,8 @@ static int network_resolve_stacked_netdevs(Network *network) { } int network_verify(Network *network) { + int r; + assert(network); assert(network->filename); @@ -299,7 +301,9 @@ int network_verify(Network *network) { network->ipv6_proxy_ndp_addresses = set_free_free(network->ipv6_proxy_ndp_addresses); } - network_drop_invalid_addresses(network); + r = network_drop_invalid_addresses(network); + if (r < 0) + return r; network_drop_invalid_routes(network); network_drop_invalid_nexthops(network); network_drop_invalid_bridge_fdb_entries(network); |