@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user