diff options
Diffstat (limited to 'lib/command.c')
| -rw-r--r-- | lib/command.c | 95 |
1 files changed, 61 insertions, 34 deletions
diff --git a/lib/command.c b/lib/command.c index 97ea200ff4..0288ab7599 100644 --- a/lib/command.c +++ b/lib/command.c @@ -10,6 +10,10 @@ */ #include <zebra.h> +#include <sys/utsname.h> +#include <sys/stat.h> +#include <fcntl.h> + #include <lib/version.h> #include "command.h" @@ -31,12 +35,16 @@ #include "jhash.h" #include "hook.h" #include "lib_errors.h" +#include "mgmt_be_client.h" +#include "mgmt_fe_client.h" #include "northbound_cli.h" #include "network.h" #include "routemap.h" #include "frrscript.h" +#include "lib/config_paths.h" + DEFINE_MTYPE_STATIC(LIB, HOST, "Host config"); DEFINE_MTYPE(LIB, COMPLETION, "Completion item"); @@ -475,33 +483,18 @@ static int config_write_host(struct vty *vty) } log_config_write(vty); - /* print disable always, but enable only if default is flipped - * => prep for future removal of compile-time knob - */ if (!cputime_enabled) vty_out(vty, "no service cputime-stats\n"); -#ifdef EXCLUDE_CPU_TIME - else - vty_out(vty, "service cputime-stats\n"); -#endif if (!cputime_threshold) vty_out(vty, "no service cputime-warning\n"); -#if defined(CONSUMED_TIME_CHECK) && CONSUMED_TIME_CHECK != 5000000 - else /* again, always print non-default */ -#else - else if (cputime_threshold != 5000000) -#endif + else if (cputime_threshold != CONSUMED_TIME_CHECK) vty_out(vty, "service cputime-warning %lu\n", cputime_threshold / 1000); if (!walltime_threshold) vty_out(vty, "no service walltime-warning\n"); -#if defined(CONSUMED_TIME_CHECK) && CONSUMED_TIME_CHECK != 5000000 - else /* again, always print non-default */ -#else - else if (walltime_threshold != 5000000) -#endif + else if (walltime_threshold != CONSUMED_TIME_CHECK) vty_out(vty, "service walltime-warning %lu\n", walltime_threshold / 1000); @@ -685,6 +678,21 @@ vector cmd_describe_command(vector vline, struct vty *vty, int *status) static struct list *varhandlers = NULL; +static int __add_key_comp(const struct lyd_node *dnode, void *arg) +{ + const char *key_value = yang_dnode_get_string(dnode, NULL); + + vector_set((vector)arg, XSTRDUP(MTYPE_COMPLETION, key_value)); + + return YANG_ITER_CONTINUE; +} + +static void __get_list_keys(vector comps, const char *xpath) +{ + yang_dnode_iterate(__add_key_comp, comps, + vty_shared_candidate_config->dnode, "%s", xpath); +} + void cmd_variable_complete(struct cmd_token *token, const char *arg, vector comps) { @@ -701,7 +709,10 @@ void cmd_variable_complete(struct cmd_token *token, const char *arg, if (cvh->varname && (!token->varname || strcmp(cvh->varname, token->varname))) continue; - cvh->completions(tmpcomps, token); + if (cvh->xpath) + __get_list_keys(tmpcomps, cvh->xpath); + if (cvh->completions) + cvh->completions(tmpcomps, token); break; } @@ -733,9 +744,13 @@ char *cmd_variable_comp2str(vector comps, unsigned short cols) char *item = vector_slot(comps, j); itemlen = strlen(item); - if (cs + itemlen + AUTOCOMP_INDENT + 3 >= bsz) - buf = XREALLOC(MTYPE_TMP, buf, (bsz *= 2)); + size_t next_sz = cs + itemlen + AUTOCOMP_INDENT + 3; + if (next_sz > bsz) { + /* Make sure the buf size is large enough */ + bsz = next_sz; + buf = XREALLOC(MTYPE_TMP, buf, bsz); + } if (lc + itemlen + 1 >= cols) { cs += snprintf(&buf[cs], bsz - cs, "\n%*s", AUTOCOMP_INDENT, ""); @@ -756,7 +771,7 @@ void cmd_variable_handler_register(const struct cmd_variable_handler *cvh) if (!varhandlers) return; - for (; cvh->completions; cvh++) + for (; cvh->completions || cvh->xpath; cvh++) listnode_add(varhandlers, (void *)cvh); } @@ -897,8 +912,7 @@ enum node_type node_parent(enum node_type node) } /* Execute command by argument vline vector. */ -static int cmd_execute_command_real(vector vline, enum cmd_filter_type filter, - struct vty *vty, +static int cmd_execute_command_real(vector vline, struct vty *vty, const struct cmd_element **cmd, unsigned int up_level) { @@ -1035,8 +1049,7 @@ int cmd_execute_command(vector vline, struct vty *vty, vector_set_index(shifted_vline, index - 1, vector_lookup(vline, index)); - ret = cmd_execute_command_real(shifted_vline, FILTER_RELAXED, - vty, cmd, 0); + ret = cmd_execute_command_real(shifted_vline, vty, cmd, 0); vector_free(shifted_vline); vty->node = onode; @@ -1045,7 +1058,7 @@ int cmd_execute_command(vector vline, struct vty *vty, } saved_ret = ret = - cmd_execute_command_real(vline, FILTER_RELAXED, vty, cmd, 0); + cmd_execute_command_real(vline, vty, cmd, 0); if (vtysh) return saved_ret; @@ -1063,8 +1076,7 @@ int cmd_execute_command(vector vline, struct vty *vty, if (vty->xpath_index > 0 && !cnode->no_xpath) vty->xpath_index--; - ret = cmd_execute_command_real(vline, FILTER_RELAXED, - vty, cmd, 0); + ret = cmd_execute_command_real(vline, vty, cmd, 0); if (ret == CMD_SUCCESS || ret == CMD_WARNING || ret == CMD_ERR_AMBIGUOUS || ret == CMD_ERR_INCOMPLETE || ret == CMD_NOT_MY_INSTANCE @@ -1096,7 +1108,7 @@ int cmd_execute_command(vector vline, struct vty *vty, int cmd_execute_command_strict(vector vline, struct vty *vty, const struct cmd_element **cmd) { - return cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd, 0); + return cmd_execute_command_real(vline, vty, cmd, 0); } /* @@ -1268,8 +1280,7 @@ int command_config_read_one_line(struct vty *vty, && ret != CMD_ERR_AMBIGUOUS && ret != CMD_ERR_INCOMPLETE && ret != CMD_NOT_MY_INSTANCE && ret != CMD_WARNING_CONFIG_FAILED && ret != CMD_NO_LEVEL_UP) - ret = cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd, - ++up_level); + ret = cmd_execute_command_real(vline, vty, cmd, ++up_level); if (ret == CMD_NO_LEVEL_UP) ret = CMD_ERR_NO_MATCH; @@ -1281,6 +1292,7 @@ int command_config_read_one_line(struct vty *vty, memcpy(ve->error_buf, vty->buf, VTY_BUFSIZ); ve->line_num = line_num; + ve->cmd_ret = ret; if (!vty->error) vty->error = list_new(); @@ -1301,6 +1313,14 @@ int config_from_file(struct vty *vty, FILE *fp, unsigned int *line_num) while (fgets(vty->buf, VTY_BUFSIZ, fp)) { ++(*line_num); + if (vty_log_commands) { + int len = strlen(vty->buf); + + /* now log the command */ + zlog_notice("config-from-file# %.*s", len ? len - 1 : 0, + vty->buf); + } + ret = command_config_read_one_line(vty, NULL, *line_num, 0); if (ret != CMD_SUCCESS && ret != CMD_WARNING @@ -1318,11 +1338,12 @@ int config_from_file(struct vty *vty, FILE *fp, unsigned int *line_num) /* Configuration from terminal */ DEFUN (config_terminal, config_terminal_cmd, - "configure [terminal]", + "configure [terminal [file-lock]]", "Configuration from vty interface\n" - "Configuration terminal\n") + "Configuration terminal\n" + "Configuration with locked datastores\n") { - return vty_config_enter(vty, false, false); + return vty_config_enter(vty, false, false, argc == 3); } /* Enable command */ @@ -1632,6 +1653,10 @@ static int vty_write_config(struct vty *vty) return CMD_SUCCESS; } +/* cross-reference frr_daemon_state_save in libfrr.c + * the code there is similar but not identical (state files always use the same + * name for the new write, and don't keep a backup of previous state.) + */ static int file_write_config(struct vty *vty) { int fd, dirfd; @@ -2438,6 +2463,8 @@ const char *host_config_get(void) void cmd_show_lib_debugs(struct vty *vty) { route_map_show_debug(vty); + mgmt_debug_be_client_show_debug(vty); + mgmt_debug_fe_client_show_debug(vty); } void install_default(enum node_type node) |
