Skip to content

Commit

Permalink
zebra: Fix leaked nhe
Browse files Browse the repository at this point in the history
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 <[email protected]>
(cherry picked from commit 97fa24e)

# Conflicts:
#	zebra/zebra_nhg.c
  • Loading branch information
donaldsharp authored and mergify[bot] committed Jan 9, 2025
1 parent 9f51282 commit 4d22986
Showing 1 changed file with 22 additions and 5 deletions.
27 changes: 22 additions & 5 deletions zebra/zebra_nhg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2920,7 +2920,7 @@ static uint32_t proto_nhg_nexthop_active_update(struct nexthop_group *nhg)
*/
int nexthop_active_update(struct route_node *rn, struct route_entry *re)
{
struct nhg_hash_entry *curr_nhe;
struct nhg_hash_entry *curr_nhe, *remove;
uint32_t curr_active = 0, backup_active = 0;

if (PROTO_OWNED(re->nhe))
Expand Down Expand Up @@ -2974,11 +2974,28 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)

new_nhe = zebra_nhg_rib_find_nhe(curr_nhe, rt_afi);

<<<<<<< HEAD
=======
remove = new_nhe;

if (old_re && old_re->type == re->type &&
old_re->instance == re->instance)
new_nhe = zebra_nhg_rib_compare_old_nhe(rn, re, new_nhe,
old_re->nhe);

>>>>>>> 97fa24e70 (zebra: Fix leaked nhe)
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
zlog_debug(
"%s: re %p CHANGED: nhe %p (%pNG) => new_nhe %p (%pNG)",
__func__, re, re->nhe, re->nhe, new_nhe,
new_nhe);
zlog_debug("%s: re %p CHANGED: nhe %p (%pNG) => new_nhe %p (%pNG) rib_find_nhe returned %p (%pNG) refcnt: %d",
__func__, re, re->nhe, re->nhe, new_nhe, new_nhe, remove, remove,
remove ? remove->refcnt : 0);

/*
* 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);
}
Expand Down

0 comments on commit 4d22986

Please sign in to comment.