summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_nhg.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bgpd/bgp_nhg.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/bgpd/bgp_nhg.c b/bgpd/bgp_nhg.c
new file mode 100644
index 0000000..bf0ba77
--- /dev/null
+++ b/bgpd/bgp_nhg.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* BGP Nexthop Group Support
+ * Copyright (C) 2023 NVIDIA Corporation
+ * Copyright (C) 2023 6WIND
+ */
+
+#include <zebra.h>
+
+#include <bgpd/bgpd.h>
+#include <bgpd/bgp_debug.h>
+#include <bgpd/bgp_nhg.h>
+
+
+/****************************************************************************
+ * L3 NHGs are used for fast failover of nexthops in the dplane. These are
+ * the APIs for allocating L3 NHG ids. Management of the L3 NHG itself is
+ * left to the application using it.
+ * PS: Currently EVPN host routes is the only app using L3 NHG for fast
+ * failover of remote ES links.
+ ***************************************************************************/
+static bitfield_t bgp_nh_id_bitmap;
+static uint32_t bgp_nhg_start;
+
+/* XXX - currently we do nothing on the callbacks */
+static void bgp_nhg_add_cb(const char *name)
+{
+}
+
+static void bgp_nhg_modify_cb(const struct nexthop_group_cmd *nhgc)
+{
+}
+
+static void bgp_nhg_add_nexthop_cb(const struct nexthop_group_cmd *nhgc,
+ const struct nexthop *nhop)
+{
+}
+
+static void bgp_nhg_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
+ const struct nexthop *nhop)
+{
+}
+
+static void bgp_nhg_del_cb(const char *name)
+{
+}
+
+static void bgp_nhg_zebra_init(void)
+{
+ static bool bgp_nhg_zebra_inited;
+
+ if (bgp_nhg_zebra_inited)
+ return;
+
+ bgp_nhg_zebra_inited = true;
+ bgp_nhg_start = zclient_get_nhg_start(ZEBRA_ROUTE_BGP);
+ nexthop_group_init(bgp_nhg_add_cb, bgp_nhg_modify_cb,
+ bgp_nhg_add_nexthop_cb, bgp_nhg_del_nexthop_cb,
+ bgp_nhg_del_cb);
+}
+
+void bgp_nhg_init(void)
+{
+ uint32_t id_max;
+
+ id_max = MIN(ZEBRA_NHG_PROTO_SPACING - 1, 16 * 1024);
+ bf_init(bgp_nh_id_bitmap, id_max);
+ bf_assign_zero_index(bgp_nh_id_bitmap);
+
+ if (BGP_DEBUG(nht, NHT) || BGP_DEBUG(evpn_mh, EVPN_MH_ES))
+ zlog_debug("bgp nhg range %u - %u", bgp_nhg_start + 1,
+ bgp_nhg_start + id_max);
+}
+
+void bgp_nhg_finish(void)
+{
+ bf_free(bgp_nh_id_bitmap);
+}
+
+uint32_t bgp_nhg_id_alloc(void)
+{
+ uint32_t nhg_id = 0;
+
+ bgp_nhg_zebra_init();
+ bf_assign_index(bgp_nh_id_bitmap, nhg_id);
+ if (nhg_id)
+ nhg_id += bgp_nhg_start;
+
+ return nhg_id;
+}
+
+void bgp_nhg_id_free(uint32_t nhg_id)
+{
+ if (!nhg_id || (nhg_id <= bgp_nhg_start))
+ return;
+
+ nhg_id -= bgp_nhg_start;
+
+ bf_release_index(bgp_nh_id_bitmap, nhg_id);
+}