diff options
author | Igor Ryzhov <iryzhov@nfware.com> | 2021-06-16 13:07:30 +0200 |
---|---|---|
committer | Igor Ryzhov <iryzhov@nfware.com> | 2021-06-18 02:27:46 +0200 |
commit | 763725cd5e431cb4f4ec385e35b312cc7807163a (patch) | |
tree | 30a3627d078d50fba5a32a96556f504b061a18d0 /lib/vty.c | |
parent | Merge pull request #8874 from idryzhov/ospf-routemap-fix (diff) | |
download | frr-763725cd5e431cb4f4ec385e35b312cc7807163a.tar.xz frr-763725cd5e431cb4f4ec385e35b312cc7807163a.zip |
lib: fix interface configuration after vrf change
This commit fixes the following problem:
- enter the interface node
- move the interface to another VRF
- try to continue configuring the interface
It is not possible to continue configuration because the XPath stored in
the vty doesn't correspond with the actual state of the system anymore.
For example:
```
nfware# conf
nfware(config)# interface enp2s0
<-- move the enp2s0 to a different VRF -->
nfware(config-if)# ip router isis 1
% Failed to get iface dnode in candidate DB
```
To fix the issue, go through all connected vty shells and update the
stored XPath.
Suggested-by: Renato Westphal <renato@opensourcerouting.org>
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Diffstat (limited to 'lib/vty.c')
-rw-r--r-- | lib/vty.c | 52 |
1 files changed, 50 insertions, 2 deletions
@@ -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; + } } |