summaryrefslogtreecommitdiffstats
path: root/vtysh
diff options
context:
space:
mode:
authorIgor Ryzhov <iryzhov@nfware.com>2021-08-08 21:38:50 +0200
committerIgor Ryzhov <iryzhov@nfware.com>2021-08-23 21:08:20 +0200
commit07679ad98ab97a4b783f7ae54f88d4d70a5729de (patch)
treee2a670c3a68fb5b856cd52426c2f0b972a414bcb /vtysh
parentpathd: rework config printing code (diff)
downloadfrr-07679ad98ab97a4b783f7ae54f88d4d70a5729de.tar.xz
frr-07679ad98ab97a4b783f7ae54f88d4d70a5729de.zip
*: explicitly print "exit" at the end of every node config
There is a possibility that the same line can be matched as a command in some node and its parent node. In this case, when reading the config, this line is always executed as a command of the child node. For example, with the following config: ``` router ospf network 193.168.0.0/16 area 0 ! mpls ldp discovery hello interval 111 ! ``` Line `mpls ldp` is processed as command `mpls ldp-sync` inside the `router ospf` node. This leads to a complete loss of `mpls ldp` node configuration. To eliminate this issue and all possible similar issues, let's print an explicit "exit" at the end of every node config. This commit also changes indentation for a couple of existing exit commands so that all existing commands are on the same level as their corresponding node-entering commands. Fixes #9206. Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Diffstat (limited to 'vtysh')
-rw-r--r--vtysh/vtysh_config.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index d22ec3113..2e1d7c5ba 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -272,16 +272,11 @@ void vtysh_config_parse_line(void *arg, const char *line)
strlen(" ip igmp query-interval")) == 0) {
config_add_line_uniq_end(config->line, line);
} else if (config->index == LINK_PARAMS_NODE
- && strncmp(line, " exit-link-params",
- strlen(" exit"))
+ && strncmp(line, " exit-link-params",
+ strlen(" exit"))
== 0) {
config_add_line(config->line, line);
config->index = INTERFACE_NODE;
- } else if (config->index == VRF_NODE
- && strncmp(line, " exit-vrf",
- strlen(" exit-vrf"))
- == 0) {
- config_add_line_uniq_end(config->line, line);
} else if (!strncmp(line, " vrrp", strlen(" vrrp"))
|| !strncmp(line, " no vrrp",
strlen(" no vrrp"))) {
@@ -300,7 +295,10 @@ void vtysh_config_parse_line(void *arg, const char *line)
config_add_line(config_top, line);
break;
default:
- if (strncmp(line, "interface", strlen("interface")) == 0)
+ if (strncmp(line, "exit", strlen("exit")) == 0) {
+ if (config)
+ config_add_line_uniq_end(config->line, line);
+ } else if (strncmp(line, "interface", strlen("interface")) == 0)
config = config_get(INTERFACE_NODE, line);
else if (strncmp(line, "pseudowire", strlen("pseudowire")) == 0)
config = config_get(PW_NODE, line);
@@ -496,7 +494,9 @@ void vtysh_config_dump(void)
* are not under the VRF node.
*/
if (config->index == INTERFACE_NODE
- && list_isempty(config->line)) {
+ && (listcount(config->line) == 1)
+ && (line = listnode_head(config->line))
+ && strmatch(line, "exit")) {
config_del(config);
continue;
}