]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/nexthop: cache requested nexthop IDs
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 15 Dec 2023 00:04:57 +0000 (09:04 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 20 Dec 2023 19:22:46 +0000 (04:22 +0900)
src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/networkd-network.c
src/network/networkd-nexthop.c
src/network/networkd-nexthop.h

index b162d21aa0f9f91720f2cdc819f6775e3b6f82b9..d5ee841b1b106871916f5d5a79686a7648e0c57b 100644 (file)
@@ -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(
index a9827d8a4b4fffea9b61280829b5abc6e40691b6..c20e7ff767b5cf0f9182983a9f70dbbfbf75d07a 100644 (file)
@@ -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;
index 1bf7b8b46c7e5f224dabc295d8fd7c504b45dfa7..dcfdfd1b52eade6da994d3e834fea3fe85afbd6b 100644 (file)
@@ -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);
index 7ebeb9615299dc511a4cc729a84fbb68180bd18f..4a9c84e5e761805f8788d03fd24e36626c4c8cdd 100644 (file)
@@ -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,
index 025307c4606af8d247d4ec8f2224f991c80ec7c2..564b52532fa72fb7aff3a75b14f420f256bc5e20 100644 (file)
@@ -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);