summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
authorStephen Worley <sworley@cumulusnetworks.com>2019-05-14 15:27:40 -0700
committerStephen Worley <sworley@cumulusnetworks.com>2019-10-25 11:13:40 -0400
commit98cda54a9543ea125e5e1eea6621c453f407edb2 (patch)
tree39d132983b105b883c40fe2d07a6c7a55b36eefe /zebra/zebra_rib.c
parent1c3d2890408e05f60b4864a93a1dff0c23ab346c (diff)
zebra: Add recursive functionality to NHE's
Add the ability to recursively resolve nexthop group hash entries and resolve them when sending to the kernel. When copying over nexthops into an NHE, copy resolved info as well. Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r--zebra/zebra_rib.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 6276ed3478..438923e232 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -2717,6 +2717,7 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id)
int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
struct prefix_ipv6 *src_p, struct route_entry *re)
{
+ struct nhg_hash_entry *nhe = NULL;
struct route_table *table;
struct route_node *rn;
struct route_entry *same = NULL;
@@ -2736,6 +2737,49 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
return 0;
}
+ if (re->nhe_id) {
+ nhe = zebra_nhg_lookup_id(re->nhe_id);
+
+ if (!nhe) {
+ flog_err(
+ EC_ZEBRA_TABLE_LOOKUP_FAILED,
+ "Zebra failed to find the nexthop hash entry for id=%u in a route entry",
+ re->nhe_id);
+ XFREE(MTYPE_RE, re);
+ return -1;
+ }
+ } else {
+ nhe = zebra_nhg_rib_find(0, re->ng, re->vrf_id, afi);
+
+ /*
+ * The nexthops got copied over into an nhe,
+ * so free them now.
+ */
+ nexthop_group_free_delete(&re->ng);
+
+ if (!nhe) {
+ char buf[PREFIX_STRLEN] = "";
+ char buf2[PREFIX_STRLEN] = "";
+
+ flog_err(
+ EC_ZEBRA_TABLE_LOOKUP_FAILED,
+ "Zebra failed to find or create a nexthop hash entry for %s%s%s",
+ prefix2str(p, buf, sizeof(buf)),
+ src_p ? " from " : "",
+ src_p ? prefix2str(src_p, buf2, sizeof(buf2))
+ : "");
+
+ XFREE(MTYPE_RE, re);
+ return -1;
+ }
+
+ re->nhe_id = nhe->id;
+ }
+
+ /* Attach the re to the nhe's nexthop group */
+ zebra_nhg_increment_ref(nhe);
+ re->ng = nhe->nhg;
+
/* Make it sure prefixlen is applied to the prefix. */
apply_mask(p);
if (src_p)