Add a command/functionality to only install proto-based nexthops.
That is nexthops owned/created by upper level protocols, not ones
implicitly created by zebra.
There are some scenarios where you would not want zebra to be
arbitrarily installing nexthop groups and but you still want
to use ones you have control over via lib/nexthop_group config
and an upper level protocol.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
return ZEBRA_NHG_SPACING * proto;
}
+
+/*
+ * Where do routing protocols IDs start overall (first ID after zebra)
+ */
+uint32_t zclient_get_nhg_lower_bound()
+{
+ return ZEBRA_NHG_SPACING * (ZEBRA_ROUTE_CONNECT + 1);
+}
*/
#define ZEBRA_NHG_SPACING 50000000
extern uint32_t zclient_get_nhg_start(uint32_t proto);
+extern uint32_t zclient_get_nhg_lower_bound(void);
extern struct zclient *zclient_new(struct thread_master *m,
struct zclient_options *opt);
&& zebra_nhg_kernel_nexthops_enabled());
}
+/*
+ * Some people may only want to use NHGs created by protos and not
+ * implicitly created by Zebra. This check accounts for that.
+ */
+static bool proto_nexthops_only(void)
+{
+ return zebra_nhg_proto_nexthops_only();
+}
+
+/* Is this a proto created NHG? */
+static bool is_proto_nhg(uint32_t id, int type)
+{
+ /* If type is available, use it as the source of truth */
+ if (type) {
+ if (type != ZEBRA_ROUTE_NHG)
+ return true;
+ return false;
+ }
+
+ if (id >= zclient_get_nhg_lower_bound())
+ return true;
+
+ return false;
+}
+
/*
* The ipv4_ll data structure is used for all 5549
* additions to the kernel. Let's figure out the
nl_attr_nest_end(&req->n, nest);
}
- if ((!fpm && kernel_nexthops_supported()) || (fpm && force_nhg)) {
+ if ((!fpm && kernel_nexthops_supported()
+ && (!proto_nexthops_only()
+ || is_proto_nhg(dplane_ctx_get_nhe_id(ctx), 0)))
+ || (fpm && force_nhg)) {
/* Kernel supports nexthop objects */
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("%s: %pFX nhg_id is %u", __func__, p,
char label_buf[256];
int num_labels = 0;
+ /*
+ * Nothing to do if the kernel doesn't support nexthop objects or
+ * we dont want to install this type of NHG
+ */
+ if (!kernel_nexthops_supported()
+ || (proto_nexthops_only()
+ && !is_proto_nhg(dplane_ctx_get_nhe_id(ctx),
+ dplane_ctx_get_nhe_type(ctx))))
+ return 0;
+
label_buf[0] = '\0';
if (buflen < sizeof(*req))
/* */
static bool g_nexthops_enabled = true;
+static bool proto_nexthops_only = false;
static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi,
int type);
return g_nexthops_enabled;
}
+/*
+ * Global control to only use kernel nexthops for protocol created NHGs.
+ * There are some use cases where you may not want zebra to implicitly
+ * create kernel nexthops for all routes and only create them for NHGs
+ * passed down by upper level protos.
+ *
+ * Default is off.
+ */
+void zebra_nhg_set_proto_nexthops_only(bool set)
+{
+ proto_nexthops_only = set;
+}
+
+bool zebra_nhg_proto_nexthops_only(void)
+{
+ return proto_nexthops_only;
+}
+
/* Add NHE from upper level proto */
struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
struct nexthop_group *nhg, afi_t afi)
void zebra_nhg_enable_kernel_nexthops(bool set);
bool zebra_nhg_kernel_nexthops_enabled(void);
+/* Global control for zebra to only use proto-owned nexthops */
+void zebra_nhg_set_proto_nexthops_only(bool set);
+bool zebra_nhg_proto_nexthops_only(void);
+
/**
* NHE abstracted tree functions.
* Use these where possible instead of direct access.
return CMD_SUCCESS;
}
+DEFPY_HIDDEN (proto_nexthop_group_only,
+ proto_nexthop_group_only_cmd,
+ "[no] zebra nexthop proto only",
+ NO_STR
+ ZEBRA_STR
+ "Nexthop configuration\n"
+ "Configure exclusive use of proto nexthops\n"
+ "Only use proto nexthops\n")
+{
+ zebra_nhg_set_proto_nexthops_only(!no);
+ return CMD_SUCCESS;
+}
+
DEFUN (no_ip_nht_default_route,
no_ip_nht_default_route_cmd,
"no ip nht resolve-via-default",
if (!zebra_nhg_kernel_nexthops_enabled())
vty_out(vty, "no zebra nexthop kernel enable\n");
+ if (zebra_nhg_proto_nexthops_only())
+ vty_out(vty, "zebra nexthop proto only\n");
+
#ifdef HAVE_NETLINK
/* Include netlink info */
netlink_config_write_helper(vty);
install_element(CONFIG_NODE, &zebra_packet_process_cmd);
install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
install_element(CONFIG_NODE, &nexthop_group_use_enable_cmd);
+ install_element(CONFIG_NODE, &proto_nexthop_group_only_cmd);
install_element(VIEW_NODE, &show_nexthop_group_cmd);
install_element(VIEW_NODE, &show_interface_nexthop_group_cmd);