From: Yu Watanabe Date: Fri, 2 Oct 2020 03:34:19 +0000 (+0900) Subject: network: drop list of static addresses X-Git-Tag: v247-rc1~117^2~45 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9cd9fc8f447329281d6d1614e1a86011c8cbec5c;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/network/networkd-address-pool.c b/src/network/networkd-address-pool.c index b4a94f07282..e867323dbbc 100644 --- a/src/network/networkd-address-pool.c +++ b/src/network/networkd-address-pool.c @@ -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; diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index d14da8195e1..d2c08a0f32e 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -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)); - - if (filename) { - r = network_config_section_new(filename, section_line, &n); - if (r < 0) - return r; + assert(filename); + assert(section_line > 0); - address = hashmap_get(network->addresses_by_section, n); - if (address) { - *ret = TAKE_PTR(address); + r = network_config_section_new(filename, section_line, &n); + if (r < 0) + return r; - 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 = hashmap_ensure_allocated(&network->addresses_by_section, &network_config_hash_ops); - if (r < 0) - return r; + r = ordered_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); } diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c index 890d9b55a11..ddc58cb9c04 100644 --- a/src/network/networkd-dhcp-server.c +++ b/src/network/networkd-dhcp-server.c @@ -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; diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 79ae2899d37..c1c1ff502e1 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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; diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index c56c24656a7..f6ebda4a144 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -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; diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index e59f634fb17..3d25f6f489e 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -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. " diff --git a/src/network/test-networkd-conf.c b/src/network/test-networkd-conf.c index 5d338e6f1a3..030e50688a4 100644 --- a/src/network/test-networkd-conf.c +++ b/src/network/test-networkd-conf.c @@ -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 */ } }