]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: drop list of static addresses
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 2 Oct 2020 03:34:19 +0000 (12:34 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 6 Oct 2020 17:50:50 +0000 (02:50 +0900)
[Address] sections are managed by both LIST and Hashmap. Let's drop the
list and manage them by OrderedHashmap.

src/network/networkd-address-pool.c
src/network/networkd-address.c
src/network/networkd-dhcp-server.c
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-route.c
src/network/test-networkd-conf.c

index b4a94f0728271cf613265475a0b8c7ae59610f67..e867323dbbc559f0158f6a77b064fcf21ed6fa93 100644 (file)
@@ -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;
 
index d14da8195e1525586e567ba5e7732a5b9caf9007..d2c08a0f32e43f006fd2c322ae8cbe934510d69b 100644 (file)
@@ -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);
 }
index 890d9b55a11a5acdee282f821609a485f862025f..ddc58cb9c04b7840ce7e6c89244fb3345b84fd2e 100644 (file)
@@ -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;
index 79ae2899d37a086f10a85693505e0d70d6c86732..c1c1ff502e1716ffa930918e99ad53076074a92f 100644 (file)
@@ -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;
 
index c56c24656a73c675e046e8c75082b7aa9656aa46..f6ebda4a144b17f6482a8cc78a541955203340ce 100644 (file)
@@ -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;
index e59f634fb172d207d2e7ef284928b001e30aa10b..3d25f6f489e382534e5263dac623fd82ea1e6c99 100644 (file)
@@ -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. "
index 5d338e6f1a3a90f92f9bb77568d80d4e1432cfe1..030e50688a4e9ecd0a94f6340dd0a970a8b3687c 100644 (file)
@@ -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 */
         }
 }