]> git.puffer.fish Git - matthieu/frr.git/commitdiff
mgmtd: convert map to darr use allowing dynamic registrations
authorChristian Hopps <chopps@labn.net>
Sat, 24 Jun 2023 16:35:47 +0000 (12:35 -0400)
committerChristian Hopps <chopps@labn.net>
Sat, 15 Jul 2023 21:57:39 +0000 (17:57 -0400)
- move from the static allocated and initialize xpath map to using the
new darr (dynamic array) code.

Signed-off-by: Christian Hopps <chopps@labn.net>
(cherry picked from commit 5447d16b7389703e6a8e0af7e9faaf153b2c4ad2)

mgmtd/mgmt_be_adapter.c

index 5e9d5a1104fcf1e385894265036e1b8185c40a08..399fdafded1a6b2f80309c59641b7c1aa3484736 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <zebra.h>
+#include "darr.h"
 #include "frrevent.h"
 #include "sockopt.h"
 #include "network.h"
        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)