forked from Mirror/frr
lib: fix route map northbound memory leak
Keep a list of hook contexts used by northbound so we don't lose the pointer when free()ing the route map index entry data. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
91835f1fd2
commit
54a35ff48b
|
@ -909,6 +909,7 @@ static struct route_map_index *route_map_index_new(void)
|
||||||
|
|
||||||
new = XCALLOC(MTYPE_ROUTE_MAP_INDEX, sizeof(struct route_map_index));
|
new = XCALLOC(MTYPE_ROUTE_MAP_INDEX, sizeof(struct route_map_index));
|
||||||
new->exitpolicy = RMAP_EXIT; /* Default to Cisco-style */
|
new->exitpolicy = RMAP_EXIT; /* Default to Cisco-style */
|
||||||
|
TAILQ_INIT(&new->rhclist);
|
||||||
QOBJ_REG(new, route_map_index);
|
QOBJ_REG(new, route_map_index);
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
@ -924,6 +925,10 @@ void route_map_index_delete(struct route_map_index *index, int notify)
|
||||||
zlog_debug("Deleting route-map %s sequence %d",
|
zlog_debug("Deleting route-map %s sequence %d",
|
||||||
index->map->name, index->pref);
|
index->map->name, index->pref);
|
||||||
|
|
||||||
|
/* Free route map northbound hook contexts. */
|
||||||
|
while (!TAILQ_EMPTY(&index->rhclist))
|
||||||
|
routemap_hook_context_free(TAILQ_FIRST(&index->rhclist));
|
||||||
|
|
||||||
/* Free route match. */
|
/* Free route match. */
|
||||||
while ((rule = index->match_list.head) != NULL)
|
while ((rule = index->match_list.head) != NULL)
|
||||||
route_map_rule_delete(&index->match_list, rule);
|
route_map_rule_delete(&index->match_list, rule);
|
||||||
|
|
|
@ -162,6 +162,9 @@ struct route_map_rule_list {
|
||||||
struct route_map_rule *tail;
|
struct route_map_rule *tail;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Forward struct declaration: the complete can be found later this file. */
|
||||||
|
struct routemap_hook_context;
|
||||||
|
|
||||||
/* Route map index structure. */
|
/* Route map index structure. */
|
||||||
struct route_map_index {
|
struct route_map_index {
|
||||||
struct route_map *map;
|
struct route_map *map;
|
||||||
|
@ -194,6 +197,9 @@ struct route_map_index {
|
||||||
uint64_t applied;
|
uint64_t applied;
|
||||||
uint64_t applied_clear;
|
uint64_t applied_clear;
|
||||||
|
|
||||||
|
/* List of match/sets contexts. */
|
||||||
|
TAILQ_HEAD(, routemap_hook_context) rhclist;
|
||||||
|
|
||||||
QOBJ_FIELDS
|
QOBJ_FIELDS
|
||||||
};
|
};
|
||||||
DECLARE_QOBJ_TYPE(route_map_index)
|
DECLARE_QOBJ_TYPE(route_map_index)
|
||||||
|
@ -660,6 +666,7 @@ struct routemap_hook_context {
|
||||||
route_map_event_t rhc_event;
|
route_map_event_t rhc_event;
|
||||||
routemap_set_hook_fun rhc_shook;
|
routemap_set_hook_fun rhc_shook;
|
||||||
routemap_match_hook_fun rhc_mhook;
|
routemap_match_hook_fun rhc_mhook;
|
||||||
|
TAILQ_ENTRY(routemap_hook_context) rhc_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
int lib_route_map_entry_match_destroy(enum nb_event event,
|
int lib_route_map_entry_match_destroy(enum nb_event event,
|
||||||
|
@ -667,6 +674,10 @@ int lib_route_map_entry_match_destroy(enum nb_event event,
|
||||||
int lib_route_map_entry_set_destroy(enum nb_event event,
|
int lib_route_map_entry_set_destroy(enum nb_event event,
|
||||||
const struct lyd_node *dnode);
|
const struct lyd_node *dnode);
|
||||||
|
|
||||||
|
struct routemap_hook_context *
|
||||||
|
routemap_hook_context_insert(struct route_map_index *rmi);
|
||||||
|
void routemap_hook_context_free(struct routemap_hook_context *rhc);
|
||||||
|
|
||||||
extern const struct frr_yang_module_info frr_route_map_info;
|
extern const struct frr_yang_module_info frr_route_map_info;
|
||||||
|
|
||||||
/* routemap_cli.c */
|
/* routemap_cli.c */
|
||||||
|
|
|
@ -74,6 +74,30 @@ int lib_route_map_entry_set_destroy(enum nb_event event,
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Auxiliary hook context list manipulation functions.
|
||||||
|
*/
|
||||||
|
struct routemap_hook_context *
|
||||||
|
routemap_hook_context_insert(struct route_map_index *rmi)
|
||||||
|
{
|
||||||
|
struct routemap_hook_context *rhc;
|
||||||
|
|
||||||
|
rhc = XCALLOC(MTYPE_TMP, sizeof(*rhc));
|
||||||
|
rhc->rhc_rmi = rmi;
|
||||||
|
TAILQ_INSERT_TAIL(&rmi->rhclist, rhc, rhc_entry);
|
||||||
|
|
||||||
|
return rhc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
routemap_hook_context_free(struct routemap_hook_context *rhc)
|
||||||
|
{
|
||||||
|
struct route_map_index *rmi = rhc->rhc_rmi;
|
||||||
|
|
||||||
|
TAILQ_REMOVE(&rmi->rhclist, rhc, rhc_entry);
|
||||||
|
XFREE(MTYPE_TMP, rhc);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XPath: /frr-route-map:lib/route-map
|
* XPath: /frr-route-map:lib/route-map
|
||||||
*/
|
*/
|
||||||
|
@ -436,20 +460,17 @@ lib_route_map_entry_match_condition_create(enum nb_event event,
|
||||||
union nb_resource *resource)
|
union nb_resource *resource)
|
||||||
{
|
{
|
||||||
struct routemap_hook_context *rhc;
|
struct routemap_hook_context *rhc;
|
||||||
|
struct route_map_index *rmi;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NB_EV_VALIDATE:
|
case NB_EV_VALIDATE:
|
||||||
|
case NB_EV_PREPARE:
|
||||||
|
case NB_EV_ABORT:
|
||||||
/* NOTHING */
|
/* NOTHING */
|
||||||
break;
|
break;
|
||||||
case NB_EV_PREPARE:
|
|
||||||
resource->ptr = XCALLOC(MTYPE_TMP, sizeof(*rhc));
|
|
||||||
break;
|
|
||||||
case NB_EV_ABORT:
|
|
||||||
XFREE(MTYPE_TMP, resource->ptr);
|
|
||||||
break;
|
|
||||||
case NB_EV_APPLY:
|
case NB_EV_APPLY:
|
||||||
rhc = resource->ptr;
|
rmi = nb_running_get_entry(dnode, NULL, true);
|
||||||
rhc->rhc_rmi = nb_running_get_entry(dnode, NULL, true);
|
rhc = routemap_hook_context_insert(rmi);
|
||||||
nb_running_set_entry(dnode, rhc);
|
nb_running_set_entry(dnode, rhc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -469,7 +490,7 @@ lib_route_map_entry_match_condition_destroy(enum nb_event event,
|
||||||
|
|
||||||
rv = lib_route_map_entry_match_destroy(event, dnode);
|
rv = lib_route_map_entry_match_destroy(event, dnode);
|
||||||
rhc = nb_running_unset_entry(dnode);
|
rhc = nb_running_unset_entry(dnode);
|
||||||
XFREE(MTYPE_TMP, rhc);
|
routemap_hook_context_free(rhc);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -893,7 +914,7 @@ static int lib_route_map_entry_set_action_destroy(enum nb_event event,
|
||||||
|
|
||||||
rv = lib_route_map_entry_set_destroy(event, dnode);
|
rv = lib_route_map_entry_set_destroy(event, dnode);
|
||||||
rhc = nb_running_unset_entry(dnode);
|
rhc = nb_running_unset_entry(dnode);
|
||||||
XFREE(MTYPE_TMP, rhc);
|
routemap_hook_context_free(rhc);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue