]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: move all userdata when changing node xpath
authorQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 4 Jun 2020 23:26:42 +0000 (19:26 -0400)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Fri, 5 Jun 2020 00:24:52 +0000 (20:24 -0400)
All userdata pointers need to be rekeyed to their new xpaths, not just
the one associated with the dnode being moved.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
lib/if.c
lib/northbound.c
lib/northbound.h

index 9efd298a4f2a65588f3fb602d3952e955a5a18a6..b34744f80dc1f70d946bca62176ac691245eb3d8 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -263,15 +263,21 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
         */
        if (yang_module_find("frr-interface")) {
                struct lyd_node *if_dnode;
+               char oldpath[XPATH_MAXLEN];
+               char newpath[XPATH_MAXLEN];
 
                if_dnode = yang_dnode_get(
                        running_config->dnode,
                        "/frr-interface:lib/interface[name='%s'][vrf='%s']/vrf",
                        ifp->name, old_vrf->name);
+
                if (if_dnode) {
-                       nb_running_unset_entry(if_dnode->parent);
+                       yang_dnode_get_path(if_dnode->parent, oldpath,
+                                           sizeof(oldpath));
                        yang_dnode_change_leaf(if_dnode, vrf->name);
-                       nb_running_set_entry(if_dnode->parent, ifp);
+                       yang_dnode_get_path(if_dnode->parent, newpath,
+                                           sizeof(newpath));
+                       nb_running_move_tree(oldpath, newpath);
                        running_config->version++;
                }
        }
index 18bd4f5fd872d563122564cf02b8b84536ebfc16..e393c3392844c4ce13d502093b0572a27b659c77 100644 (file)
@@ -30,6 +30,7 @@
 #include "northbound.h"
 #include "northbound_cli.h"
 #include "northbound_db.h"
+#include "frrstr.h"
 
 DEFINE_MTYPE_STATIC(LIB, NB_NODE, "Northbound Node")
 DEFINE_MTYPE_STATIC(LIB, NB_CONFIG, "Northbound Configuration")
@@ -1789,6 +1790,29 @@ void nb_running_set_entry(const struct lyd_node *dnode, void *entry)
        config->entry = entry;
 }
 
+void nb_running_move_tree(const char *xpath_from, const char *xpath_to)
+{
+       struct nb_config_entry *entry;
+       struct list *entries = hash_to_list(running_config_entries);
+       struct listnode *ln;
+
+       for (ALL_LIST_ELEMENTS_RO(entries, ln, entry)) {
+               if (!frrstr_startswith(entry->xpath, xpath_from))
+                       continue;
+
+               hash_release(running_config_entries, entry);
+
+               char *newpath =
+                       frrstr_replace(entry->xpath, xpath_from, xpath_to);
+               strlcpy(entry->xpath, newpath, sizeof(entry->xpath));
+               XFREE(MTYPE_TMP, newpath);
+
+               hash_get(running_config_entries, entry, hash_alloc_intern);
+       }
+
+       list_delete(&entries);
+}
+
 static void *nb_running_unset_entry_helper(const struct lyd_node *dnode)
 {
        struct nb_config_entry *config, s;
index 84382eeb60e707518fc7b3f1444b9f720c2e6fd1..2a1beeabaa35acff6c1b4f457df281dbea032ce3 100644 (file)
@@ -992,6 +992,23 @@ extern int nb_notification_send(const char *xpath, struct list *arguments);
  */
 extern void nb_running_set_entry(const struct lyd_node *dnode, void *entry);
 
+/*
+ * Move an entire tree of user pointer nodes.
+ *
+ * Suppose we have xpath A/B/C/D, with user pointers associated to C and D. We
+ * need to move B to be under Z, so the new xpath is Z/B/C/D. Because user
+ * pointers are indexed with their absolute path, We need to move all user
+ * pointers at and below B to their new absolute paths; this function does
+ * that.
+ *
+ * xpath_from
+ *    base xpath of tree to move (A/B)
+ *
+ * xpath_to
+ *    base xpath of new location of tree (Z/B)
+ */
+extern void nb_running_move_tree(const char *xpath_from, const char *xpath_to);
+
 /*
  * Unset the user pointer associated to a configuration node.
  *