diff options
Diffstat (limited to 'bgpd/bgp_nhg.c')
-rw-r--r-- | bgpd/bgp_nhg.c | 99 |
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); +} |