]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/nexthop: introduce ref/unref functions for NextHop object 30717/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 2 Jan 2024 19:41:27 +0000 (04:41 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 3 Jan 2024 19:58:36 +0000 (04:58 +0900)
src/network/networkd-network.c
src/network/networkd-nexthop.c
src/network/networkd-nexthop.h

index 51f5cacc140628d79368b4f1ea09a1e0fe36f83b..5638320b6dff4ec8d496137070d566499f9fcfbf 100644 (file)
@@ -784,7 +784,7 @@ static Network *network_free(Network *network) {
         set_free_free(network->ipv6_proxy_ndp_addresses);
         ordered_hashmap_free(network->addresses_by_section);
         hashmap_free_with_destructor(network->routes_by_section, route_free);
-        ordered_hashmap_free_with_destructor(network->nexthops_by_section, nexthop_free);
+        ordered_hashmap_free(network->nexthops_by_section);
         hashmap_free_with_destructor(network->bridge_fdb_entries_by_section, bridge_fdb_free);
         hashmap_free_with_destructor(network->bridge_mdb_entries_by_section, bridge_mdb_free);
         ordered_hashmap_free(network->neighbors_by_section);
index 1ab56a8ffdb79e8f43db748a52f99eefb1428818..a48080471e00eef6d316e7c915b175dad1e05eaa 100644 (file)
 #include "stdio-util.h"
 #include "string-util.h"
 
-NextHop *nexthop_free(NextHop *nexthop) {
-        if (!nexthop)
-                return NULL;
+static NextHop* nexthop_detach_impl(NextHop *nexthop) {
+        assert(nexthop);
+        assert(!nexthop->manager || !nexthop->network);
 
         if (nexthop->network) {
                 assert(nexthop->section);
                 ordered_hashmap_remove(nexthop->network->nexthops_by_section, nexthop->section);
+                nexthop->network = NULL;
+                return nexthop;
         }
 
-        config_section_free(nexthop->section);
-
         if (nexthop->manager) {
                 assert(nexthop->id > 0);
                 hashmap_remove(nexthop->manager->nexthops_by_id, UINT32_TO_PTR(nexthop->id));
+                nexthop->manager = NULL;
+                return nexthop;
         }
 
+        return NULL;
+}
+
+static void nexthop_detach(NextHop *nexthop) {
+        nexthop_unref(nexthop_detach_impl(nexthop));
+}
+
+static NextHop* nexthop_free(NextHop *nexthop) {
+        if (!nexthop)
+                return NULL;
+
+        nexthop_detach_impl(nexthop);
+
+        config_section_free(nexthop->section);
         hashmap_free_free(nexthop->group);
 
         return mfree(nexthop);
 }
 
-DEFINE_SECTION_CLEANUP_FUNCTIONS(NextHop, nexthop_free);
+DEFINE_TRIVIAL_REF_UNREF_FUNC(NextHop, nexthop, nexthop_free);
+DEFINE_SECTION_CLEANUP_FUNCTIONS(NextHop, nexthop_unref);
 
 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
                 nexthop_hash_ops,
@@ -47,17 +64,25 @@ DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
                 trivial_hash_func,
                 trivial_compare_func,
                 NextHop,
-                nexthop_free);
+                nexthop_detach);
+
+DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
+                nexthop_section_hash_ops,
+                ConfigSection,
+                config_section_hash_func,
+                config_section_compare_func,
+                NextHop,
+                nexthop_detach);
 
 static int nexthop_new(NextHop **ret) {
-        _cleanup_(nexthop_freep) NextHop *nexthop = NULL;
+        _cleanup_(nexthop_unrefp) NextHop *nexthop = NULL;
 
         nexthop = new(NextHop, 1);
         if (!nexthop)
                 return -ENOMEM;
 
         *nexthop = (NextHop) {
-                .family = AF_UNSPEC,
+                .n_ref = 1,
                 .onlink = -1,
         };
 
@@ -68,7 +93,7 @@ static int nexthop_new(NextHop **ret) {
 
 static int nexthop_new_static(Network *network, const char *filename, unsigned section_line, NextHop **ret) {
         _cleanup_(config_section_freep) ConfigSection *n = NULL;
-        _cleanup_(nexthop_freep) NextHop *nexthop = NULL;
+        _cleanup_(nexthop_unrefp) NextHop *nexthop = NULL;
         int r;
 
         assert(network);
@@ -95,7 +120,7 @@ static int nexthop_new_static(Network *network, const char *filename, unsigned s
         nexthop->section = TAKE_PTR(n);
         nexthop->source = NETWORK_CONFIG_SOURCE_STATIC;
 
-        r = ordered_hashmap_ensure_put(&network->nexthops_by_section, &config_section_hash_ops, nexthop->section, nexthop);
+        r = ordered_hashmap_ensure_put(&network->nexthops_by_section, &nexthop_section_hash_ops, nexthop->section, nexthop);
         if (r < 0)
                 return r;
 
@@ -171,7 +196,7 @@ static int nexthop_compare_full(const NextHop *a, const NextHop *b) {
 }
 
 static int nexthop_dup(const NextHop *src, NextHop **ret) {
-        _cleanup_(nexthop_freep) NextHop *dest = NULL;
+        _cleanup_(nexthop_unrefp) NextHop *dest = NULL;
         struct nexthop_grp *nhg;
         int r;
 
@@ -182,7 +207,8 @@ static int nexthop_dup(const NextHop *src, NextHop **ret) {
         if (!dest)
                 return -ENOMEM;
 
-        /* unset all pointers */
+        /* clear the reference counter and all pointers */
+        dest->n_ref = 1;
         dest->manager = NULL;
         dest->network = NULL;
         dest->section = NULL;
@@ -326,7 +352,7 @@ static int nexthop_get_request(Link *link, const NextHop *in, Request **ret) {
 }
 
 static int nexthop_add_new(Manager *manager, uint32_t id, NextHop **ret) {
-        _cleanup_(nexthop_freep) NextHop *nexthop = NULL;
+        _cleanup_(nexthop_unrefp) NextHop *nexthop = NULL;
         int r;
 
         assert(manager);
@@ -609,7 +635,7 @@ static int nexthop_process_request(Request *req, Link *link, NextHop *nexthop) {
 }
 
 static int link_request_nexthop(Link *link, const NextHop *nexthop) {
-        _cleanup_(nexthop_freep) NextHop *tmp = NULL;
+        _cleanup_(nexthop_unrefp) NextHop *tmp = NULL;
         NextHop *existing = NULL;
         int r;
 
@@ -644,7 +670,7 @@ static int link_request_nexthop(Link *link, const NextHop *nexthop) {
         log_nexthop_debug(tmp, "Requesting", link->manager);
         r = link_queue_request_safe(link, REQUEST_TYPE_NEXTHOP,
                                     tmp,
-                                    nexthop_free,
+                                    nexthop_unref,
                                     nexthop_hash_func,
                                     nexthop_compare_func,
                                     nexthop_process_request,
@@ -902,7 +928,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
                 if (nexthop) {
                         nexthop_enter_removed(nexthop);
                         log_nexthop_debug(nexthop, "Forgetting removed", m);
-                        nexthop_free(nexthop);
+                        nexthop_detach(nexthop);
                 } else
                         log_nexthop_debug(&(const NextHop) { .id = id }, "Kernel removed unknown", m);
 
@@ -1065,7 +1091,7 @@ int network_drop_invalid_nexthops(Network *network) {
 
         ORDERED_HASHMAP_FOREACH(nh, network->nexthops_by_section) {
                 if (nexthop_section_verify(nh) < 0) {
-                        nexthop_free(nh);
+                        nexthop_detach(nh);
                         continue;
                 }
 
@@ -1080,8 +1106,8 @@ int network_drop_invalid_nexthops(Network *network) {
                                     dup->section->filename,
                                     nh->id, nh->section->line,
                                     dup->section->line, dup->section->line);
-                        /* nexthop_free() will drop the nexthop from nexthops_by_section. */
-                        nexthop_free(dup);
+                        /* nexthop_detach() will drop the nexthop from nexthops_by_section. */
+                        nexthop_detach(dup);
                 }
 
                 r = hashmap_ensure_put(&nexthops, NULL, UINT32_TO_PTR(nh->id), nh);
@@ -1132,7 +1158,7 @@ int config_parse_nexthop_id(
                 void *data,
                 void *userdata) {
 
-        _cleanup_(nexthop_free_or_set_invalidp) NextHop *n = NULL;
+        _cleanup_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
         Network *network = userdata;
         uint32_t id;
         int r;
@@ -1182,7 +1208,7 @@ int config_parse_nexthop_gateway(
                 void *data,
                 void *userdata) {
 
-        _cleanup_(nexthop_free_or_set_invalidp) NextHop *n = NULL;
+        _cleanup_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
         Network *network = userdata;
         int r;
 
@@ -1227,7 +1253,7 @@ int config_parse_nexthop_family(
                 void *data,
                 void *userdata) {
 
-        _cleanup_(nexthop_free_or_set_invalidp) NextHop *n = NULL;
+        _cleanup_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
         Network *network = userdata;
         AddressFamily a;
         int r;
@@ -1293,7 +1319,7 @@ int config_parse_nexthop_onlink(
                 void *data,
                 void *userdata) {
 
-        _cleanup_(nexthop_free_or_set_invalidp) NextHop *n = NULL;
+        _cleanup_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
         Network *network = userdata;
         int r;
 
@@ -1330,7 +1356,7 @@ int config_parse_nexthop_blackhole(
                 void *data,
                 void *userdata) {
 
-        _cleanup_(nexthop_free_or_set_invalidp) NextHop *n = NULL;
+        _cleanup_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
         Network *network = userdata;
         int r;
 
@@ -1369,7 +1395,7 @@ int config_parse_nexthop_group(
                 void *data,
                 void *userdata) {
 
-        _cleanup_(nexthop_free_or_set_invalidp) NextHop *n = NULL;
+        _cleanup_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
         Network *network = userdata;
         int r;
 
index 564b52532fa72fb7aff3a75b14f420f256bc5e20..f79eda5cb1eaa777c2411b055f88ecfb798a57f6 100644 (file)
@@ -24,6 +24,8 @@ typedef struct NextHop {
         NetworkConfigSource source;
         NetworkConfigState state;
 
+        unsigned n_ref;
+
         uint8_t protocol;
         int ifindex;
         uint32_t id;
@@ -35,7 +37,8 @@ typedef struct NextHop {
         Hashmap *group;
 } NextHop;
 
-NextHop *nexthop_free(NextHop *nexthop);
+NextHop* nexthop_ref(NextHop *nexthop);
+NextHop* nexthop_unref(NextHop *nexthop);
 
 int network_drop_invalid_nexthops(Network *network);