Skip to content

Commit 97fa24e

Browse files
committed
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 <[email protected]>
1 parent 465d286 commit 97fa24e

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

zebra/zebra_nhg.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3089,7 +3089,7 @@ static struct nhg_hash_entry *zebra_nhg_rib_compare_old_nhe(
30893089
int nexthop_active_update(struct route_node *rn, struct route_entry *re,
30903090
struct route_entry *old_re)
30913091
{
3092-
struct nhg_hash_entry *curr_nhe;
3092+
struct nhg_hash_entry *curr_nhe, *remove;
30933093
uint32_t curr_active = 0, backup_active = 0;
30943094

30953095
if (PROTO_OWNED(re->nhe))
@@ -3143,16 +3143,25 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re,
31433143

31443144
new_nhe = zebra_nhg_rib_find_nhe(curr_nhe, rt_afi);
31453145

3146+
remove = new_nhe;
3147+
31463148
if (old_re && old_re->type == re->type &&
31473149
old_re->instance == re->instance)
31483150
new_nhe = zebra_nhg_rib_compare_old_nhe(rn, re, new_nhe,
31493151
old_re->nhe);
31503152

31513153
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
3152-
zlog_debug(
3153-
"%s: re %p CHANGED: nhe %p (%pNG) => new_nhe %p (%pNG)",
3154-
__func__, re, re->nhe, re->nhe, new_nhe,
3155-
new_nhe);
3154+
zlog_debug("%s: re %p CHANGED: nhe %p (%pNG) => new_nhe %p (%pNG) rib_find_nhe returned %p (%pNG) refcnt: %d",
3155+
__func__, re, re->nhe, re->nhe, new_nhe, new_nhe, remove, remove,
3156+
remove ? remove->refcnt : 0);
3157+
3158+
/*
3159+
* if the results from zebra_nhg_rib_find_nhe is being
3160+
* dropped and it was generated in that function
3161+
* (refcnt of 0) then we know we can clean it up
3162+
*/
3163+
if (remove && remove != new_nhe && remove != re->nhe && remove->refcnt == 0)
3164+
zebra_nhg_handle_uninstall(remove);
31563165

31573166
route_entry_update_nhe(re, new_nhe);
31583167
}

0 commit comments

Comments
 (0)