From 144a546e611b38bc347c136c432cea19fb8bb208 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Sat, 24 Jun 2023 12:35:47 -0400 Subject: [PATCH] mgmtd: convert map to darr use allowing dynamic registrations - move from the static allocated and initialize xpath map to using the new darr (dynamic array) code. Signed-off-by: Christian Hopps (cherry picked from commit 5447d16b7389703e6a8e0af7e9faaf153b2c4ad2) --- mgmtd/mgmt_be_adapter.c | 154 ++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 99 deletions(-) diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c index 5e9d5a1104..399fdafded 100644 --- a/mgmtd/mgmt_be_adapter.c +++ b/mgmtd/mgmt_be_adapter.c @@ -8,6 +8,7 @@ */ #include +#include "darr.h" #include "frrevent.h" #include "sockopt.h" #include "network.h" @@ -28,23 +29,9 @@ frr_each_safe (mgmt_be_adapters, &mgmt_be_adapters, (adapter)) /* - * Static mapping of YANG XPath regular expressions and - * the corresponding interested backend clients. - * NOTE: Thiis is a static mapping defined by all MGMTD - * backend client modules (for now, till we develop a - * more dynamic way of creating and updating this map). - * A running map is created by MGMTD in run-time to - * handle real-time mapping of YANG xpaths to one or - * more interested backend client adapters. - * - * Please see xpath_map_reg[] in lib/mgmt_be_client.c - * for the actual map + * Mapping of YANG XPath regular expressions to + * their corresponding backend clients. */ -struct mgmt_be_xpath_map_init { - const char *xpath_regexp; - uint subscr_info[MGMTD_BE_CLIENT_ID_MAX]; -}; - struct mgmt_be_xpath_map { char *xpath_regexp; uint subscr_info[MGMTD_BE_CLIENT_ID_MAX]; @@ -66,55 +53,6 @@ struct mgmt_be_get_adapter_config_params { uint32_t seq; }; -/* - * Static mapping of YANG XPath regular expressions and - * the corresponding interested backend clients. - * NOTE: Thiis is a static mapping defined by all MGMTD - * backend client modules (for now, till we develop a - * more dynamic way of creating and updating this map). - * A running map is created by MGMTD in run-time to - * handle real-time mapping of YANG xpaths to one or - * more interested backend client adapters. - */ -static const struct mgmt_be_xpath_map_init mgmt_xpath_map_init[] = { - { - .xpath_regexp = "/frr-vrf:lib/*", - .subscr_info = - { -#if HAVE_STATICD - [MGMTD_BE_CLIENT_ID_STATICD] = - MGMT_SUBSCR_VALIDATE_CFG | - MGMT_SUBSCR_NOTIFY_CFG, -#endif - }, - }, - { - .xpath_regexp = "/frr-interface:lib/*", - .subscr_info = - { -#if HAVE_STATICD - [MGMTD_BE_CLIENT_ID_STATICD] = - MGMT_SUBSCR_VALIDATE_CFG | - MGMT_SUBSCR_NOTIFY_CFG, -#endif - }, - }, - - { - .xpath_regexp = - "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/*", - .subscr_info = - { -#if HAVE_STATICD - [MGMTD_BE_CLIENT_ID_STATICD] = - MGMT_SUBSCR_VALIDATE_CFG | - MGMT_SUBSCR_NOTIFY_CFG, -#endif - }, - }, -}; - - /* * Each client gets their own map, but also union all the strings into the * above map as well. @@ -145,12 +83,15 @@ static struct mgmt_be_client_xpath_map #endif }; -#define MGMTD_BE_MAX_NUM_XPATH_MAP 256 - -/* We would like to have a better ADT than one with O(n) - comparisons */ +/* + * We would like to have a better ADT than one with O(n) comparisons + * + * Perhaps it's possible to sort this array in a way that allows binary search + * to find the start, then walk until no possible match can follow? Intuition + * says this probably involves exact match/no-match on a stem in the map array + * or something like that. + */ static struct mgmt_be_xpath_map *mgmt_xpath_map; -static uint mgmt_num_xpath_maps; static struct event_loop *mgmt_loop; static struct msg_server mgmt_be_server = {.fd = -1}; @@ -193,34 +134,52 @@ mgmt_be_find_adapter_by_name(const char *name) return NULL; } +static void mgmt_register_client_xpath(enum mgmt_be_client_id id, + const char *xpath, uint subscribed) +{ + struct mgmt_be_xpath_map *map; + + darr_foreach_p (mgmt_xpath_map, map) + if (!strcmp(xpath, map->xpath_regexp)) { + map->subscr_info[id] = subscribed; + return; + } + /* we didn't find a matching entry */ + map = darr_append(mgmt_xpath_map); + map->xpath_regexp = XSTRDUP(MTYPE_MGMTD_XPATH, xpath); + map->subscr_info[id] = subscribed; +} + +/* + * Load the initial mapping from static init map + */ static void mgmt_be_xpath_map_init(void) { - uint i; + struct mgmt_be_client_xpath *init, *end; + enum mgmt_be_client_id id; MGMTD_BE_ADAPTER_DBG("Init XPath Maps"); - mgmt_num_xpath_maps = array_size(mgmt_xpath_map_init); - mgmt_xpath_map = - calloc(1, sizeof(*mgmt_xpath_map) * mgmt_num_xpath_maps); - for (i = 0; i < mgmt_num_xpath_maps; i++) { - MGMTD_BE_ADAPTER_DBG(" - XPATH: '%s'", - mgmt_xpath_map_init[i].xpath_regexp); - mgmt_xpath_map[i].xpath_regexp = XSTRDUP( - MTYPE_MGMTD_XPATH, mgmt_xpath_map_init[i].xpath_regexp); - memcpy(mgmt_xpath_map[i].subscr_info, - mgmt_xpath_map_init[i].subscr_info, - sizeof(mgmt_xpath_map_init[i].subscr_info)); + FOREACH_MGMTD_BE_CLIENT_ID (id) { + init = mgmt_client_xpaths[id].xpaths; + end = init + mgmt_client_xpaths[id].nxpaths; + for (; init < end; init++) { + MGMTD_BE_ADAPTER_DBG(" - XPATH: '%s'", init->xpath); + mgmt_register_client_xpath(id, init->xpath, + init->subscribed); + } } - MGMTD_BE_ADAPTER_DBG("Total XPath Maps: %u", mgmt_num_xpath_maps); + + MGMTD_BE_ADAPTER_DBG("Total XPath Maps: %u", darr_len(mgmt_xpath_map)); } static void mgmt_be_xpath_map_cleanup(void) { - uint i; + struct mgmt_be_xpath_map *map; - for (i = 0; i < mgmt_num_xpath_maps; i++) - XFREE(MTYPE_MGMTD_XPATH, mgmt_xpath_map[i].xpath_regexp); - free(mgmt_xpath_map); + darr_foreach_p (mgmt_xpath_map, map) + XFREE(MTYPE_MGMTD_XPATH, map->xpath_regexp); + darr_free(mgmt_xpath_map); } static int mgmt_be_eval_regexp_match(const char *xpath_regexp, @@ -830,19 +789,17 @@ int mgmt_be_get_adapter_config(struct mgmt_be_client_adapter *adapter, void mgmt_be_get_subscr_info_for_xpath( const char *xpath, struct mgmt_be_client_subscr_info *subscr_info) { + struct mgmt_be_xpath_map *map; enum mgmt_be_client_id id; - uint i; memset(subscr_info, 0, sizeof(*subscr_info)); MGMTD_BE_ADAPTER_DBG("XPATH: '%s'", xpath); - for (i = 0; i < mgmt_num_xpath_maps; i++) { - if (!mgmt_be_eval_regexp_match(mgmt_xpath_map[i].xpath_regexp, - xpath)) + darr_foreach_p (mgmt_xpath_map, map) { + if (!mgmt_be_eval_regexp_match(map->xpath_regexp, xpath)) continue; FOREACH_MGMTD_BE_CLIENT_ID (id) { - subscr_info->xpath_subscr[id] |= - mgmt_xpath_map[i].subscr_info[id]; + subscr_info->xpath_subscr[id] |= map->subscr_info[id]; } } @@ -923,18 +880,17 @@ void mgmt_be_adapter_status_write(struct vty *vty) void mgmt_be_xpath_register_write(struct vty *vty) { - uint indx; + struct mgmt_be_xpath_map *map; enum mgmt_be_client_id id; struct mgmt_be_client_adapter *adapter; uint info; vty_out(vty, "MGMTD Backend XPath Registry\n"); - for (indx = 0; indx < mgmt_num_xpath_maps; indx++) { - vty_out(vty, " - XPATH: '%s'\n", - mgmt_xpath_map[indx].xpath_regexp); + darr_foreach_p (mgmt_xpath_map, map) { + vty_out(vty, " - XPATH: '%s'\n", map->xpath_regexp); FOREACH_MGMTD_BE_CLIENT_ID (id) { - info = mgmt_xpath_map[indx].subscr_info[id]; + info = map->subscr_info[id]; if (!info) continue; vty_out(vty, @@ -949,7 +905,7 @@ void mgmt_be_xpath_register_write(struct vty *vty) } } - vty_out(vty, "Total XPath Registries: %u\n", mgmt_num_xpath_maps); + vty_out(vty, "Total XPath Registries: %u\n", darr_len(mgmt_xpath_map)); } void mgmt_be_xpath_subscr_info_write(struct vty *vty, const char *xpath) -- 2.39.5