From: Yu Watanabe Date: Tue, 2 Jan 2024 19:41:27 +0000 (+0900) Subject: network/nexthop: introduce ref/unref functions for NextHop object X-Git-Tag: v256-rc1~1199^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=59ac53a690dcda473a635022f08efbe533ddb110;p=thirdparty%2Fsystemd.git network/nexthop: introduce ref/unref functions for NextHop object --- diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 51f5cacc140..5638320b6df 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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); diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c index 1ab56a8ffdb..a48080471e0 100644 --- a/src/network/networkd-nexthop.c +++ b/src/network/networkd-nexthop.c @@ -18,28 +18,45 @@ #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; diff --git a/src/network/networkd-nexthop.h b/src/network/networkd-nexthop.h index 564b52532fa..f79eda5cb1e 100644 --- a/src/network/networkd-nexthop.h +++ b/src/network/networkd-nexthop.h @@ -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);