diff --git a/lib/if.c b/lib/if.c index b3803141df..e37b4f55b0 100644 --- a/lib/if.c +++ b/lib/if.c @@ -266,20 +266,23 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id) char oldpath[XPATH_MAXLEN]; char newpath[XPATH_MAXLEN]; - if_dnode = yang_dnode_getf( - running_config->dnode, - "/frr-interface:lib/interface[name='%s'][vrf='%s']/vrf", - ifp->name, old_vrf->name); + snprintf(oldpath, sizeof(oldpath), + "/frr-interface:lib/interface[name='%s'][vrf='%s']", + ifp->name, old_vrf->name); + snprintf(newpath, sizeof(newpath), + "/frr-interface:lib/interface[name='%s'][vrf='%s']", + ifp->name, vrf->name); + + if_dnode = yang_dnode_getf(running_config->dnode, "%s/vrf", + oldpath); if (if_dnode) { - yang_dnode_get_path(lyd_parent(if_dnode), oldpath, - sizeof(oldpath)); yang_dnode_change_leaf(if_dnode, vrf->name); - yang_dnode_get_path(lyd_parent(if_dnode), newpath, - sizeof(newpath)); nb_running_move_tree(oldpath, newpath); running_config->version++; } + + vty_update_xpath(oldpath, newpath); } } diff --git a/lib/vty.c b/lib/vty.c index 6853fc3301..50d116c564 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -82,6 +82,9 @@ extern struct host host; /* Vector which store each vty structure. */ static vector vtyvec; +/* Vector for vtysh connections. */ +static vector vtyshvec; + /* Vty timeout value. */ static unsigned long vty_timeout_val = VTY_TIMEOUT_DEFAULT; @@ -2038,6 +2041,7 @@ static int vtysh_accept(struct thread *thread) vty->wfd = sock; vty->type = VTY_SHELL_SERV; vty->node = VIEW_NODE; + vector_set_index(vtyshvec, sock, vty); vty_event(VTYSH_READ, vty); @@ -2211,8 +2215,12 @@ void vty_close(struct vty *vty) } /* Unset vector. */ - if (vty->fd != -1) - vector_unset(vtyvec, vty->fd); + if (vty->fd != -1) { + if (vty->type == VTY_SHELL_SERV) + vector_unset(vtyshvec, vty->fd); + else + vector_unset(vtyvec, vty->fd); + } if (vty->wfd > 0 && vty->type == VTY_FILE) fsync(vty->wfd); @@ -2571,6 +2579,41 @@ void vty_log_fixed(char *buf, size_t len) } } +static void update_xpath(struct vty *vty, const char *oldpath, + const char *newpath) +{ + int i; + + for (i = 0; i < vty->xpath_index; i++) { + if (!frrstr_startswith(vty->xpath[i], oldpath)) + break; + + char *tmp = frrstr_replace(vty->xpath[i], oldpath, newpath); + strlcpy(vty->xpath[i], tmp, sizeof(vty->xpath[0])); + XFREE(MTYPE_TMP, tmp); + } +} + +void vty_update_xpath(const char *oldpath, const char *newpath) +{ + struct vty *vty; + unsigned int i; + + for (i = 0; i < vector_active(vtyshvec); i++) { + if ((vty = vector_slot(vtyshvec, i)) == NULL) + continue; + + update_xpath(vty, oldpath, newpath); + } + + for (i = 0; i < vector_active(vtyvec); i++) { + if ((vty = vector_slot(vtyvec, i)) == NULL) + continue; + + update_xpath(vty, oldpath, newpath); + } +} + int vty_config_enter(struct vty *vty, bool private_config, bool exclusive) { if (exclusive && nb_running_lock(NB_CLIENT_CLI, vty)) { @@ -3114,6 +3157,7 @@ void vty_init(struct thread_master *master_thread, bool do_command_logging) vty_save_cwd(); vtyvec = vector_init(VECTOR_MIN_SIZE); + vtyshvec = vector_init(VECTOR_MIN_SIZE); vty_master = master_thread; @@ -3165,4 +3209,8 @@ void vty_terminate(void) vtyvec = NULL; Vvty_serv_thread = NULL; } + if (vtyshvec) { + vector_free(vtyshvec); + vtyshvec = NULL; + } } diff --git a/lib/vty.h b/lib/vty.h index 10fbb16a47..70ec4fcd84 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -327,6 +327,7 @@ extern void vty_close(struct vty *); extern char *vty_get_cwd(void); extern void vty_log(const char *level, const char *proto, const char *msg, struct timestamp_control *); +extern void vty_update_xpath(const char *oldpath, const char *newpath); extern int vty_config_enter(struct vty *vty, bool private_config, bool exclusive); extern void vty_config_exit(struct vty *);