summaryrefslogtreecommitdiff
path: root/lib/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/command.c')
-rw-r--r--lib/command.c269
1 files changed, 187 insertions, 82 deletions
diff --git a/lib/command.c b/lib/command.c
index f244d67e86..0fa6bde334 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -49,6 +49,29 @@ DEFINE_MTYPE(LIB, HOST, "Host config")
DEFINE_MTYPE(LIB, STRVEC, "String vector")
DEFINE_MTYPE(LIB, COMPLETION, "Completion item")
+#define item(x) \
+ { \
+ x, #x \
+ }
+
+/* clang-format off */
+const struct message tokennames[] = {
+ item(WORD_TKN),
+ item(VARIABLE_TKN),
+ item(RANGE_TKN),
+ item(IPV4_TKN),
+ item(IPV4_PREFIX_TKN),
+ item(IPV6_TKN),
+ item(IPV6_PREFIX_TKN),
+ item(MAC_TKN),
+ item(MAC_PREFIX_TKN),
+ item(FORK_TKN),
+ item(JOIN_TKN),
+ item(START_TKN),
+ item(END_TKN),
+ {0},
+};
+
const char *node_names[] = {
"auth", // AUTH_NODE,
"view", // VIEW_NODE,
@@ -62,6 +85,7 @@ const char *node_names[] = {
"keychain", // KEYCHAIN_NODE,
"keychain key", // KEYCHAIN_KEY_NODE,
"logical-router", // LOGICALROUTER_NODE,
+ "static ip", // IP_NODE,
"vrf", // VRF_NODE,
"interface", // INTERFACE_NODE,
"nexthop-group", // NH_GROUP_NODE,
@@ -96,7 +120,6 @@ const char *node_names[] = {
"ldp l2vpn", // LDP_L2VPN_NODE,
"ldp", // LDP_PSEUDOWIRE_NODE,
"isis", // ISIS_NODE,
- "static ip", // IP_NODE,
"ipv4 access list", // ACCESS_NODE,
"ipv4 prefix list", // PREFIX_NODE,
"ipv6 access list", // ACCESS_IPV6_NODE,
@@ -105,6 +128,7 @@ const char *node_names[] = {
"as list", // AS_LIST_NODE,
"community list", // COMMUNITY_LIST_NODE,
"routemap", // RMAP_NODE,
+ "pbr-map", // PBRMAP_NODE,
"smux", // SMUX_NODE,
"dump", // DUMP_NODE,
"forwarding", // FORWARDING_NODE,
@@ -120,6 +144,7 @@ const char *node_names[] = {
"bgp ipv6 flowspec", /* BGP_FLOWSPECV6_NODE
*/
};
+/* clang-format on */
/* Command vector which includes some level of command lists. Normally
each daemon maintains each own cmdvec. */
@@ -504,87 +529,103 @@ static int config_write_host(struct vty *vty)
if (cmd_domainname_get())
vty_out(vty, "domainname %s\n", cmd_domainname_get());
- if (host.encrypt) {
- if (host.password_encrypt)
- vty_out(vty, "password 8 %s\n", host.password_encrypt);
- if (host.enable_encrypt)
- vty_out(vty, "enable password 8 %s\n",
- host.enable_encrypt);
- } else {
- if (host.password)
- vty_out(vty, "password %s\n", host.password);
- if (host.enable)
- vty_out(vty, "enable password %s\n", host.enable);
- }
+ /* The following are all configuration commands that are not sent to
+ * watchfrr. For instance watchfrr is hardcoded to log to syslog so
+ * we would always display 'log syslog informational' in the config
+ * which would cause other daemons to then switch to syslog when they
+ * parse frr.conf.
+ */
+ if (strcmp(zlog_default->protoname, "WATCHFRR")) {
+ if (host.encrypt) {
+ if (host.password_encrypt)
+ vty_out(vty, "password 8 %s\n",
+ host.password_encrypt);
+ if (host.enable_encrypt)
+ vty_out(vty, "enable password 8 %s\n",
+ host.enable_encrypt);
+ } else {
+ if (host.password)
+ vty_out(vty, "password %s\n", host.password);
+ if (host.enable)
+ vty_out(vty, "enable password %s\n",
+ host.enable);
+ }
- if (zlog_default->default_lvl != LOG_DEBUG) {
- vty_out(vty, "! N.B. The 'log trap' command is deprecated.\n");
- vty_out(vty, "log trap %s\n",
- zlog_priority[zlog_default->default_lvl]);
- }
+ if (zlog_default->default_lvl != LOG_DEBUG) {
+ vty_out(vty,
+ "! N.B. The 'log trap' command is deprecated.\n");
+ vty_out(vty, "log trap %s\n",
+ zlog_priority[zlog_default->default_lvl]);
+ }
- if (host.logfile
- && (zlog_default->maxlvl[ZLOG_DEST_FILE] != ZLOG_DISABLED)) {
- vty_out(vty, "log file %s", host.logfile);
- if (zlog_default->maxlvl[ZLOG_DEST_FILE]
- != zlog_default->default_lvl)
- vty_out(vty, " %s",
- zlog_priority
- [zlog_default->maxlvl[ZLOG_DEST_FILE]]);
- vty_out(vty, "\n");
- }
+ if (host.logfile
+ && (zlog_default->maxlvl[ZLOG_DEST_FILE]
+ != ZLOG_DISABLED)) {
+ vty_out(vty, "log file %s", host.logfile);
+ if (zlog_default->maxlvl[ZLOG_DEST_FILE]
+ != zlog_default->default_lvl)
+ vty_out(vty, " %s",
+ zlog_priority
+ [zlog_default->maxlvl
+ [ZLOG_DEST_FILE]]);
+ vty_out(vty, "\n");
+ }
- if (zlog_default->maxlvl[ZLOG_DEST_STDOUT] != ZLOG_DISABLED) {
- vty_out(vty, "log stdout");
- if (zlog_default->maxlvl[ZLOG_DEST_STDOUT]
- != zlog_default->default_lvl)
- vty_out(vty, " %s",
- zlog_priority[zlog_default->maxlvl
- [ZLOG_DEST_STDOUT]]);
- vty_out(vty, "\n");
- }
+ if (zlog_default->maxlvl[ZLOG_DEST_STDOUT] != ZLOG_DISABLED) {
+ vty_out(vty, "log stdout");
+ if (zlog_default->maxlvl[ZLOG_DEST_STDOUT]
+ != zlog_default->default_lvl)
+ vty_out(vty, " %s",
+ zlog_priority
+ [zlog_default->maxlvl
+ [ZLOG_DEST_STDOUT]]);
+ vty_out(vty, "\n");
+ }
- if (zlog_default->maxlvl[ZLOG_DEST_MONITOR] == ZLOG_DISABLED)
- vty_out(vty, "no log monitor\n");
- else if (zlog_default->maxlvl[ZLOG_DEST_MONITOR]
- != zlog_default->default_lvl)
- vty_out(vty, "log monitor %s\n",
- zlog_priority[zlog_default->maxlvl[ZLOG_DEST_MONITOR]]);
-
- if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED) {
- vty_out(vty, "log syslog");
- if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG]
- != zlog_default->default_lvl)
- vty_out(vty, " %s",
+ if (zlog_default->maxlvl[ZLOG_DEST_MONITOR] == ZLOG_DISABLED)
+ vty_out(vty, "no log monitor\n");
+ else if (zlog_default->maxlvl[ZLOG_DEST_MONITOR]
+ != zlog_default->default_lvl)
+ vty_out(vty, "log monitor %s\n",
zlog_priority[zlog_default->maxlvl
- [ZLOG_DEST_SYSLOG]]);
- vty_out(vty, "\n");
- }
+ [ZLOG_DEST_MONITOR]]);
+
+ if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED) {
+ vty_out(vty, "log syslog");
+ if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG]
+ != zlog_default->default_lvl)
+ vty_out(vty, " %s",
+ zlog_priority[zlog_default->maxlvl
+ [ZLOG_DEST_SYSLOG]]);
+ vty_out(vty, "\n");
+ }
- if (zlog_default->facility != LOG_DAEMON)
- vty_out(vty, "log facility %s\n",
- facility_name(zlog_default->facility));
+ if (zlog_default->facility != LOG_DAEMON)
+ vty_out(vty, "log facility %s\n",
+ facility_name(zlog_default->facility));
- if (zlog_default->record_priority == 1)
- vty_out(vty, "log record-priority\n");
+ if (zlog_default->record_priority == 1)
+ vty_out(vty, "log record-priority\n");
- if (zlog_default->timestamp_precision > 0)
- vty_out(vty, "log timestamp precision %d\n",
- zlog_default->timestamp_precision);
+ if (zlog_default->timestamp_precision > 0)
+ vty_out(vty, "log timestamp precision %d\n",
+ zlog_default->timestamp_precision);
- if (host.advanced)
- vty_out(vty, "service advanced-vty\n");
+ if (host.advanced)
+ vty_out(vty, "service advanced-vty\n");
- if (host.encrypt)
- vty_out(vty, "service password-encryption\n");
+ if (host.encrypt)
+ vty_out(vty, "service password-encryption\n");
- if (host.lines >= 0)
- vty_out(vty, "service terminal-length %d\n", host.lines);
+ if (host.lines >= 0)
+ vty_out(vty, "service terminal-length %d\n",
+ host.lines);
- if (host.motdfile)
- vty_out(vty, "banner motd file %s\n", host.motdfile);
- else if (!host.motd)
- vty_out(vty, "no banner motd\n");
+ if (host.motdfile)
+ vty_out(vty, "banner motd file %s\n", host.motdfile);
+ else if (!host.motd)
+ vty_out(vty, "no banner motd\n");
+ }
if (debug_memstats_at_exit)
vty_out(vty, "!\ndebug memstats-at-exit\n");
@@ -1312,6 +1353,7 @@ void cmd_exit(struct vty *vty)
case ISIS_NODE:
case KEYCHAIN_NODE:
case RMAP_NODE:
+ case PBRMAP_NODE:
case VTY_NODE:
vty->node = CONFIG_NODE;
break;
@@ -1409,6 +1451,7 @@ DEFUN (config_end,
case BGP_EVPN_VNI_NODE:
case BGP_IPV6L_NODE:
case RMAP_NODE:
+ case PBRMAP_NODE:
case OSPF_NODE:
case OSPF6_NODE:
case LDP_NODE:
@@ -1563,6 +1606,21 @@ DEFUN (show_commandtree,
return cmd_list_cmds(vty, argc == 3);
}
+DEFUN_HIDDEN(show_cli_graph,
+ show_cli_graph_cmd,
+ "show cli graph",
+ SHOW_STR
+ "CLI reflection\n"
+ "Dump current command space as DOT graph\n")
+{
+ struct cmd_node *cn = vector_slot(cmdvec, vty->node);
+ char *dot = cmd_graph_dump_dot(cn->cmdgraph);
+
+ vty_out(vty, "%s\n", dot);
+ XFREE(MTYPE_TMP, dot);
+ return CMD_SUCCESS;
+}
+
static int vty_write_config(struct vty *vty)
{
size_t i;
@@ -1831,7 +1889,7 @@ DEFUN (config_hostname,
{
struct cmd_token *word = argv[1];
- if (!isalpha((int)word->arg[0])) {
+ if (!isalnum((int)word->arg[0])) {
vty_out(vty, "Please specify string starting with alphabet\n");
return CMD_WARNING_CONFIG_FAILED;
}
@@ -1853,7 +1911,7 @@ DEFUN (config_no_hostname,
DEFUN (config_password,
password_cmd,
"password [(8-8)] WORD",
- "Assign the terminal connection password\n"
+ "Modify the terminal connection password\n"
"Specifies a HIDDEN password will follow\n"
"The password string\n")
{
@@ -1892,6 +1950,34 @@ DEFUN (config_password,
return CMD_SUCCESS;
}
+/* VTY interface password delete. */
+DEFUN (no_config_password,
+ no_password_cmd,
+ "no password",
+ NO_STR
+ "Modify the terminal connection password\n")
+{
+ bool warned = false;
+
+ if (host.password) {
+ if (!vty_shell_serv(vty)) {
+ vty_out(vty, NO_PASSWD_CMD_WARNING);
+ warned = true;
+ }
+ XFREE(MTYPE_HOST, host.password);
+ }
+ host.password = NULL;
+
+ if (host.password_encrypt) {
+ if (!warned && !vty_shell_serv(vty))
+ vty_out(vty, NO_PASSWD_CMD_WARNING);
+ XFREE(MTYPE_HOST, host.password_encrypt);
+ }
+ host.password_encrypt = NULL;
+
+ return CMD_SUCCESS;
+}
+
/* VTY enable password set. */
DEFUN (config_enable_password,
enable_password_cmd,
@@ -1953,12 +2039,22 @@ DEFUN (no_config_enable_password,
"Modify enable password parameters\n"
"Assign the privileged level password\n")
{
- if (host.enable)
+ bool warned = false;
+
+ if (host.enable) {
+ if (!vty_shell_serv(vty)) {
+ vty_out(vty, NO_PASSWD_CMD_WARNING);
+ warned = true;
+ }
XFREE(MTYPE_HOST, host.enable);
+ }
host.enable = NULL;
- if (host.enable_encrypt)
+ if (host.enable_encrypt) {
+ if (!warned && !vty_shell_serv(vty))
+ vty_out(vty, NO_PASSWD_CMD_WARNING);
XFREE(MTYPE_HOST, host.enable_encrypt);
+ }
host.enable_encrypt = NULL;
return CMD_SUCCESS;
@@ -2262,7 +2358,7 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel)
#if defined(HAVE_CUMULUS)
if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED)
- zlog_default->maxlvl[ZLOG_DEST_SYSLOG] = ZLOG_DISABLED;
+ zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
#endif
return CMD_SUCCESS;
}
@@ -2288,6 +2384,16 @@ DEFUN (config_log_file,
zlog_default->default_lvl);
}
+static void disable_log_file(void)
+{
+ zlog_reset_file();
+
+ if (host.logfile)
+ XFREE(MTYPE_HOST, host.logfile);
+
+ host.logfile = NULL;
+}
+
DEFUN (no_config_log_file,
no_config_log_file_cmd,
"no log file [FILENAME [LEVEL]]",
@@ -2297,13 +2403,7 @@ DEFUN (no_config_log_file,
"Logging file name\n"
"Logging level\n")
{
- zlog_reset_file();
-
- if (host.logfile)
- XFREE(MTYPE_HOST, host.logfile);
-
- host.logfile = NULL;
-
+ disable_log_file();
return CMD_SUCCESS;
}
@@ -2315,6 +2415,9 @@ DEFUN (config_log_syslog,
LOG_LEVEL_DESC)
{
int idx_log_levels = 2;
+
+ disable_log_file();
+
if (argc == 3) {
int level;
if ((level = level_match(argv[idx_log_levels]->arg))
@@ -2570,6 +2673,7 @@ void install_default(enum node_type node)
install_element(node, &config_end_cmd);
install_element(node, &config_help_cmd);
install_element(node, &config_list_cmd);
+ install_element(node, &show_cli_graph_cmd);
install_element(node, &find_cmd);
install_element(node, &config_write_cmd);
@@ -2667,6 +2771,7 @@ void cmd_init(int terminal)
if (terminal > 0) {
install_element(CONFIG_NODE, &password_cmd);
+ install_element(CONFIG_NODE, &no_password_cmd);
install_element(CONFIG_NODE, &enable_password_cmd);
install_element(CONFIG_NODE, &no_enable_password_cmd);