mirror of
https://github.com/systemd/systemd.git
synced 2024-10-28 03:25:31 +03:00
network: drop list of static addresses
[Address] sections are managed by both LIST and Hashmap. Let's drop the list and manage them by OrderedHashmap.
This commit is contained in:
parent
7818f8589a
commit
9cd9fc8f44
@ -107,7 +107,7 @@ static bool address_pool_prefix_is_taken(
|
||||
ORDERED_HASHMAP_FOREACH(n, p->manager->networks) {
|
||||
Address *a;
|
||||
|
||||
LIST_FOREACH(addresses, a, n->static_addresses) {
|
||||
ORDERED_HASHMAP_FOREACH(a, n->addresses_by_section) {
|
||||
if (a->family != p->family)
|
||||
continue;
|
||||
|
||||
|
@ -67,22 +67,20 @@ static int address_new_static(Network *network, const char *filename, unsigned s
|
||||
|
||||
assert(network);
|
||||
assert(ret);
|
||||
assert(!!filename == (section_line > 0));
|
||||
assert(filename);
|
||||
assert(section_line > 0);
|
||||
|
||||
if (filename) {
|
||||
r = network_config_section_new(filename, section_line, &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = network_config_section_new(filename, section_line, &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
address = hashmap_get(network->addresses_by_section, n);
|
||||
if (address) {
|
||||
*ret = TAKE_PTR(address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
address = ordered_hashmap_get(network->addresses_by_section, n);
|
||||
if (address) {
|
||||
*ret = TAKE_PTR(address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (network->n_static_addresses >= STATIC_ADDRESSES_PER_NETWORK_MAX)
|
||||
if (ordered_hashmap_size(network->addresses_by_section) >= STATIC_ADDRESSES_PER_NETWORK_MAX)
|
||||
return -E2BIG;
|
||||
|
||||
r = address_new(&address);
|
||||
@ -90,23 +88,17 @@ static int address_new_static(Network *network, const char *filename, unsigned s
|
||||
return r;
|
||||
|
||||
address->network = network;
|
||||
LIST_APPEND(addresses, network->static_addresses, address);
|
||||
network->n_static_addresses++;
|
||||
address->section = TAKE_PTR(n);
|
||||
|
||||
if (filename) {
|
||||
address->section = TAKE_PTR(n);
|
||||
r = ordered_hashmap_ensure_allocated(&network->addresses_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_ensure_allocated(&network->addresses_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(network->addresses_by_section, address->section, address);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
r = ordered_hashmap_put(network->addresses_by_section, address->section, address);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = TAKE_PTR(address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -115,12 +107,8 @@ Address *address_free(Address *address) {
|
||||
return NULL;
|
||||
|
||||
if (address->network) {
|
||||
LIST_REMOVE(addresses, address->network->static_addresses, address);
|
||||
assert(address->network->n_static_addresses > 0);
|
||||
address->network->n_static_addresses--;
|
||||
|
||||
if (address->section)
|
||||
hashmap_remove(address->network->addresses_by_section, address->section);
|
||||
assert(address->section);
|
||||
ordered_hashmap_remove(address->network->addresses_by_section, address->section);
|
||||
}
|
||||
|
||||
if (address->link && !address->acd) {
|
||||
@ -551,7 +539,7 @@ static bool link_is_static_address_configured(Link *link, Address *address) {
|
||||
if (!link->network)
|
||||
return false;
|
||||
|
||||
LIST_FOREACH(addresses, net_address, link->network->static_addresses)
|
||||
ORDERED_HASHMAP_FOREACH(net_address, link->network->addresses_by_section)
|
||||
if (address_equal(net_address, address))
|
||||
return true;
|
||||
else if (address->family == AF_INET6 && net_address->family == AF_INET6 &&
|
||||
@ -1002,7 +990,7 @@ int link_set_addresses(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIST_FOREACH(addresses, ad, link->network->static_addresses) {
|
||||
ORDERED_HASHMAP_FOREACH(ad, link->network->addresses_by_section) {
|
||||
bool update;
|
||||
|
||||
if (ad->family == AF_INET6 && !in_addr_is_null(ad->family, &ad->in_addr_peer))
|
||||
@ -1368,7 +1356,7 @@ int link_configure_ipv4_dad(Link *link) {
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
LIST_FOREACH(addresses, address, link->network->static_addresses)
|
||||
ORDERED_HASHMAP_FOREACH(address, link->network->addresses_by_section)
|
||||
if (address->family == AF_INET &&
|
||||
FLAGS_SET(address->duplicate_address_detection, ADDRESS_FAMILY_IPV4)) {
|
||||
r = ipv4_dad_configure(link, address);
|
||||
@ -1388,7 +1376,7 @@ int link_stop_ipv4_dad(Link *link) {
|
||||
if (!link->network)
|
||||
return 0;
|
||||
|
||||
LIST_FOREACH(addresses, address, link->network->static_addresses) {
|
||||
ORDERED_HASHMAP_FOREACH(address, link->network->addresses_by_section) {
|
||||
if (!address->acd)
|
||||
continue;
|
||||
|
||||
@ -1473,11 +1461,10 @@ int config_parse_address(const char *unit,
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if (streq(section, "Network")) {
|
||||
/* we are not in an Address section, so treat
|
||||
* this as the special '0' section */
|
||||
r = address_new_static(network, NULL, 0, &n);
|
||||
} else
|
||||
if (streq(section, "Network"))
|
||||
/* we are not in an Address section, so use line number instead. */
|
||||
r = address_new_static(network, filename, line, &n);
|
||||
else
|
||||
r = address_new_static(network, filename, section_line, &n);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
@ -1810,11 +1797,11 @@ static int address_section_verify(Address *address) {
|
||||
}
|
||||
|
||||
void network_verify_addresses(Network *network) {
|
||||
Address *address, *address_next;
|
||||
Address *address;
|
||||
|
||||
assert(network);
|
||||
|
||||
LIST_FOREACH_SAFE(addresses, address, address_next, network->static_addresses)
|
||||
ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section)
|
||||
if (address_section_verify(address) < 0)
|
||||
address_free(address);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ static Address* link_find_dhcp_server_address(Link *link) {
|
||||
assert(link->network);
|
||||
|
||||
/* The first statically configured address if there is any */
|
||||
LIST_FOREACH(addresses, address, link->network->static_addresses)
|
||||
ORDERED_HASHMAP_FOREACH(address, link->network->addresses_by_section)
|
||||
if (address->family == AF_INET &&
|
||||
!in_addr_is_null(address->family, &address->in_addr))
|
||||
return address;
|
||||
|
@ -210,17 +210,14 @@ int network_verify(Network *network) {
|
||||
network->filename);
|
||||
network->dhcp_server = false;
|
||||
}
|
||||
if (network->n_static_addresses > 0) {
|
||||
Address *address;
|
||||
|
||||
if (!ordered_hashmap_isempty(network->addresses_by_section))
|
||||
log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
|
||||
network->filename);
|
||||
while ((address = network->static_addresses))
|
||||
address_free(address);
|
||||
}
|
||||
if (!hashmap_isempty(network->routes_by_section))
|
||||
log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
|
||||
network->filename);
|
||||
|
||||
network->addresses_by_section = ordered_hashmap_free_with_destructor(network->addresses_by_section, address_free);
|
||||
network->routes_by_section = hashmap_free_with_destructor(network->routes_by_section, route_free);
|
||||
}
|
||||
|
||||
@ -617,8 +614,6 @@ failure:
|
||||
}
|
||||
|
||||
static Network *network_free(Network *network) {
|
||||
Address *address;
|
||||
|
||||
if (!network)
|
||||
return NULL;
|
||||
|
||||
@ -674,11 +669,8 @@ static Network *network_free(Network *network) {
|
||||
netdev_unref(network->vrf);
|
||||
hashmap_free_with_destructor(network->stacked_netdevs, netdev_unref);
|
||||
|
||||
while ((address = network->static_addresses))
|
||||
address_free(address);
|
||||
|
||||
set_free_free(network->ipv6_proxy_ndp_addresses);
|
||||
hashmap_free(network->addresses_by_section);
|
||||
ordered_hashmap_free_with_destructor(network->addresses_by_section, address_free);
|
||||
hashmap_free_with_destructor(network->routes_by_section, route_free);
|
||||
hashmap_free_with_destructor(network->nexthops_by_section, nexthop_free);
|
||||
hashmap_free_with_destructor(network->fdb_entries_by_section, fdb_entry_free);
|
||||
@ -800,7 +792,7 @@ bool network_has_static_ipv6_configurations(Network *network) {
|
||||
|
||||
assert(network);
|
||||
|
||||
LIST_FOREACH(addresses, address, network->static_addresses)
|
||||
ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section)
|
||||
if (address->family == AF_INET6)
|
||||
return true;
|
||||
|
||||
|
@ -278,11 +278,7 @@ struct Network {
|
||||
LLDPEmit lldp_emit; /* LLDP transmission */
|
||||
char *lldp_mud; /* LLDP MUD URL */
|
||||
|
||||
LIST_HEAD(Address, static_addresses);
|
||||
|
||||
unsigned n_static_addresses;
|
||||
|
||||
Hashmap *addresses_by_section;
|
||||
OrderedHashmap *addresses_by_section;
|
||||
Hashmap *routes_by_section;
|
||||
Hashmap *nexthops_by_section;
|
||||
Hashmap *fdb_entries_by_section;
|
||||
|
@ -2182,7 +2182,7 @@ static int route_section_verify(Route *route, Network *network) {
|
||||
route->scope = RT_SCOPE_LINK;
|
||||
}
|
||||
|
||||
if (network->n_static_addresses == 0 &&
|
||||
if (ordered_hashmap_isempty(network->addresses_by_section) &&
|
||||
in_addr_is_null(route->family, &route->gw) == 0 &&
|
||||
route->gateway_onlink < 0) {
|
||||
log_warning("%s: Gateway= without static address configured. "
|
||||
|
@ -176,14 +176,16 @@ static void test_config_parse_address_one(const char *rvalue, int family, unsign
|
||||
assert_se(network->filename = strdup("hogehoge.network"));
|
||||
assert_se(config_parse_match_ifnames("network", "filename", 1, "section", 1, "Name", 0, "*", &network->match_name, network) == 0);
|
||||
assert_se(config_parse_address("network", "filename", 1, "section", 1, "Address", 0, rvalue, network, network) == 0);
|
||||
assert_se(network->n_static_addresses == 1);
|
||||
assert_se(ordered_hashmap_size(network->addresses_by_section) == 1);
|
||||
assert_se(network_verify(network) >= 0);
|
||||
assert_se(network->n_static_addresses == n_addresses);
|
||||
assert_se(ordered_hashmap_size(network->addresses_by_section) == n_addresses);
|
||||
if (n_addresses > 0) {
|
||||
assert_se(network->static_addresses);
|
||||
assert_se(network->static_addresses->prefixlen == prefixlen);
|
||||
assert_se(network->static_addresses->family == family);
|
||||
assert_se(in_addr_equal(family, &network->static_addresses->in_addr, u));
|
||||
Address *a;
|
||||
|
||||
assert_se(a = ordered_hashmap_first(network->addresses_by_section));
|
||||
assert_se(a->prefixlen == prefixlen);
|
||||
assert_se(a->family == family);
|
||||
assert_se(in_addr_equal(family, &a->in_addr, u));
|
||||
/* TODO: check Address.in_addr and Address.broadcast */
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user