diff options
author | Igor Ryzhov <iryzhov@nfware.com> | 2021-08-14 01:09:54 +0200 |
---|---|---|
committer | Igor Ryzhov <iryzhov@nfware.com> | 2021-12-03 16:52:42 +0100 |
commit | 4b639f996759eef388c42ca657a520de693ac6fc (patch) | |
tree | 18ba29ae89109a9ebd58eb8df180d520620d0ba9 /vtysh/vtysh_config.c | |
parent | Merge pull request #9703 from donaldsharp/splitup_bgp_gr (diff) | |
download | frr-4b639f996759eef388c42ca657a520de693ac6fc.tar.xz frr-4b639f996759eef388c42ca657a520de693ac6fc.zip |
vtysh: fix duplicated output of key chain configuration
When both ripd and eigrpd run at the same time, all key configuration in
key chain node is duplicated. This change adds a concept of nested nodes
into vtysh to fix the issue.
Before:
```
key chain test
key 1
key-string 1
exit
key 1
key-string 1
exit
exit
!
```
After:
```
key chain test
key 1
key-string 1
exit
exit
!
```
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Diffstat (limited to 'vtysh/vtysh_config.c')
-rw-r--r-- | vtysh/vtysh_config.c | 109 |
1 files changed, 80 insertions, 29 deletions
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 936cb7062..3bd5489ee 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -44,8 +44,12 @@ struct config { /* Configuration string line. */ struct list *line; - /* Configuration can be nest. */ - struct config *config; + /* Configuration can be nested. */ + struct config *parent; + vector nested; + + /* Exit command. */ + char *exit; /* Index of this config. */ uint32_t index; @@ -76,7 +80,10 @@ static struct config *config_new(void) static void config_del(struct config *config) { + vector_free(config->nested); list_delete(&config->line); + if (config->exit) + XFREE(MTYPE_VTYSH_CONFIG_LINE, config->exit); XFREE(MTYPE_VTYSH_CONFIG_LINE, config->name); XFREE(MTYPE_VTYSH_CONFIG, config); } @@ -104,7 +111,7 @@ struct configuration { struct config_master_hash_head hash_master; }; -static struct config *config_get(int index, const char *line) +static struct config *config_get_vec(vector vec, int index, const char *line) { struct config *config, *config_loop; struct configuration *configuration; @@ -112,14 +119,14 @@ static struct config *config_get(int index, const char *line) config = config_loop = NULL; - configuration = vector_lookup_ensure(configvec, index); + configuration = vector_lookup_ensure(vec, index); if (!configuration) { configuration = XMALLOC(MTYPE_VTYSH_CONFIG, sizeof(struct configuration)); config_master_init(&configuration->master); config_master_hash_init(&configuration->hash_master); - vector_set_index(configvec, index, configuration); + vector_set_index(vec, index, configuration); } lookup.name = (char *)line; @@ -131,13 +138,31 @@ static struct config *config_get(int index, const char *line) config->line->del = (void (*)(void *))line_del; config->line->cmp = (int (*)(void *, void *))line_cmp; config->name = XSTRDUP(MTYPE_VTYSH_CONFIG_LINE, line); + config->exit = NULL; config->index = index; + config->nested = vector_init(1); config_master_add_tail(&configuration->master, config); config_master_hash_add(&configuration->hash_master, config); } return config; } +static struct config *config_get(int index, const char *line) +{ + return config_get_vec(configvec, index, line); +} + +static struct config *config_get_nested(struct config *parent, int index, + const char *line) +{ + struct config *config; + + config = config_get_vec(parent->nested, index, line); + config->parent = parent; + + return config; +} + void config_add_line(struct list *config, const char *line) { listnode_add(config, XSTRDUP(MTYPE_VTYSH_CONFIG_LINE, line)); @@ -259,9 +284,23 @@ void vtysh_config_parse_line(void *arg, const char *line) case ' ': /* Store line to current configuration. */ if (config) { - if (strncmp(line, " link-params", - strlen(" link-params")) - == 0) { + if (config->index == KEYCHAIN_NODE + && strncmp(line, " key", strlen(" key")) == 0) { + config = config_get_nested( + config, KEYCHAIN_KEY_NODE, line); + } else if (config->index == KEYCHAIN_KEY_NODE) { + if (strncmp(line, " exit", strlen(" exit")) + == 0) { + config_add_line_uniq_end(config->line, + line); + config = config->parent; + } else { + config_add_line_uniq(config->line, + line); + } + } else if (strncmp(line, " link-params", + strlen(" link-params")) + == 0) { config_add_line(config->line, line); config->index = LINK_PARAMS_NODE; } else if (strncmp(line, " ip multicast boundary", @@ -269,7 +308,8 @@ void vtysh_config_parse_line(void *arg, const char *line) == 0) { config_add_line_uniq_end(config->line, line); } else if (strncmp(line, " ip igmp query-interval", - strlen(" ip igmp query-interval")) == 0) { + 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", @@ -281,7 +321,8 @@ void vtysh_config_parse_line(void *arg, const char *line) || !strncmp(line, " no vrrp", strlen(" no vrrp"))) { config_add_line(config->line, line); - } else if (!strncmp(line, " ip mroute", strlen(" ip mroute"))) { + } else if (!strncmp(line, " ip mroute", + strlen(" ip mroute"))) { config_add_line_uniq_end(config->line, line); } else if (config->index == RMAP_NODE || config->index == INTERFACE_NODE @@ -296,7 +337,8 @@ void vtysh_config_parse_line(void *arg, const char *line) default: if (strncmp(line, "exit", strlen("exit")) == 0) { if (config) - config_add_line_uniq_end(config->line, line); + config->exit = + XSTRDUP(MTYPE_VTYSH_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) @@ -463,25 +505,18 @@ void vtysh_config_parse_line(void *arg, const char *line) || (I) == FORWARDING_NODE || (I) == DEBUG_NODE || (I) == AAA_NODE \ || (I) == VRF_DEBUG_NODE || (I) == NORTHBOUND_DEBUG_NODE \ || (I) == RMAP_DEBUG_NODE || (I) == RESOLVER_DEBUG_NODE \ - || (I) == MPLS_NODE) + || (I) == MPLS_NODE || (I) == KEYCHAIN_KEY_NODE) -/* Display configuration to file pointer. */ -void vtysh_config_dump(void) +static void configvec_dump(vector vec, bool nested) { - struct listnode *node, *nnode; struct listnode *mnode, *mnnode; struct config *config; struct configuration *configuration; char *line; unsigned int i; - for (ALL_LIST_ELEMENTS(config_top, node, nnode, line)) - vty_out(vty, "%s\n", line); - - vty_out(vty, "!\n"); - - for (i = 0; i < vector_active(configvec); i++) - if ((configuration = vector_slot(configvec, i)) != NULL) { + for (i = 0; i < vector_active(vec); i++) + if ((configuration = vector_slot(vec, i)) != NULL) { while ((config = config_master_pop( &configuration->master))) { config_master_hash_del( @@ -507,23 +542,39 @@ void vtysh_config_dump(void) for (ALL_LIST_ELEMENTS(config->line, mnode, mnnode, line)) vty_out(vty, "%s\n", line); + + configvec_dump(config->nested, true); + + if (config->exit) + vty_out(vty, "%s\n", config->exit); + if (!NO_DELIMITER(i)) vty_out(vty, "!\n"); config_del(config); } - if (NO_DELIMITER(i)) - vty_out(vty, "!\n"); - } - - for (i = 0; i < vector_active(configvec); i++) - if ((configuration = vector_slot(configvec, i)) != NULL) { config_master_fini(&configuration->master); config_master_hash_fini(&configuration->hash_master); XFREE(MTYPE_VTYSH_CONFIG, configuration); - vector_slot(configvec, i) = NULL; + vector_slot(vec, i) = NULL; + if (!nested && NO_DELIMITER(i)) + vty_out(vty, "!\n"); } +} + +void vtysh_config_dump(void) +{ + struct listnode *node, *nnode; + char *line; + + for (ALL_LIST_ELEMENTS(config_top, node, nnode, line)) + vty_out(vty, "%s\n", line); + list_delete_all_node(config_top); + + vty_out(vty, "!\n"); + + configvec_dump(configvec, false); } /* Read up configuration file from file_name. */ |