summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
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)