From 2a54a0446b2ff2cd8f4fcded06fcc59602140079 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 2 Oct 2020 10:41:55 +0900 Subject: [PATCH] network: drop list of static routes [Route] sections are managed by both LIST and Hashmap. Let's drop the list. --- src/network/networkd-dhcp4.c | 2 +- src/network/networkd-ndisc.c | 2 +- src/network/networkd-network.c | 16 ++------ src/network/networkd-network.h | 2 - src/network/networkd-route.c | 74 +++++++++++++++------------------- src/network/networkd-route.h | 2 - 6 files changed, 39 insertions(+), 59 deletions(-) diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 8dd89c22a2..18ce0c61bb 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -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; diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 64b27276e0..256f6cc659 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -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; diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index db192cb475..aa9a3346dc 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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; diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index b7a93fb942..8470941709 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -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; diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 460f3623a7..453a33e1ce 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -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)); + 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; - route = hashmap_get(network->routes_by_section, n); - if (route) { - *ret = TAKE_PTR(route); - - 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++; + route->section = TAKE_PTR(n); - if (filename) { - 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); } diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 7bbe16e7e0..676bea3d70 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -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);