#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,
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,
};
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);
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;
}
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;
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;
}
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);
}
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;
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,
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);
ORDERED_HASHMAP_FOREACH(nh, network->nexthops_by_section) {
if (nexthop_section_verify(nh) < 0) {
- nexthop_free(nh);
+ nexthop_detach(nh);
continue;
}
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);
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;
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;
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;
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;
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;
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;