diff --git a/lib/if.c b/lib/if.c index 9efd298a4f..b34744f80d 100644 --- 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++; } } diff --git a/lib/northbound.c b/lib/northbound.c index 18bd4f5fd8..e393c33928 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -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; diff --git a/lib/northbound.h b/lib/northbound.h index 84382eeb60..2a1beeabaa 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -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. *