From fb126bb16835ec162673051c1836a74052d2240f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 15 Dec 2023 09:04:57 +0900 Subject: [PATCH] network/nexthop: cache requested nexthop IDs --- src/network/networkd-manager.c | 11 +++++++- src/network/networkd-manager.h | 1 + src/network/networkd-network.c | 10 +++++++- src/network/networkd-nexthop.c | 46 +++++++++++++++++++++------------- src/network/networkd-nexthop.h | 1 + 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index b162d21aa0f..d5ee841b1b1 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -650,6 +650,7 @@ Manager* manager_free(Manager *m) { m->routes = set_free(m->routes); m->nexthops_by_id = hashmap_free(m->nexthops_by_id); + m->nexthop_ids = set_free(m->nexthop_ids); sd_event_source_unref(m->speed_meter_event_source); sd_event_unref(m->event); @@ -708,7 +709,15 @@ int manager_load_config(Manager *m) { if (r < 0) return r; - return manager_build_dhcp_pd_subnet_ids(m); + r = manager_build_dhcp_pd_subnet_ids(m); + if (r < 0) + return r; + + r = manager_build_nexthop_ids(m); + if (r < 0) + return r; + + return 0; } int manager_enumerate_internal( diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index a9827d8a4b4..c20e7ff767b 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -73,6 +73,7 @@ struct Manager { /* Manage nexthops by id. */ Hashmap *nexthops_by_id; + Set *nexthop_ids; /* requested IDs in .network files */ /* Manager stores routes without RTA_OIF attribute. */ unsigned route_remove_messages; diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 1bf7b8b46c7..dcfdfd1b52e 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -636,7 +636,15 @@ int network_reload(Manager *manager) { ordered_hashmap_free_with_destructor(manager->networks, network_unref); manager->networks = new_networks; - return manager_build_dhcp_pd_subnet_ids(manager); + r = manager_build_dhcp_pd_subnet_ids(manager); + if (r < 0) + return r; + + r = manager_build_nexthop_ids(manager); + if (r < 0) + return r; + + return 0; failure: ordered_hashmap_free_with_destructor(new_networks, network_unref); diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c index 7ebeb961529..4a9c84e5e76 100644 --- a/src/network/networkd-nexthop.c +++ b/src/network/networkd-nexthop.c @@ -344,10 +344,6 @@ static int nexthop_add_new(Manager *manager, uint32_t id, NextHop **ret) { } static int nexthop_acquire_id(Manager *manager, NextHop *nexthop) { - _cleanup_set_free_ Set *ids = NULL; - Network *network; - int r; - assert(manager); assert(nexthop); @@ -360,25 +356,12 @@ static int nexthop_acquire_id(Manager *manager, NextHop *nexthop) { /* Find the lowest unused ID. */ - ORDERED_HASHMAP_FOREACH(network, manager->networks) { - NextHop *tmp; - - ORDERED_HASHMAP_FOREACH(tmp, network->nexthops_by_section) { - if (tmp->id == 0) - continue; - - r = set_ensure_put(&ids, NULL, UINT32_TO_PTR(tmp->id)); - if (r < 0) - return r; - } - } - for (uint32_t id = 1; id < UINT32_MAX; id++) { if (nexthop_get_by_id(manager, id, NULL) >= 0) continue; if (nexthop_get_request_by_id(manager, id, NULL) >= 0) continue; - if (set_contains(ids, UINT32_TO_PTR(id))) + if (set_contains(manager->nexthop_ids, UINT32_TO_PTR(id))) continue; nexthop->id = id; @@ -1100,6 +1083,33 @@ int network_drop_invalid_nexthops(Network *network) { return 0; } +int manager_build_nexthop_ids(Manager *manager) { + Network *network; + int r; + + assert(manager); + + if (!manager->manage_foreign_nexthops) + return 0; + + manager->nexthop_ids = set_free(manager->nexthop_ids); + + ORDERED_HASHMAP_FOREACH(network, manager->networks) { + NextHop *nh; + + ORDERED_HASHMAP_FOREACH(nh, network->nexthops_by_section) { + if (nh->id == 0) + continue; + + r = set_ensure_put(&manager->nexthop_ids, NULL, UINT32_TO_PTR(nh->id)); + if (r < 0) + return r; + } + } + + return 0; +} + int config_parse_nexthop_id( const char *unit, const char *filename, diff --git a/src/network/networkd-nexthop.h b/src/network/networkd-nexthop.h index 025307c4606..564b52532fa 100644 --- a/src/network/networkd-nexthop.h +++ b/src/network/networkd-nexthop.h @@ -52,6 +52,7 @@ int link_request_static_nexthops(Link *link, bool only_ipv4); int nexthop_get_by_id(Manager *manager, uint32_t id, NextHop **ret); int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m); +int manager_build_nexthop_ids(Manager *manager); DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(NextHop, nexthop); -- 2.39.2