mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 01:14:48 +00:00
isisd: fix refcounting in isis_route.c
This fixes multiple issues and inefficiencies regarding the usage of route_tables in isis_route.c and removes some memory leaks. Signed-off-by: Christian Franke <chris@opensourcerouting.org>
This commit is contained in:
parent
321c1bbb94
commit
bcd9fd5011
@ -353,6 +353,7 @@ struct isis_route_info *isis_route_create(struct prefix *prefix,
|
||||
route_info = rinfo_new;
|
||||
UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
|
||||
} else {
|
||||
route_unlock_node(route_node);
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_debug("ISIS-Rte (%s) route already exists: %s",
|
||||
area->area_tag, buff);
|
||||
@ -379,20 +380,21 @@ struct isis_route_info *isis_route_create(struct prefix *prefix,
|
||||
return route_info;
|
||||
}
|
||||
|
||||
static void isis_route_delete(struct prefix *prefix,
|
||||
struct prefix_ipv6 *src_p,
|
||||
static void isis_route_delete(struct route_node *rode,
|
||||
struct route_table *table)
|
||||
{
|
||||
struct route_node *rode;
|
||||
struct isis_route_info *rinfo;
|
||||
char buff[SRCDEST2STR_BUFFER];
|
||||
struct prefix *prefix;
|
||||
struct prefix_ipv6 *src_p;
|
||||
|
||||
/* for log */
|
||||
srcdest2str(prefix, src_p, buff, sizeof(buff));
|
||||
srcdest_rnode2str(rode, buff, sizeof(buff));
|
||||
|
||||
srcdest_rnode_prefixes(rode, (const struct prefix **)&prefix,
|
||||
(const struct prefix **)&src_p);
|
||||
|
||||
rode = srcdest_rnode_get(table, prefix, src_p);
|
||||
rinfo = rode->info;
|
||||
|
||||
if (rinfo == NULL) {
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_debug(
|
||||
@ -409,8 +411,7 @@ static void isis_route_delete(struct prefix *prefix,
|
||||
}
|
||||
isis_route_info_delete(rinfo);
|
||||
rode->info = NULL;
|
||||
|
||||
return;
|
||||
route_unlock_node(rode);
|
||||
}
|
||||
|
||||
static void _isis_route_verify_table(struct isis_area *area,
|
||||
@ -454,28 +455,38 @@ static void _isis_route_verify_table(struct isis_area *area,
|
||||
}
|
||||
|
||||
isis_zebra_route_update(dst_p, src_p, rinfo);
|
||||
if (!CHECK_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE)) {
|
||||
/* Area is either L1 or L2 => we use level route tables
|
||||
* directly for
|
||||
* validating => no problems with deleting routes. */
|
||||
if (!tables) {
|
||||
isis_route_delete(dst_p, src_p, table);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If area is L1L2, we work with merge table and
|
||||
* therefore must
|
||||
* delete node from level tables as well before deleting
|
||||
* route info. */
|
||||
for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
|
||||
drnode = srcdest_rnode_get(tables[level - 1],
|
||||
dst_p, src_p);
|
||||
if (drnode->info == rnode->info)
|
||||
drnode->info = NULL;
|
||||
}
|
||||
if (CHECK_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE))
|
||||
continue;
|
||||
|
||||
isis_route_delete(dst_p, src_p, table);
|
||||
/* Area is either L1 or L2 => we use level route tables
|
||||
* directly for
|
||||
* validating => no problems with deleting routes. */
|
||||
if (!tables) {
|
||||
isis_route_delete(rnode, table);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If area is L1L2, we work with merge table and
|
||||
* therefore must
|
||||
* delete node from level tables as well before deleting
|
||||
* route info. */
|
||||
for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
|
||||
drnode = srcdest_rnode_lookup(tables[level - 1],
|
||||
dst_p, src_p);
|
||||
if (!drnode)
|
||||
continue;
|
||||
|
||||
route_unlock_node(drnode);
|
||||
|
||||
if (drnode->info != rnode->info)
|
||||
continue;
|
||||
|
||||
drnode->info = NULL;
|
||||
route_unlock_node(drnode);
|
||||
}
|
||||
|
||||
isis_route_delete(rnode, table);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user