/* id counter to keep in sync with kernel */
uint32_t id_counter;
-static struct nhg_hash_entry *depends_find(struct nexthop *nh, afi_t afi);
+static struct nhg_hash_entry *depends_find(const struct nexthop *nh,
+ afi_t afi);
static void depends_add(struct nhg_connected_tree_head *head,
struct nhg_hash_entry *depend);
static struct nhg_hash_entry *
nexthop_group_add_sorted(&nhg, nh);
- zebra_nhg_find(&nhe, id, &nhg, NULL, nh->vrf_id, afi, 0);
+ zebra_nhg_find(&nhe, id, &nhg, NULL, nh->vrf_id, afi, type);
return nhe;
}
}
/* Some dependency helper functions */
-static struct nhg_hash_entry *depends_find(struct nexthop *nh, afi_t afi)
+static struct nhg_hash_entry *depends_find_recursive(const struct nexthop *nh,
+ afi_t afi)
{
+ struct nhg_hash_entry *nhe;
struct nexthop *lookup = NULL;
- struct nhg_hash_entry *nhe = 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);
- /* Clear it, in case its a group */
+ /* Make it a single, recursive nexthop */
nexthops_free(lookup->next);
nexthops_free(lookup->prev);
lookup->next = NULL;
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.
+ */
+ nexthop_copy(&lookup, nh, NULL);
+
+ nhe = zebra_nhg_find_nexthop(0, &lookup, afi, 0);
+
+ /* 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;
}