diff options
Diffstat (limited to 'zebra/zebra_nhg.c')
| -rw-r--r-- | zebra/zebra_nhg.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 4f41406a5c..2be9238ee8 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1048,18 +1048,41 @@ int zebra_nhg_kernel_del(uint32_t id) } /* Some dependency helper functions */ -static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi) +static struct nhg_hash_entry *depends_find_recursive(const struct nexthop *nh, + afi_t afi) { - struct nexthop lookup; - struct nhg_hash_entry *nhe = NULL; + struct nhg_hash_entry *nhe; + struct nexthop *lookup = NULL; - if (!nh) - goto done; + /* + * We need to copy its resolved nexthop if its recursively + * resolved so that has to be handled with allocs/frees since + * it could resolve to a group of unknown size. + */ + copy_nexthops(&lookup, nh, NULL); + + /* Make it a single, recursive nexthop */ + nexthops_free(lookup->next); + nexthops_free(lookup->prev); + lookup->next = NULL; + lookup->prev = NULL; + + nhe = zebra_nhg_find_nexthop(0, lookup, afi, 0); + + nexthops_free(lookup); + + return nhe; +} + +static struct nhg_hash_entry *depends_find_singleton(const struct nexthop *nh, + afi_t afi) +{ + struct nhg_hash_entry *nhe; + struct nexthop lookup = {}; /* Capture a snapshot of this single nh; it might be part of a list, * so we need to make a standalone copy. */ - memset(&lookup, 0, sizeof(lookup)); nexthop_copy(&lookup, nh, NULL); nhe = zebra_nhg_find_nexthop(0, &lookup, afi, 0); @@ -1067,6 +1090,24 @@ static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi) /* The copy may have allocated labels; free them if necessary. */ nexthop_del_labels(&lookup); + return nhe; +} + +static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi) +{ + struct nhg_hash_entry *nhe = NULL; + + if (!nh) + goto done; + + /* We are separating these functions out to increase handling speed + * in the non-recursive case (by not alloc/freeing) + */ + if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE)) + nhe = depends_find_recursive(nh, afi); + else + nhe = depends_find_singleton(nh, afi); + done: return nhe; } |
