]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: drop list of static routes
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 2 Oct 2020 01:41:55 +0000 (10:41 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 6 Oct 2020 17:44:43 +0000 (02:44 +0900)
[Route] sections are managed by both LIST and Hashmap. Let's drop the
list.

src/network/networkd-dhcp4.c
src/network/networkd-ndisc.c
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-route.c
src/network/networkd-route.h

index 8dd89c22a279ea9dc0890dc087c649cf2acec7ef..18ce0c61bb636ac137f0a7d01b2cf79d9e19fb21 100644 (file)
@@ -384,7 +384,7 @@ static int link_set_dhcp_routes(Link *link) {
                         if (r < 0)
                                 return log_link_error_errno(link, r, "Could not set router: %m");
 
-                        LIST_FOREACH(routes, rt, link->network->static_routes) {
+                        HASHMAP_FOREACH(rt, link->network->routes_by_section) {
                                 if (!rt->gateway_from_dhcp)
                                         continue;
 
index 64b27276e0882852f1ac24abb979cd175b3bcb88..256f6cc659bc96052085cf4779d12633dca74b46 100644 (file)
@@ -490,7 +490,7 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
                 return log_link_error_errno(link, r, "Could not set default route: %m");
 
         Route *route_gw;
-        LIST_FOREACH(routes, route_gw, link->network->static_routes) {
+        HASHMAP_FOREACH(route_gw, link->network->routes_by_section) {
                 if (!route_gw->gateway_from_dhcp)
                         continue;
 
index db192cb475c123cdad194e3f5c86a97fe2f1137b..aa9a3346dcb7da8e5c50fab6e851c5afc6ab5c92 100644 (file)
@@ -217,14 +217,10 @@ int network_verify(Network *network) {
                         while ((address = network->static_addresses))
                                 address_free(address);
                 }
-                if (network->n_static_routes > 0) {
-                        Route *route;
-
+                if (!hashmap_isempty(network->routes_by_section))
                         log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
                                     network->filename);
-                        while ((route = network->static_routes))
-                                route_free(route);
-                }
+                network->routes_by_section = hashmap_free_with_destructor(network->routes_by_section, route_free);
         }
 
         if (network->link_local < 0)
@@ -624,7 +620,6 @@ failure:
 
 static Network *network_free(Network *network) {
         Address *address;
-        Route *route;
 
         if (!network)
                 return NULL;
@@ -681,15 +676,12 @@ static Network *network_free(Network *network) {
         netdev_unref(network->vrf);
         hashmap_free_with_destructor(network->stacked_netdevs, netdev_unref);
 
-        while ((route = network->static_routes))
-                route_free(route);
-
         while ((address = network->static_addresses))
                 address_free(address);
 
         set_free_free(network->ipv6_proxy_ndp_addresses);
         hashmap_free(network->addresses_by_section);
-        hashmap_free(network->routes_by_section);
+        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);
         hashmap_free_with_destructor(network->mdb_entries_by_section, mdb_entry_free);
@@ -814,7 +806,7 @@ bool network_has_static_ipv6_configurations(Network *network) {
                 if (address->family == AF_INET6)
                         return true;
 
-        LIST_FOREACH(routes, route, network->static_routes)
+        HASHMAP_FOREACH(route, network->routes_by_section)
                 if (route->family == AF_INET6)
                         return true;
 
index b7a93fb942cabe0404ea57a120128fbd95eb7cc2..847094170990fb75acbe62a61a38ea56100dafc8 100644 (file)
@@ -280,10 +280,8 @@ struct Network {
         char *lldp_mud;    /* LLDP MUD URL */
 
         LIST_HEAD(Address, static_addresses);
-        LIST_HEAD(Route, static_routes);
 
         unsigned n_static_addresses;
-        unsigned n_static_routes;
 
         Hashmap *addresses_by_section;
         Hashmap *routes_by_section;
index 460f3623a79528d1af9d9036c4e3693cf51a0898..453a33e1cea6b17e7379811ed4e879c03df63706 100644 (file)
@@ -194,22 +194,20 @@ static int route_new_static(Network *network, const char *filename, unsigned sec
 
         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);
 
-                route = hashmap_get(network->routes_by_section, n);
-                if (route) {
-                        *ret = TAKE_PTR(route);
+        r = network_config_section_new(filename, section_line, &n);
+        if (r < 0)
+                return r;
 
-                        return 0;
-                }
+        route = hashmap_get(network->routes_by_section, n);
+        if (route) {
+                *ret = TAKE_PTR(route);
+                return 0;
         }
 
-        if (network->n_static_routes >= routes_max())
+        if (hashmap_size(network->routes_by_section) >= routes_max())
                 return -E2BIG;
 
         r = route_new(&route);
@@ -218,23 +216,17 @@ static int route_new_static(Network *network, const char *filename, unsigned sec
 
         route->protocol = RTPROT_STATIC;
         route->network = network;
-        LIST_PREPEND(routes, network->static_routes, route);
-        network->n_static_routes++;
-
-        if (filename) {
-                route->section = TAKE_PTR(n);
+        route->section = TAKE_PTR(n);
 
-                r = hashmap_ensure_allocated(&network->routes_by_section, &network_config_hash_ops);
-                if (r < 0)
-                        return r;
+        r = hashmap_ensure_allocated(&network->routes_by_section, &network_config_hash_ops);
+        if (r < 0)
+                return r;
 
-                r = hashmap_put(network->routes_by_section, route->section, route);
-                if (r < 0)
-                        return r;
-        }
+        r = hashmap_put(network->routes_by_section, route->section, route);
+        if (r < 0)
+                return r;
 
         *ret = TAKE_PTR(route);
-
         return 0;
 }
 
@@ -243,13 +235,8 @@ Route *route_free(Route *route) {
                 return NULL;
 
         if (route->network) {
-                LIST_REMOVE(routes, route->network->static_routes, route);
-
-                assert(route->network->n_static_routes > 0);
-                route->network->n_static_routes--;
-
-                if (route->section)
-                        hashmap_remove(route->network->routes_by_section, route->section);
+                assert(route->section);
+                hashmap_remove(route->network->routes_by_section, route->section);
         }
 
         network_config_section_free(route->section);
@@ -630,7 +617,7 @@ static bool link_is_static_route_configured(Link *link, Route *route) {
         if (!link->network)
                 return false;
 
-        LIST_FOREACH(routes, net_route, link->network->static_routes)
+        HASHMAP_FOREACH(net_route, link->network->routes_by_section)
                 if (route_equal(net_route, route))
                         return true;
 
@@ -1065,7 +1052,7 @@ int link_set_routes(Link *link) {
 
         /* First add the routes that enable us to talk to gateways, then add in the others that need a gateway. */
         for (phase = 0; phase < _PHASE_MAX; phase++)
-                LIST_FOREACH(routes, rt, link->network->static_routes) {
+                HASHMAP_FOREACH(rt, link->network->routes_by_section) {
                         if (rt->gateway_from_dhcp)
                                 continue;
 
@@ -1437,6 +1424,7 @@ int link_deserialize_routes(Link *link, const char *routes) {
 
 int network_add_ipv4ll_route(Network *network) {
         _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
+        unsigned section_line;
         int r;
 
         assert(network);
@@ -1444,8 +1432,10 @@ int network_add_ipv4ll_route(Network *network) {
         if (!network->ipv4ll_route)
                 return 0;
 
+        section_line = hashmap_find_free_section_line(network->routes_by_section);
+
         /* IPv4LLRoute= is in [Network] section. */
-        r = route_new_static(network, NULL, 0, &n);
+        r = route_new_static(network, network->filename, section_line, &n);
         if (r < 0)
                 return r;
 
@@ -1467,6 +1457,7 @@ int network_add_ipv4ll_route(Network *network) {
 
 int network_add_default_route_on_device(Network *network) {
         _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
+        unsigned section_line;
         int r;
 
         assert(network);
@@ -1474,8 +1465,10 @@ int network_add_default_route_on_device(Network *network) {
         if (!network->default_route_on_device)
                 return 0;
 
+        section_line = hashmap_find_free_section_line(network->routes_by_section);
+
         /* DefaultRouteOnDevice= is in [Network] section. */
-        r = route_new_static(network, NULL, 0, &n);
+        r = route_new_static(network, network->filename, section_line, &n);
         if (r < 0)
                 return r;
 
@@ -1511,9 +1504,8 @@ int config_parse_gateway(
         assert(data);
 
         if (streq(section, "Network")) {
-                /* we are not in an Route section, so treat
-                 * this as the special '0' section */
-                r = route_new_static(network, NULL, 0, &n);
+                /* we are not in an Route section, so use line number instead */
+                r = route_new_static(network, filename, line, &n);
                 if (r == -ENOMEM)
                         return log_oom();
                 if (r < 0) {
@@ -2207,11 +2199,11 @@ static int route_section_verify(Route *route, Network *network) {
 }
 
 void network_verify_routes(Network *network) {
-        Route *route, *route_next;
+        Route *route;
 
         assert(network);
 
-        LIST_FOREACH_SAFE(routes, route, route_next, network->static_routes)
+        HASHMAP_FOREACH(route, network->routes_by_section)
                 if (route_section_verify(route, network) < 0)
                         route_free(route);
 }
index 7bbe16e7e028faa837f69597a307044f64324f1e..676bea3d701a745d57ff9fef2a6c27bd633c8ba1 100644 (file)
@@ -58,8 +58,6 @@ struct Route {
 
         usec_t lifetime;
         sd_event_source *expire;
-
-        LIST_FIELDS(Route, routes);
 };
 
 void route_hash_func(const Route *route, struct siphash *state);