/* id counter to keep in sync with kernel */
uint32_t id_counter;
+/* */
+static bool g_nexthops_enabled = true;
+
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 interface *ifp = NULL;
ifp = if_lookup_by_index(nhe->nhg->nexthop->ifindex,
- nhe->vrf_id);
+ nhe->nhg->nexthop->vrf_id);
if (ifp)
zebra_nhg_set_if(nhe, ifp);
else
flog_err(
EC_ZEBRA_IF_LOOKUP_FAILED,
"Zebra failed to lookup an interface with ifindex=%d in vrf=%u for NHE id=%u",
- nhe->nhg->nexthop->ifindex, nhe->vrf_id,
- nhe->id);
+ nhe->nhg->nexthop->ifindex,
+ nhe->nhg->nexthop->vrf_id, nhe->id);
}
}
resolved_ng.nexthop = nh;
depend = zebra_nhg_rib_find(0, &resolved_ng, afi);
- depends_add(nhg_depends, depend);
+
+ if (depend)
+ depends_add(nhg_depends, depend);
}
static bool zebra_nhg_find(struct nhg_hash_entry **nhe, uint32_t id,
lookup.type = type ? type : ZEBRA_ROUTE_NHG;
lookup.nhg = nhg;
+ lookup.vrf_id = vrf_id;
if (lookup.nhg->nexthop->next) {
/* Groups can have all vrfs and AF's in them */
lookup.afi = AFI_UNSPEC;
- lookup.vrf_id = VRF_DEFAULT;
} else {
switch (lookup.nhg->nexthop->type) {
case (NEXTHOP_TYPE_IFINDEX):
lookup.afi = AFI_IP6;
break;
}
-
- lookup.vrf_id = vrf_id;
}
if (id)
{
struct nhg_hash_entry *nhe = NULL;
struct nexthop_group nhg = {};
+ vrf_id_t vrf_id = !vrf_is_backend_netns() ? VRF_DEFAULT : nh->vrf_id;
nexthop_group_add_sorted(&nhg, nh);
- zebra_nhg_find(&nhe, id, &nhg, NULL, nh->vrf_id, afi, type);
+ zebra_nhg_find(&nhe, id, &nhg, NULL, vrf_id, afi, type);
return nhe;
}
done:
XFREE(MTYPE_NHG_CTX, *ctx);
- *ctx = NULL;
}
static struct nhg_ctx *nhg_ctx_init(uint32_t id, struct nexthop *nh,
}
/* Kernel-side, received delete message */
-int zebra_nhg_kernel_del(uint32_t id)
+int zebra_nhg_kernel_del(uint32_t id, vrf_id_t vrf_id)
{
struct nhg_ctx *ctx = NULL;
- ctx = nhg_ctx_init(id, NULL, NULL, 0, 0, 0, 0);
+ ctx = nhg_ctx_init(id, NULL, NULL, vrf_id, 0, 0, 0);
nhg_ctx_set_op(ctx, NHG_CTX_OP_DEL);
zebra_nhg_rib_find(uint32_t id, struct nexthop_group *nhg, afi_t rt_afi)
{
struct nhg_hash_entry *nhe = NULL;
+ vrf_id_t vrf_id;
+
+ /*
+ * CLANG SA is complaining that nexthop may be NULL
+ * Make it happy but this is ridonc
+ */
+ assert(nhg->nexthop);
+ vrf_id = !vrf_is_backend_netns() ? VRF_DEFAULT : nhg->nexthop->vrf_id;
if (!(nhg && nhg->nexthop)) {
flog_err(EC_ZEBRA_TABLE_LOOKUP_FAILED,
return NULL;
}
- zebra_nhg_find(&nhe, id, nhg, NULL, nhg->nexthop->vrf_id, rt_afi, 0);
+ zebra_nhg_find(&nhe, id, nhg, NULL, vrf_id, rt_afi, 0);
return nhe;
}
* resolved by a route NH1. The exception is if the route is a
* host route.
*/
- if (top && rn == top)
+ if (rn == top)
if (((afi == AFI_IP) && (rn->p.prefixlen != 32))
|| ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) {
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
{
hash_iterate(hash, zebra_nhg_sweep_entry, NULL);
}
+
+/* Global control to disable use of kernel nexthops, if available. We can't
+ * force the kernel to support nexthop ids, of course, but we can disable
+ * zebra's use of them, for testing e.g. By default, if the kernel supports
+ * nexthop ids, zebra uses them.
+ */
+void zebra_nhg_enable_kernel_nexthops(bool set)
+{
+ g_nexthops_enabled = set;
+}
+
+bool zebra_nhg_kernel_nexthops_enabled(void)
+{
+ return g_nexthops_enabled;
+}