diff options
author | Russ White <russ@riw.us> | 2023-05-02 17:33:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-02 17:33:38 +0200 |
commit | d0053da26b49166353c5f48c11fb11f6bea691d0 (patch) | |
tree | 5eed5e43a11b695373a1951869489c05a63c27c0 | |
parent | Merge pull request #13366 from zmw12306/rte_tag (diff) | |
parent | isisd: fix a memory leak in isis_spftree_clear() (diff) | |
download | frr-d0053da26b49166353c5f48c11fb11f6bea691d0.tar.xz frr-d0053da26b49166353c5f48c11fb11f6bea691d0.zip |
Merge pull request #13376 from louis-6wind/fix-flex-algo-mem-leak
isisd, lib: fix flex-algo memory leak
-rw-r--r-- | isisd/isis_flex_algo.c | 3 | ||||
-rw-r--r-- | isisd/isis_spf.c | 4 | ||||
-rw-r--r-- | isisd/isisd.c | 4 | ||||
-rw-r--r-- | lib/flex_algo.c | 66 | ||||
-rw-r--r-- | lib/flex_algo.h | 1 |
5 files changed, 53 insertions, 25 deletions
diff --git a/isisd/isis_flex_algo.c b/isisd/isis_flex_algo.c index 0efc519ea..ef30987b8 100644 --- a/isisd/isis_flex_algo.c +++ b/isisd/isis_flex_algo.c @@ -45,7 +45,7 @@ void *isis_flex_algo_data_alloc(void *voidarg) struct isis_flex_algo_alloc_arg *arg = voidarg; struct isis_flex_algo_data *data; - data = XCALLOC(MTYPE_FLEX_ALGO, sizeof(*data)); + data = XCALLOC(MTYPE_FLEX_ALGO, sizeof(struct isis_flex_algo_data)); for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) { for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) { @@ -70,6 +70,7 @@ void isis_flex_algo_data_free(void *voiddata) if (data->spftree[tree][level - 1]) isis_spftree_del( data->spftree[tree][level - 1]); + XFREE(MTYPE_FLEX_ALGO, data); } static struct isis_router_cap_fad * diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 156c8b089..de467c826 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -393,14 +393,14 @@ static void _isis_spftree_del(struct isis_spftree *spftree) isis_vertex_queue_free(&spftree->paths); isis_route_table_info_free(spftree->route_table->info); isis_route_table_info_free(spftree->route_table_backup->info); + route_table_finish(spftree->route_table); + route_table_finish(spftree->route_table_backup); } void isis_spftree_del(struct isis_spftree *spftree) { _isis_spftree_del(spftree); - route_table_finish(spftree->route_table); - route_table_finish(spftree->route_table_backup); spftree->route_table = NULL; XFREE(MTYPE_ISIS_SPFTREE, spftree); diff --git a/isisd/isisd.c b/isisd/isisd.c index 4b01a18ec..ea304ba5e 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -520,6 +520,10 @@ void isis_area_destroy(struct isis_area *area) isis_area_invalidate_routes(area, area->is_type); isis_area_verify_routes(area); +#ifndef FABRICD + flex_algos_free(area->flex_algos); +#endif /* ifndef FABRICD */ + isis_sr_area_term(area); isis_mpls_te_term(area); diff --git a/lib/flex_algo.c b/lib/flex_algo.c index efeacb5a0..f48117ff1 100644 --- a/lib/flex_algo.c +++ b/lib/flex_algo.c @@ -17,26 +17,42 @@ #include "flex_algo.h" -DEFINE_MTYPE_STATIC(LIB, FLEX_ALGO, "Flex-Algo Definition"); +DEFINE_MTYPE_STATIC(LIB, FLEX_ALGO_DATABASE, "Flex-Algo database"); +DEFINE_MTYPE_STATIC(LIB, FLEX_ALGO, "Flex-Algo algorithm information"); + +static void _flex_algo_delete(struct flex_algos *flex_algos, + struct flex_algo *fa); struct flex_algos *flex_algos_alloc(flex_algo_allocator_t allocator, flex_algo_releaser_t releaser) { struct flex_algos *flex_algos; - flex_algos = XCALLOC(MTYPE_FLEX_ALGO, sizeof(*flex_algos)); + flex_algos = + XCALLOC(MTYPE_FLEX_ALGO_DATABASE, sizeof(struct flex_algos)); flex_algos->flex_algos = list_new(); flex_algos->allocator = allocator; flex_algos->releaser = releaser; return flex_algos; } +void flex_algos_free(struct flex_algos *flex_algos) +{ + struct listnode *node, *nnode; + struct flex_algo *fa; + + for (ALL_LIST_ELEMENTS(flex_algos->flex_algos, node, nnode, fa)) + _flex_algo_delete(flex_algos, fa); + list_delete(&flex_algos->flex_algos); + XFREE(MTYPE_FLEX_ALGO_DATABASE, flex_algos); +} + struct flex_algo *flex_algo_alloc(struct flex_algos *flex_algos, uint8_t algorithm, void *arg) { struct flex_algo *fa; - fa = XCALLOC(MTYPE_FLEX_ALGO, sizeof(*fa)); + fa = XCALLOC(MTYPE_FLEX_ALGO, sizeof(struct flex_algo)); fa->algorithm = algorithm; if (flex_algos->allocator) fa->data = flex_algos->allocator(arg); @@ -47,6 +63,31 @@ struct flex_algo *flex_algo_alloc(struct flex_algos *flex_algos, return fa; } +static void _flex_algo_delete(struct flex_algos *flex_algos, + struct flex_algo *fa) +{ + if (flex_algos->releaser) + flex_algos->releaser(fa->data); + admin_group_term(&fa->admin_group_exclude_any); + admin_group_term(&fa->admin_group_include_any); + admin_group_term(&fa->admin_group_include_all); + listnode_delete(flex_algos->flex_algos, fa); + XFREE(MTYPE_FLEX_ALGO, fa); +} + + +void flex_algo_delete(struct flex_algos *flex_algos, uint8_t algorithm) +{ + struct listnode *node, *nnode; + struct flex_algo *fa; + + for (ALL_LIST_ELEMENTS(flex_algos->flex_algos, node, nnode, fa)) { + if (fa->algorithm != algorithm) + continue; + _flex_algo_delete(flex_algos, fa); + } +} + /** * @brief Look up the local flex-algo object by its algorithm number. * @param algorithm flex-algo algorithm number @@ -99,25 +140,6 @@ bool flex_algo_definition_cmp(struct flex_algo *fa1, struct flex_algo *fa2) return true; } -void flex_algo_delete(struct flex_algos *flex_algos, uint8_t algorithm) -{ - struct listnode *node, *nnode; - struct flex_algo *fa; - - for (ALL_LIST_ELEMENTS(flex_algos->flex_algos, node, nnode, fa)) { - if (fa->algorithm != algorithm) - continue; - if (flex_algos->releaser) - flex_algos->releaser(fa->data); - admin_group_term(&fa->admin_group_exclude_any); - admin_group_term(&fa->admin_group_include_any); - admin_group_term(&fa->admin_group_include_all); - listnode_delete(flex_algos->flex_algos, fa); - XFREE(MTYPE_FLEX_ALGO, fa); - return; - } -} - /** * Check SR Algorithm is Flex-Algo * according to RFC9350 section 4 diff --git a/lib/flex_algo.h b/lib/flex_algo.h index 81a0af85b..e617e7cae 100644 --- a/lib/flex_algo.h +++ b/lib/flex_algo.h @@ -112,6 +112,7 @@ struct flex_algos { */ struct flex_algos *flex_algos_alloc(flex_algo_allocator_t allocator, flex_algo_releaser_t releaser); +void flex_algos_free(struct flex_algos *flex_algos); struct flex_algo *flex_algo_alloc(struct flex_algos *flex_algos, uint8_t algorithm, void *arg); struct flex_algo *flex_algo_lookup(struct flex_algos *flex_algos, |