forked from Mirror/frr
zebra: Fix leaked nhe
During route processing in zebra, Zebra will create a nexthop group that matches the nexthops passed down from the routing protocol. Then Zebra will look to see if it can re-use a nhe from a previous version of the route entry( say a interface goes down ). If Zebra decides to re-use an nhe it was just dropping the route entry created. Which led to nexthop group's that had a refcount of 0 and in some cases these nexthop groups were installed into the kernel. Add a bit of code to see if the returned entry is not being used and it has no reference count and if so, properly dispose of it. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This commit is contained in:
parent
465d286819
commit
97fa24e70b
|
@ -3089,7 +3089,7 @@ static struct nhg_hash_entry *zebra_nhg_rib_compare_old_nhe(
|
||||||
int nexthop_active_update(struct route_node *rn, struct route_entry *re,
|
int nexthop_active_update(struct route_node *rn, struct route_entry *re,
|
||||||
struct route_entry *old_re)
|
struct route_entry *old_re)
|
||||||
{
|
{
|
||||||
struct nhg_hash_entry *curr_nhe;
|
struct nhg_hash_entry *curr_nhe, *remove;
|
||||||
uint32_t curr_active = 0, backup_active = 0;
|
uint32_t curr_active = 0, backup_active = 0;
|
||||||
|
|
||||||
if (PROTO_OWNED(re->nhe))
|
if (PROTO_OWNED(re->nhe))
|
||||||
|
@ -3143,16 +3143,25 @@ backups_done:
|
||||||
|
|
||||||
new_nhe = zebra_nhg_rib_find_nhe(curr_nhe, rt_afi);
|
new_nhe = zebra_nhg_rib_find_nhe(curr_nhe, rt_afi);
|
||||||
|
|
||||||
|
remove = new_nhe;
|
||||||
|
|
||||||
if (old_re && old_re->type == re->type &&
|
if (old_re && old_re->type == re->type &&
|
||||||
old_re->instance == re->instance)
|
old_re->instance == re->instance)
|
||||||
new_nhe = zebra_nhg_rib_compare_old_nhe(rn, re, new_nhe,
|
new_nhe = zebra_nhg_rib_compare_old_nhe(rn, re, new_nhe,
|
||||||
old_re->nhe);
|
old_re->nhe);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
||||||
zlog_debug(
|
zlog_debug("%s: re %p CHANGED: nhe %p (%pNG) => new_nhe %p (%pNG) rib_find_nhe returned %p (%pNG) refcnt: %d",
|
||||||
"%s: re %p CHANGED: nhe %p (%pNG) => new_nhe %p (%pNG)",
|
__func__, re, re->nhe, re->nhe, new_nhe, new_nhe, remove, remove,
|
||||||
__func__, re, re->nhe, re->nhe, new_nhe,
|
remove ? remove->refcnt : 0);
|
||||||
new_nhe);
|
|
||||||
|
/*
|
||||||
|
* if the results from zebra_nhg_rib_find_nhe is being
|
||||||
|
* dropped and it was generated in that function
|
||||||
|
* (refcnt of 0) then we know we can clean it up
|
||||||
|
*/
|
||||||
|
if (remove && remove != new_nhe && remove != re->nhe && remove->refcnt == 0)
|
||||||
|
zebra_nhg_handle_uninstall(remove);
|
||||||
|
|
||||||
route_entry_update_nhe(re, new_nhe);
|
route_entry_update_nhe(re, new_nhe);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue