1 /* Virtual terminal interface shell.
2 * Copyright (C) 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <sys/resource.h>
29 /* readline carries some ancient definitions around */
30 #pragma GCC diagnostic push
31 #pragma GCC diagnostic ignored "-Wstrict-prototypes"
32 #include <readline/readline.h>
33 #include <readline/history.h>
34 #pragma GCC diagnostic pop
44 #include "vtysh/vtysh.h"
45 #include "vtysh/vtysh_daemons.h"
49 #include "command_graph.h"
54 DEFINE_MTYPE_STATIC(MVTYSH
, VTYSH_CMD
, "Vtysh cmd copy");
59 /* VTY shell pager name. */
60 char *vtysh_pager_name
= NULL
;
62 /* VTY should add timestamp */
63 bool vtysh_add_timestamp
;
65 /* VTY shell client structure */
70 char path
[MAXPATHLEN
];
71 struct vtysh_client
*next
;
74 /* Some utility functions for working on vtysh-specific vty tasks */
76 static FILE *vty_open_pager(struct vty
*vty
)
81 if (!vtysh_pager_name
)
84 vty
->of_saved
= vty
->of
;
85 vty
->of
= popen(vtysh_pager_name
, "w");
86 if (vty
->of
== NULL
) {
87 vty
->of
= vty
->of_saved
;
97 static int vty_close_pager(struct vty
*vty
)
103 if (pclose(vty
->of
) == -1) {
108 vty
->of
= vty
->of_saved
;
109 vty
->is_paged
= false;
114 static void vtysh_pager_envdef(bool fallback
)
118 pager_defined
= getenv("VTYSH_PAGER");
121 vtysh_pager_name
= strdup(pager_defined
);
123 vtysh_pager_name
= strdup(VTYSH_PAGER
);
128 struct vtysh_client vtysh_client
[] = {
129 {.fd
= -1, .name
= "zebra", .flag
= VTYSH_ZEBRA
, .next
= NULL
},
130 {.fd
= -1, .name
= "ripd", .flag
= VTYSH_RIPD
, .next
= NULL
},
131 {.fd
= -1, .name
= "ripngd", .flag
= VTYSH_RIPNGD
, .next
= NULL
},
132 {.fd
= -1, .name
= "ospfd", .flag
= VTYSH_OSPFD
, .next
= NULL
},
133 {.fd
= -1, .name
= "ospf6d", .flag
= VTYSH_OSPF6D
, .next
= NULL
},
134 {.fd
= -1, .name
= "ldpd", .flag
= VTYSH_LDPD
, .next
= NULL
},
135 {.fd
= -1, .name
= "bgpd", .flag
= VTYSH_BGPD
, .next
= NULL
},
136 {.fd
= -1, .name
= "isisd", .flag
= VTYSH_ISISD
, .next
= NULL
},
137 {.fd
= -1, .name
= "pimd", .flag
= VTYSH_PIMD
, .next
= NULL
},
138 {.fd
= -1, .name
= "nhrpd", .flag
= VTYSH_NHRPD
, .next
= NULL
},
139 {.fd
= -1, .name
= "eigrpd", .flag
= VTYSH_EIGRPD
, .next
= NULL
},
140 {.fd
= -1, .name
= "babeld", .flag
= VTYSH_BABELD
, .next
= NULL
},
141 {.fd
= -1, .name
= "sharpd", .flag
= VTYSH_SHARPD
, .next
= NULL
},
142 {.fd
= -1, .name
= "fabricd", .flag
= VTYSH_FABRICD
, .next
= NULL
},
143 {.fd
= -1, .name
= "watchfrr", .flag
= VTYSH_WATCHFRR
, .next
= NULL
},
144 {.fd
= -1, .name
= "pbrd", .flag
= VTYSH_PBRD
, .next
= NULL
},
145 {.fd
= -1, .name
= "staticd", .flag
= VTYSH_STATICD
, .next
= NULL
},
146 {.fd
= -1, .name
= "bfdd", .flag
= VTYSH_BFDD
, .next
= NULL
},
147 {.fd
= -1, .name
= "vrrpd", .flag
= VTYSH_VRRPD
, .next
= NULL
},
148 {.fd
= -1, .name
= "pathd", .flag
= VTYSH_PATHD
, .next
= NULL
},
151 /* Searches for client by name, returns index */
152 static int vtysh_client_lookup(const char *name
)
156 for (unsigned int i
= 0; i
< array_size(vtysh_client
); i
++) {
157 if (strmatch(vtysh_client
[i
].name
, name
)) {
166 enum vtysh_write_integrated vtysh_write_integrated
=
167 WRITE_INTEGRATED_UNSPECIFIED
;
169 static int vtysh_reconnect(struct vtysh_client
*vclient
);
171 static void vclient_close(struct vtysh_client
*vclient
)
173 if (vclient
->fd
>= 0) {
176 "Warning: closing connection to %s because of an I/O error!\n",
179 /* indicate as candidate for reconnect */
180 vclient
->fd
= VTYSH_WAS_ACTIVE
;
185 * Send a CLI command to a client and read the response.
187 * Output will be printed to vty->of. If you want to suppress output, set that
191 * the client to send the command to
194 * the command to send
197 * if non-null, this will be called with each line of output received from
198 * the client passed in the second parameter
201 * optional first argument to pass to callback
206 static int vtysh_client_run(struct vtysh_client
*vclient
, const char *line
,
207 void (*callback
)(void *, const char *), void *cbarg
)
211 char *buf
= stackbuf
;
212 size_t bufsz
= sizeof(stackbuf
);
213 char *bufvalid
, *end
= NULL
;
214 char terminator
[3] = {0, 0, 0};
216 /* vclinet was previously active, try to reconnect */
217 if (vclient
->fd
== VTYSH_WAS_ACTIVE
) {
218 ret
= vtysh_reconnect(vclient
);
226 ret
= write(vclient
->fd
, line
, strlen(line
) + 1);
228 /* close connection and try to reconnect */
229 vclient_close(vclient
);
230 ret
= vtysh_reconnect(vclient
);
234 ret
= write(vclient
->fd
, line
, strlen(line
) + 1);
242 read(vclient
->fd
, bufvalid
, buf
+ bufsz
- bufvalid
- 1);
244 if (nread
< 0 && (errno
== EINTR
|| errno
== EAGAIN
))
250 "vtysh: error reading from %s: %s (%d)",
251 vclient
->name
, safe_strerror(errno
),
258 /* Null terminate so we may pass this to *printf later. */
262 * We expect string output from daemons, so instead of looking
263 * for the full 3 null bytes of the terminator, we check for
264 * just one instead and assume it is the first byte of the
265 * terminator. The presence of the full terminator is checked
268 if (bufvalid
- buf
>= 4)
269 end
= memmem(bufvalid
- 4, 4, "\0", 1);
272 * calculate # bytes we have, up to & not including the
273 * terminator if present
275 size_t textlen
= (end
? end
: bufvalid
) - buf
;
278 /* feed line processing callback if present */
279 while (callback
&& bufvalid
> buf
&& (end
> buf
|| !end
)) {
280 textlen
= (end
? end
: bufvalid
) - buf
;
281 char *eol
= memchr(buf
, '\n', textlen
);
287 * no line break, end of input, no text left
288 * before end; nothing to write
292 /* no nl, end of input, but some text left */
294 else if (bufvalid
== buf
+ bufsz
- 1) {
296 * no nl, no end of input, no buffer space;
302 if (buf
== stackbuf
) {
303 new = XMALLOC(MTYPE_TMP
, bufsz
);
304 memcpy(new, stackbuf
, sizeof(stackbuf
));
306 new = XREALLOC(MTYPE_TMP
, buf
, bufsz
);
308 bufvalid
= bufvalid
- buf
+ new;
310 /* if end != NULL, we won't be reading more
320 /* eol is at line end now, either \n => \0 or \0\0\0 */
321 assert(eol
&& eol
<= bufvalid
);
324 vty_out(vty
, "%s\n", buf
);
326 callback(cbarg
, buf
);
328 /* shift back data and adjust bufvalid */
329 memmove(buf
, eol
, bufvalid
- eol
);
330 bufvalid
-= eol
- buf
;
335 /* else if no callback, dump raw */
338 vty_out(vty
, "%s", buf
);
339 memmove(buf
, buf
+ textlen
, bufvalid
- buf
- textlen
);
345 * ----------------------------------------------------
346 * At this point `buf` should be in one of two states:
347 * - Empty (i.e. buf == bufvalid)
348 * - Contains up to 4 bytes of the terminator
349 * ----------------------------------------------------
351 assert(((buf
== bufvalid
)
352 || (bufvalid
- buf
<= 4 && buf
[0] == 0x00)));
355 /* if we have the terminator, break */
356 if (end
&& bufvalid
- buf
== 4) {
357 assert(!memcmp(buf
, terminator
, 3));
366 vclient_close(vclient
);
370 XFREE(MTYPE_TMP
, buf
);
374 static int vtysh_client_run_all(struct vtysh_client
*head_client
,
375 const char *line
, int continue_on_err
,
376 void (*callback
)(void *, const char *),
379 struct vtysh_client
*client
;
380 int rc
, rc_all
= CMD_SUCCESS
;
381 int correct_instance
= 0, wrong_instance
= 0;
383 for (client
= head_client
; client
; client
= client
->next
) {
384 rc
= vtysh_client_run(client
, line
, callback
, cbarg
);
385 if (rc
== CMD_NOT_MY_INSTANCE
) {
391 if (rc
!= CMD_SUCCESS
) {
392 if (!continue_on_err
)
397 if (wrong_instance
&& !correct_instance
&& vty
->of
) {
399 "%% [%s]: command ignored as it targets an instance that is not running\n",
401 rc_all
= CMD_WARNING_CONFIG_FAILED
;
407 * Execute command against all daemons.
410 * where to start walking in the daemon list
413 * the specific command to execute
418 static int vtysh_client_execute(struct vtysh_client
*head_client
,
421 return vtysh_client_run_all(head_client
, line
, 0, NULL
, NULL
);
424 /* Execute by name */
425 static int vtysh_client_execute_name(const char *name
, const char *line
)
427 int ret
= CMD_SUCCESS
;
430 idx_client
= vtysh_client_lookup(name
);
431 if (idx_client
!= -1)
432 ret
= vtysh_client_execute(&vtysh_client
[idx_client
], line
);
434 vty_out(vty
, "Client not found\n");
442 * Retrieve all running config from daemons and parse it with the vtysh config
443 * parser. Returned output is not displayed to the user.
446 * where to start walking in the daemon list
449 * the specific command to execute
451 static void vtysh_client_config(struct vtysh_client
*head_client
, char *line
)
453 /* watchfrr currently doesn't load any config, and has some hardcoded
454 * settings that show up in "show run". skip it here (for now at
455 * least) so we don't get that mangled up in config-write.
457 if (head_client
->flag
== VTYSH_WATCHFRR
)
460 /* suppress output to user */
461 vty
->of_saved
= vty
->of
;
463 vtysh_client_run_all(head_client
, line
, 1, vtysh_config_parse_line
,
465 vty
->of
= vty
->of_saved
;
468 /* Command execution over the vty interface. */
469 static int vtysh_execute_func(const char *line
, int pager
)
474 const struct cmd_element
*cmd
;
476 int saved_ret
, saved_node
;
478 /* Split readline string up into the vector. */
479 vline
= cmd_make_strvec(line
);
484 if (vtysh_add_timestamp
&& strncmp(line
, "exit", 4)) {
487 (void)frr_timestamp(3, ts
, sizeof(ts
));
488 vty_out(vty
, "%% %s\n\n", ts
);
491 saved_ret
= ret
= cmd_execute(vty
, line
, &cmd
, 1);
492 saved_node
= vty
->node
;
495 * If command doesn't succeeded in current node, try to walk up in node
496 * tree. Changing vty->node is enough to try it just out without actual
497 * walkup in the vtysh.
499 while (ret
!= CMD_SUCCESS
&& ret
!= CMD_SUCCESS_DAEMON
500 && ret
!= CMD_WARNING
&& ret
!= CMD_WARNING_CONFIG_FAILED
501 && ret
!= CMD_ERR_AMBIGUOUS
&& ret
!= CMD_ERR_INCOMPLETE
502 && vty
->node
> CONFIG_NODE
) {
503 vty
->node
= node_parent(vty
->node
);
504 ret
= cmd_execute(vty
, line
, &cmd
, 1);
508 vty
->node
= saved_node
;
511 * If command succeeded in any other node than current (tried > 0) we
512 * have to move into node in the vtysh where it succeeded.
514 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
515 || ret
== CMD_WARNING
) {
517 vtysh_execute("exit");
520 * If command didn't succeed in any node, continue with return value
527 cmd_free_strvec(vline
);
532 case CMD_WARNING_CONFIG_FAILED
:
533 if (vty
->type
== VTY_FILE
)
534 vty_out(vty
, "Warning...\n");
536 case CMD_ERR_AMBIGUOUS
:
537 vty_out(vty
, "%% Ambiguous command: %s\n", line
);
539 case CMD_ERR_NO_MATCH
:
540 vty_out(vty
, "%% Unknown command: %s\n", line
);
542 case CMD_ERR_INCOMPLETE
:
543 vty_out(vty
, "%% Command incomplete: %s\n", line
);
545 case CMD_SUCCESS_DAEMON
: {
547 * FIXME: Don't open pager for exit commands. popen() causes
548 * problems if exited from vtysh at all. This hack shouldn't
549 * cause any problem but is really ugly.
551 if (pager
&& strncmp(line
, "exit", 4))
554 if (!strcmp(cmd
->string
, "configure")) {
555 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
556 cmd_stat
= vtysh_client_execute(
557 &vtysh_client
[i
], line
);
558 if (cmd_stat
== CMD_WARNING
)
564 vline
= cmd_make_strvec(line
);
569 vty_close_pager(vty
);
573 ret
= cmd_execute_command(vline
, vty
, &cmd
, 1);
574 cmd_free_strvec(vline
);
575 if (ret
!= CMD_SUCCESS_DAEMON
)
577 } else if (cmd
->func
) {
578 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
583 cmd_stat
= CMD_SUCCESS
;
584 struct vtysh_client
*vc
;
585 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
586 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
587 if (vtysh_client
[i
].fd
< 0
588 && (cmd
->daemon
== vtysh_client
[i
].flag
)) {
589 for (vc
= &vtysh_client
[i
]; vc
;
591 if (vc
->fd
== VTYSH_WAS_ACTIVE
)
594 if (vtysh_client
[i
].fd
< 0
595 && (cmd
->daemon
== vtysh_client
[i
].flag
)) {
596 bool any_inst
= false;
597 for (vc
= &vtysh_client
[i
]; vc
;
603 "%s is not running\n",
604 vtysh_client
[i
].name
);
605 cmd_stat
= CMD_ERR_NO_DAEMON
;
609 cmd_stat
= vtysh_client_execute(
610 &vtysh_client
[i
], line
);
611 if (cmd_stat
!= CMD_SUCCESS
)
615 if (cmd_stat
!= CMD_SUCCESS
&& cmd_stat
!= CMD_ERR_NO_DAEMON
)
619 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
623 vty_close_pager(vty
);
628 int vtysh_execute_no_pager(const char *line
)
630 return vtysh_execute_func(line
, 0);
633 int vtysh_execute(const char *line
)
635 return vtysh_execute_func(line
, 1);
638 static char *trim(char *s
)
649 while (end
>= s
&& isspace((unsigned char)*end
))
653 while (*s
&& isspace((unsigned char)*s
))
659 int vtysh_mark_file(const char *filename
)
666 const struct cmd_element
*cmd
;
667 int saved_ret
, prev_node
;
669 char *vty_buf_copy
= NULL
;
670 char *vty_buf_trimmed
= NULL
;
672 if (strncmp("-", filename
, 1) == 0)
675 confp
= fopen(filename
, "r");
678 fprintf(stderr
, "%% Can't open config file %s due to '%s'.\n",
679 filename
, safe_strerror(errno
));
680 return CMD_ERR_NO_FILE
;
684 vty
->wfd
= STDOUT_FILENO
;
685 vty
->type
= VTY_TERM
;
686 vty
->node
= CONFIG_NODE
;
688 vtysh_execute_no_pager("enable");
689 vtysh_execute_no_pager("configure");
690 vty_buf_copy
= XCALLOC(MTYPE_VTYSH_CMD
, VTY_BUFSIZ
);
692 while (fgets(vty
->buf
, VTY_BUFSIZ
, confp
)) {
695 strlcpy(vty_buf_copy
, vty
->buf
, VTY_BUFSIZ
);
696 vty_buf_trimmed
= trim(vty_buf_copy
);
698 if (vty_buf_trimmed
[0] == '!' || vty_buf_trimmed
[0] == '#') {
699 vty_out(vty
, "%s", vty
->buf
);
703 /* Split readline string up into the vector. */
704 vline
= cmd_make_strvec(vty
->buf
);
707 vty_out(vty
, "%s", vty
->buf
);
712 * Ignore the "end" lines, we will generate these where
715 if (strlen(vty_buf_trimmed
) == 3
716 && strncmp("end", vty_buf_trimmed
, 3) == 0) {
717 cmd_free_strvec(vline
);
721 prev_node
= vty
->node
;
722 saved_ret
= ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
725 * If command doesn't succeeded in current node, try to walk up
726 * in node tree. Changing vty->node is enough to try it just
727 * out without actual walkup in the vtysh.
729 while (ret
!= CMD_SUCCESS
&& ret
!= CMD_SUCCESS_DAEMON
730 && ret
!= CMD_WARNING
&& ret
!= CMD_WARNING_CONFIG_FAILED
731 && ret
!= CMD_ERR_AMBIGUOUS
&& ret
!= CMD_ERR_INCOMPLETE
732 && vty
->node
> CONFIG_NODE
) {
733 vty
->node
= node_parent(vty
->node
);
734 ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
739 * If command succeeded in any other node than current (tried >
740 * 0) we have to move into node in the vtysh where it
743 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
744 || ret
== CMD_WARNING
) {
746 vty_out(vty
, "exit\n");
749 * If command didn't succeed in any node, continue with return
750 * value from first try.
754 vty
->node
= prev_node
;
757 cmd_free_strvec(vline
);
760 case CMD_WARNING_CONFIG_FAILED
:
761 if (vty
->type
== VTY_FILE
)
762 fprintf(stderr
, "line %d: Warning...: %s\n",
766 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
768 case CMD_ERR_AMBIGUOUS
:
769 fprintf(stderr
, "line %d: %% Ambiguous command: %s\n",
773 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
774 return CMD_ERR_AMBIGUOUS
;
775 case CMD_ERR_NO_MATCH
:
776 fprintf(stderr
, "line %d: %% Unknown command: %s\n",
780 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
781 return CMD_ERR_NO_MATCH
;
782 case CMD_ERR_INCOMPLETE
:
783 fprintf(stderr
, "line %d: %% Command incomplete: %s\n",
787 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
788 return CMD_ERR_INCOMPLETE
;
790 vty_out(vty
, "%s", vty
->buf
);
791 if (strmatch(vty_buf_trimmed
, "exit-vrf"))
792 vty_out(vty
, "end\n");
794 case CMD_SUCCESS_DAEMON
: {
797 vty_out(vty
, "%s", vty
->buf
);
798 if (strmatch(vty_buf_trimmed
, "exit-vrf"))
799 vty_out(vty
, "end\n");
800 cmd_stat
= vtysh_client_execute(&vtysh_client
[0],
802 if (cmd_stat
!= CMD_SUCCESS
)
806 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
810 /* This is the end */
811 vty_out(vty
, "\nend\n");
813 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
821 /* Configration make from file. */
822 int vtysh_config_from_file(struct vty
*vty
, FILE *fp
)
825 const struct cmd_element
*cmd
;
827 /* once we have an error, we remember & return that */
828 int retcode
= CMD_SUCCESS
;
830 while (fgets(vty
->buf
, VTY_BUFSIZ
, fp
)) {
833 ret
= command_config_read_one_line(vty
, &cmd
, lineno
, 1);
837 case CMD_WARNING_CONFIG_FAILED
:
838 if (vty
->type
== VTY_FILE
)
839 fprintf(stderr
, "line %d: Warning[%d]...: %s\n",
840 lineno
, vty
->node
, vty
->buf
);
844 case CMD_ERR_AMBIGUOUS
:
846 "line %d: %% Ambiguous command[%d]: %s\n",
847 lineno
, vty
->node
, vty
->buf
);
848 retcode
= CMD_ERR_AMBIGUOUS
;
850 case CMD_ERR_NO_MATCH
:
851 fprintf(stderr
, "line %d: %% Unknown command[%d]: %s",
852 lineno
, vty
->node
, vty
->buf
);
853 retcode
= CMD_ERR_NO_MATCH
;
855 case CMD_ERR_INCOMPLETE
:
857 "line %d: %% Command incomplete[%d]: %s\n",
858 lineno
, vty
->node
, vty
->buf
);
859 retcode
= CMD_ERR_INCOMPLETE
;
861 case CMD_SUCCESS_DAEMON
: {
863 int cmd_stat
= CMD_SUCCESS
;
865 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
866 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
867 cmd_stat
= vtysh_client_execute(
868 &vtysh_client
[i
], vty
->buf
);
870 * CMD_WARNING - Can mean that the
871 * command was parsed successfully but
872 * it was already entered in a few
873 * spots. As such if we receive a
874 * CMD_WARNING from a daemon we
875 * shouldn't stop talking to the other
876 * daemons for the particular command.
878 if (cmd_stat
!= CMD_SUCCESS
879 && cmd_stat
!= CMD_WARNING
) {
881 "line %d: Failure to communicate[%d] to %s, line: %s\n",
883 vtysh_client
[i
].name
,
890 if (cmd_stat
!= CMD_SUCCESS
)
894 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
903 * Function processes cli commands terminated with '?' character when entered
904 * through either 'vtysh' or 'vtysh -c' interfaces.
906 static int vtysh_process_questionmark(const char *input
, int input_len
)
910 vector vline
, describe
;
911 struct cmd_token
*token
;
916 vline
= cmd_make_strvec(input
);
918 /* In case of '> ?'. */
920 vline
= vector_init(1);
921 vector_set(vline
, NULL
);
922 } else if (input_len
&& isspace((unsigned char)input
[input_len
- 1]))
923 vector_set(vline
, NULL
);
925 describe
= cmd_describe_command(vline
, vty
, &ret
);
927 /* Ambiguous and no match error. */
929 case CMD_ERR_AMBIGUOUS
:
930 cmd_free_strvec(vline
);
931 vector_free(describe
);
932 vty_out(vty
, "%% Ambiguous command.\n");
935 case CMD_ERR_NO_MATCH
:
936 cmd_free_strvec(vline
);
938 vector_free(describe
);
939 vty_out(vty
, "%% There is no matched command.\n");
944 /* Get width of command string. */
946 for (i
= 0; i
< vector_active(describe
); i
++)
947 if ((token
= vector_slot(describe
, i
)) != NULL
) {
948 if (token
->text
[0] == '\0')
951 int len
= strlen(token
->text
);
957 for (i
= 0; i
< vector_active(describe
); i
++)
958 if ((token
= vector_slot(describe
, i
)) != NULL
) {
960 vty_out(vty
, " %-s\n", token
->text
);
962 vty_out(vty
, " %-*s %s\n", width
, token
->text
,
965 if (IS_VARYING_TOKEN(token
->type
)) {
966 const char *ref
= vector_slot(
967 vline
, vector_active(vline
) - 1);
969 vector varcomps
= vector_init(VECTOR_MIN_SIZE
);
970 cmd_variable_complete(token
, ref
, varcomps
);
972 if (vector_active(varcomps
) > 0) {
974 rl_get_screen_size(&rows
, &cols
);
976 char *ac
= cmd_variable_comp2str(
978 vty_out(vty
, "%s\n", ac
);
979 XFREE(MTYPE_TMP
, ac
);
982 vector_free(varcomps
);
986 cmd_free_strvec(vline
);
987 vector_free(describe
);
993 * Entry point for user commands terminated with '?' character and typed through
994 * the usual vtysh's stdin interface. This is the function being registered with
997 static int vtysh_rl_describe(int a
, int b
)
1003 ret
= vtysh_process_questionmark(rl_line_buffer
, rl_end
);
1010 * Function in charged of processing vtysh instructions terminating with '?'
1011 * character and received through the 'vtysh -c' interface. If user's
1012 * instruction is well-formatted, we will call the same processing routine
1013 * utilized by the traditional vtysh's stdin interface.
1015 int vtysh_execute_command_questionmark(char *input
)
1017 int input_len
, qmark_count
= 0;
1020 if (!(input
&& *input
))
1023 /* Finding out question_mark count and strlen */
1024 for (str
= input
; *str
; ++str
) {
1028 input_len
= str
- input
;
1031 * Verify that user's input terminates in '?' and that patterns such as
1032 * 'cmd ? subcmd ?' are prevented.
1034 if (qmark_count
!= 1 || input
[input_len
- 1] != '?')
1038 * Questionmark-processing function is not expecting to receive '?'
1039 * character in input string.
1041 input
[input_len
- 1] = '\0';
1043 return vtysh_process_questionmark(input
, input_len
- 1);
1046 /* Result of cmd_complete_command() call will be stored here
1047 * and used in new_completion() in order to put the space in
1048 * correct places only. */
1049 int complete_status
;
1051 static char *command_generator(const char *text
, int state
)
1054 static char **matched
= NULL
;
1055 static int index
= 0;
1061 if (vty
->node
== AUTH_NODE
|| vty
->node
== AUTH_ENABLE_NODE
)
1064 vline
= cmd_make_strvec(rl_line_buffer
);
1069 isspace((unsigned char)rl_line_buffer
[rl_end
- 1]))
1070 vector_set(vline
, NULL
);
1072 matched
= cmd_complete_command(vline
, vty
, &complete_status
);
1073 cmd_free_strvec(vline
);
1076 if (matched
&& matched
[index
]) {
1077 XCOUNTFREE(MTYPE_COMPLETION
, matched
[index
]);
1078 return matched
[index
++];
1081 XFREE(MTYPE_TMP
, matched
);
1086 static char **new_completion(const char *text
, int start
, int end
)
1090 matches
= rl_completion_matches(text
, command_generator
);
1094 if (complete_status
!= CMD_COMPLETE_FULL_MATCH
)
1095 /* only append a space on full match */
1096 rl_completion_append_character
= '\0';
1102 /* Vty node structures. */
1104 static struct cmd_node bgp_node
= {
1107 .parent_node
= CONFIG_NODE
,
1108 .prompt
= "%s(config-router)# ",
1110 #endif /* HAVE_BGPD */
1112 static struct cmd_node rip_node
= {
1115 .parent_node
= CONFIG_NODE
,
1116 .prompt
= "%s(config-router)# ",
1120 static struct cmd_node isis_node
= {
1123 .parent_node
= CONFIG_NODE
,
1124 .prompt
= "%s(config-router)# ",
1126 #endif /* HAVE_ISISD */
1129 static struct cmd_node openfabric_node
= {
1130 .name
= "openfabric",
1131 .node
= OPENFABRIC_NODE
,
1132 .parent_node
= CONFIG_NODE
,
1133 .prompt
= "%s(config-router)# ",
1135 #endif /* HAVE_FABRICD */
1137 static struct cmd_node interface_node
= {
1138 .name
= "interface",
1139 .node
= INTERFACE_NODE
,
1140 .parent_node
= CONFIG_NODE
,
1141 .prompt
= "%s(config-if)# ",
1144 static struct cmd_node pw_node
= {
1147 .parent_node
= CONFIG_NODE
,
1148 .prompt
= "%s(config-pw)# ",
1151 static struct cmd_node segment_routing_node
= {
1152 .name
= "segment-routing",
1153 .node
= SEGMENT_ROUTING_NODE
,
1154 .parent_node
= CONFIG_NODE
,
1155 .prompt
= "%s(config-sr)# ",
1158 #if defined(HAVE_PATHD)
1159 static struct cmd_node sr_traffic_eng_node
= {
1160 .name
= "sr traffic-eng",
1161 .node
= SR_TRAFFIC_ENG_NODE
,
1162 .parent_node
= SEGMENT_ROUTING_NODE
,
1163 .prompt
= "%s(config-sr-te)# ",
1166 static struct cmd_node srte_segment_list_node
= {
1167 .name
= "srte segment-list",
1168 .node
= SR_SEGMENT_LIST_NODE
,
1169 .parent_node
= SR_TRAFFIC_ENG_NODE
,
1170 .prompt
= "%s(config-sr-te-segment-list)# ",
1173 static struct cmd_node srte_policy_node
= {
1174 .name
= "srte policy",
1175 .node
= SR_POLICY_NODE
,
1176 .parent_node
= SR_TRAFFIC_ENG_NODE
,
1177 .prompt
= "%s(config-sr-te-policy)# ",
1180 static struct cmd_node srte_candidate_dyn_node
= {
1181 .name
= "srte candidate-dyn",
1182 .node
= SR_CANDIDATE_DYN_NODE
,
1183 .parent_node
= SR_POLICY_NODE
,
1184 .prompt
= "%s(config-sr-te-candidate)# ",
1187 static struct cmd_node pcep_node
= {
1188 .name
= "srte pcep",
1190 .parent_node
= SR_TRAFFIC_ENG_NODE
,
1191 .prompt
= "%s(config-sr-te-pcep)# "
1194 static struct cmd_node pcep_pcc_node
= {
1195 .name
= "srte pcep pcc",
1196 .node
= PCEP_PCC_NODE
,
1197 .parent_node
= PCEP_NODE
,
1198 .prompt
= "%s(config-sr-te-pcep-pcc)# ",
1201 static struct cmd_node pcep_pce_node
= {
1202 .name
= "srte pcep pce-peer",
1203 .node
= PCEP_PCE_NODE
,
1204 .parent_node
= PCEP_NODE
,
1205 .prompt
= "%s(config-sr-te-pcep-pce-peer)# ",
1208 static struct cmd_node pcep_pce_config_node
= {
1209 .name
= "srte pcep pce-config",
1210 .node
= PCEP_PCE_CONFIG_NODE
,
1211 .parent_node
= PCEP_NODE
,
1212 .prompt
= "%s(pcep-sr-te-pcep-pce-config)# ",
1214 #endif /* HAVE_PATHD */
1216 static struct cmd_node vrf_node
= {
1219 .parent_node
= CONFIG_NODE
,
1220 .prompt
= "%s(config-vrf)# ",
1223 static struct cmd_node nh_group_node
= {
1224 .name
= "nexthop-group",
1225 .node
= NH_GROUP_NODE
,
1226 .parent_node
= CONFIG_NODE
,
1227 .prompt
= "%s(config-nh-group)# ",
1230 static struct cmd_node rmap_node
= {
1233 .parent_node
= CONFIG_NODE
,
1234 .prompt
= "%s(config-route-map)# ",
1237 static struct cmd_node srv6_node
= {
1240 .parent_node
= SEGMENT_ROUTING_NODE
,
1241 .prompt
= "%s(config-srv6)# ",
1244 static struct cmd_node srv6_locs_node
= {
1245 .name
= "srv6-locators",
1246 .node
= SRV6_LOCS_NODE
,
1247 .parent_node
= SRV6_NODE
,
1248 .prompt
= "%s(config-srv6-locators)# ",
1251 static struct cmd_node srv6_loc_node
= {
1252 .name
= "srv6-locator",
1253 .node
= SRV6_LOC_NODE
,
1254 .parent_node
= SRV6_LOCS_NODE
,
1255 .prompt
= "%s(config-srv6-locator)# ",
1259 static struct cmd_node pbr_map_node
= {
1261 .node
= PBRMAP_NODE
,
1262 .parent_node
= CONFIG_NODE
,
1263 .prompt
= "%s(config-pbr-map)# ",
1265 #endif /* HAVE_PBRD */
1267 static struct cmd_node zebra_node
= {
1270 .parent_node
= CONFIG_NODE
,
1271 .prompt
= "%s(config-router)# ",
1275 static struct cmd_node bgp_vpnv4_node
= {
1276 .name
= "bgp vpnv4",
1277 .node
= BGP_VPNV4_NODE
,
1278 .parent_node
= BGP_NODE
,
1279 .prompt
= "%s(config-router-af)# ",
1283 static struct cmd_node bgp_vpnv6_node
= {
1284 .name
= "bgp vpnv6",
1285 .node
= BGP_VPNV6_NODE
,
1286 .parent_node
= BGP_NODE
,
1287 .prompt
= "%s(config-router-af)# ",
1291 static struct cmd_node bgp_flowspecv4_node
= {
1292 .name
= "bgp ipv4 flowspec",
1293 .node
= BGP_FLOWSPECV4_NODE
,
1294 .parent_node
= BGP_NODE
,
1295 .prompt
= "%s(config-router-af)# ",
1299 static struct cmd_node bgp_flowspecv6_node
= {
1300 .name
= "bgp ipv6 flowspec",
1301 .node
= BGP_FLOWSPECV6_NODE
,
1302 .parent_node
= BGP_NODE
,
1303 .prompt
= "%s(config-router-af)# ",
1307 static struct cmd_node bgp_ipv4_node
= {
1308 .name
= "bgp ipv4 unicast",
1309 .node
= BGP_IPV4_NODE
,
1310 .parent_node
= BGP_NODE
,
1311 .prompt
= "%s(config-router-af)# ",
1315 static struct cmd_node bgp_ipv4m_node
= {
1316 .name
= "bgp ipv4 multicast",
1317 .node
= BGP_IPV4M_NODE
,
1318 .parent_node
= BGP_NODE
,
1319 .prompt
= "%s(config-router-af)# ",
1323 static struct cmd_node bgp_ipv4l_node
= {
1324 .name
= "bgp ipv4 labeled unicast",
1325 .node
= BGP_IPV4L_NODE
,
1326 .parent_node
= BGP_NODE
,
1327 .prompt
= "%s(config-router-af)# ",
1331 static struct cmd_node bgp_ipv6_node
= {
1333 .node
= BGP_IPV6_NODE
,
1334 .parent_node
= BGP_NODE
,
1335 .prompt
= "%s(config-router-af)# ",
1339 static struct cmd_node bgp_ipv6m_node
= {
1340 .name
= "bgp ipv6 multicast",
1341 .node
= BGP_IPV6M_NODE
,
1342 .parent_node
= BGP_NODE
,
1343 .prompt
= "%s(config-router-af)# ",
1347 static struct cmd_node bgp_evpn_node
= {
1349 .node
= BGP_EVPN_NODE
,
1350 .parent_node
= BGP_NODE
,
1351 .prompt
= "%s(config-router-af)# ",
1355 static struct cmd_node bgp_evpn_vni_node
= {
1356 .name
= "bgp evpn vni",
1357 .node
= BGP_EVPN_VNI_NODE
,
1358 .parent_node
= BGP_EVPN_NODE
,
1359 .prompt
= "%s(config-router-af-vni)# ",
1362 static struct cmd_node bgp_ipv6l_node
= {
1363 .name
= "bgp ipv6 labeled unicast",
1364 .node
= BGP_IPV6L_NODE
,
1365 .parent_node
= BGP_NODE
,
1366 .prompt
= "%s(config-router-af)# ",
1370 #ifdef ENABLE_BGP_VNC
1371 static struct cmd_node bgp_vnc_defaults_node
= {
1372 .name
= "bgp vnc defaults",
1373 .node
= BGP_VNC_DEFAULTS_NODE
,
1374 .parent_node
= BGP_NODE
,
1375 .prompt
= "%s(config-router-vnc-defaults)# ",
1378 static struct cmd_node bgp_vnc_nve_group_node
= {
1379 .name
= "bgp vnc nve",
1380 .node
= BGP_VNC_NVE_GROUP_NODE
,
1381 .parent_node
= BGP_NODE
,
1382 .prompt
= "%s(config-router-vnc-nve-group)# ",
1385 static struct cmd_node bgp_vrf_policy_node
= {
1386 .name
= "bgp vrf policy",
1387 .node
= BGP_VRF_POLICY_NODE
,
1388 .parent_node
= BGP_NODE
,
1389 .prompt
= "%s(config-router-vrf-policy)# ",
1392 static struct cmd_node bgp_vnc_l2_group_node
= {
1393 .name
= "bgp vnc l2",
1394 .node
= BGP_VNC_L2_GROUP_NODE
,
1395 .parent_node
= BGP_NODE
,
1396 .prompt
= "%s(config-router-vnc-l2-group)# ",
1398 #endif /* ENABLE_BGP_VNC */
1400 static struct cmd_node bmp_node
= {
1403 .parent_node
= BGP_NODE
,
1404 .prompt
= "%s(config-bgp-bmp)# "
1407 static struct cmd_node bgp_srv6_node
= {
1409 .node
= BGP_SRV6_NODE
,
1410 .parent_node
= BGP_NODE
,
1411 .prompt
= "%s(config-router-srv6)# ",
1413 #endif /* HAVE_BGPD */
1416 static struct cmd_node ospf_node
= {
1419 .parent_node
= CONFIG_NODE
,
1420 .prompt
= "%s(config-router)# ",
1422 #endif /* HAVE_OSPFD */
1425 static struct cmd_node eigrp_node
= {
1428 .parent_node
= CONFIG_NODE
,
1429 .prompt
= "%s(config-router)# ",
1431 #endif /* HAVE_EIGRPD */
1434 static struct cmd_node babel_node
= {
1437 .parent_node
= CONFIG_NODE
,
1438 .prompt
= "%s(config-router)# ",
1440 #endif /* HAVE_BABELD */
1442 static struct cmd_node ripng_node
= {
1445 .parent_node
= CONFIG_NODE
,
1446 .prompt
= "%s(config-router)# ",
1450 static struct cmd_node ospf6_node
= {
1453 .parent_node
= CONFIG_NODE
,
1454 .prompt
= "%s(config-ospf6)# ",
1456 #endif /* HAVE_OSPF6D */
1459 static struct cmd_node ldp_node
= {
1462 .parent_node
= CONFIG_NODE
,
1463 .prompt
= "%s(config-ldp)# ",
1466 static struct cmd_node ldp_ipv4_node
= {
1468 .node
= LDP_IPV4_NODE
,
1469 .parent_node
= LDP_NODE
,
1470 .prompt
= "%s(config-ldp-af)# ",
1473 static struct cmd_node ldp_ipv6_node
= {
1475 .node
= LDP_IPV6_NODE
,
1476 .parent_node
= LDP_NODE
,
1477 .prompt
= "%s(config-ldp-af)# ",
1480 static struct cmd_node ldp_ipv4_iface_node
= {
1481 .name
= "ldp ipv4 interface",
1482 .node
= LDP_IPV4_IFACE_NODE
,
1483 .parent_node
= LDP_IPV4_NODE
,
1484 .prompt
= "%s(config-ldp-af-if)# ",
1487 static struct cmd_node ldp_ipv6_iface_node
= {
1488 .name
= "ldp ipv6 interface",
1489 .node
= LDP_IPV6_IFACE_NODE
,
1490 .parent_node
= LDP_IPV6_NODE
,
1491 .prompt
= "%s(config-ldp-af-if)# ",
1494 static struct cmd_node ldp_l2vpn_node
= {
1495 .name
= "ldp l2vpn",
1496 .node
= LDP_L2VPN_NODE
,
1497 .parent_node
= CONFIG_NODE
,
1498 .prompt
= "%s(config-l2vpn)# ",
1501 static struct cmd_node ldp_pseudowire_node
= {
1503 .node
= LDP_PSEUDOWIRE_NODE
,
1504 .parent_node
= LDP_L2VPN_NODE
,
1505 .prompt
= "%s(config-l2vpn-pw)# ",
1507 #endif /* HAVE_LDPD */
1509 static struct cmd_node keychain_node
= {
1511 .node
= KEYCHAIN_NODE
,
1512 .parent_node
= CONFIG_NODE
,
1513 .prompt
= "%s(config-keychain)# ",
1516 static struct cmd_node keychain_key_node
= {
1517 .name
= "keychain key",
1518 .node
= KEYCHAIN_KEY_NODE
,
1519 .parent_node
= KEYCHAIN_NODE
,
1520 .prompt
= "%s(config-keychain-key)# ",
1523 struct cmd_node link_params_node
= {
1524 .name
= "link-params",
1525 .node
= LINK_PARAMS_NODE
,
1526 .parent_node
= INTERFACE_NODE
,
1527 .prompt
= "%s(config-link-params)# ",
1532 static struct cmd_node rpki_node
= {
1535 .parent_node
= CONFIG_NODE
,
1536 .prompt
= "%s(config-rpki)# ",
1538 #endif /* HAVE_BGPD */
1541 static struct cmd_node bfd_node
= {
1544 .parent_node
= CONFIG_NODE
,
1545 .prompt
= "%s(config-bfd)# ",
1548 static struct cmd_node bfd_peer_node
= {
1550 .node
= BFD_PEER_NODE
,
1551 .parent_node
= BFD_NODE
,
1552 .prompt
= "%s(config-bfd-peer)# ",
1555 static struct cmd_node bfd_profile_node
= {
1556 .name
= "bfd profile",
1557 .node
= BFD_PROFILE_NODE
,
1558 .parent_node
= BFD_NODE
,
1559 .prompt
= "%s(config-bfd-profile)# ",
1561 #endif /* HAVE_BFDD */
1563 /* Defined in lib/vty.c */
1564 extern struct cmd_node vty_node
;
1566 /* When '^Z' is received from vty, move down to the enable mode. */
1567 static int vtysh_end(void)
1569 switch (vty
->node
) {
1572 /* Nothing to do. */
1575 vty
->node
= ENABLE_NODE
;
1581 DEFUNSH(VTYSH_REALLYALL
, vtysh_end_all
, vtysh_end_all_cmd
, "end",
1582 "End current mode and change to enable mode\n")
1587 DEFUNSH(VTYSH_ZEBRA
, srv6
, srv6_cmd
,
1589 "Segment-Routing SRv6 configration\n")
1591 vty
->node
= SRV6_NODE
;
1595 DEFUNSH(VTYSH_ZEBRA
, srv6_locators
, srv6_locators_cmd
,
1597 "Segment-Routing SRv6 locators configration\n")
1599 vty
->node
= SRV6_LOCS_NODE
;
1603 DEFUNSH(VTYSH_ZEBRA
, srv6_locator
, srv6_locator_cmd
,
1605 "Segment Routing SRv6 locator\n"
1606 "Specify locator-name\n")
1608 vty
->node
= SRV6_LOC_NODE
;
1613 DEFUNSH(VTYSH_BGPD
, router_bgp
, router_bgp_cmd
,
1614 "router bgp [(1-4294967295) [<view|vrf> WORD]]",
1615 ROUTER_STR BGP_STR AS_STR
1616 "BGP view\nBGP VRF\n"
1619 vty
->node
= BGP_NODE
;
1623 #ifdef KEEP_OLD_VPN_COMMANDS
1624 DEFUNSH(VTYSH_BGPD
, address_family_vpnv4
, address_family_vpnv4_cmd
,
1625 "address-family vpnv4 [unicast]",
1626 "Enter Address Family command mode\n"
1628 "Address Family modifier\n")
1630 vty
->node
= BGP_VPNV4_NODE
;
1634 DEFUNSH(VTYSH_BGPD
, address_family_vpnv6
, address_family_vpnv6_cmd
,
1635 "address-family vpnv6 [unicast]",
1636 "Enter Address Family command mode\n"
1638 "Address Family modifier\n")
1640 vty
->node
= BGP_VPNV6_NODE
;
1643 #endif /* KEEP_OLD_VPN_COMMANDS */
1645 DEFUNSH(VTYSH_BGPD
, address_family_ipv4
, address_family_ipv4_cmd
,
1646 "address-family ipv4 [unicast]",
1647 "Enter Address Family command mode\n"
1649 "Address Family Modifier\n")
1651 vty
->node
= BGP_IPV4_NODE
;
1655 DEFUNSH(VTYSH_BGPD
, address_family_flowspecv4
, address_family_flowspecv4_cmd
,
1656 "address-family ipv4 flowspec",
1657 "Enter Address Family command mode\n"
1659 "Address Family Modifier\n")
1661 vty
->node
= BGP_FLOWSPECV4_NODE
;
1665 DEFUNSH(VTYSH_BGPD
, address_family_flowspecv6
, address_family_flowspecv6_cmd
,
1666 "address-family ipv6 flowspec",
1667 "Enter Address Family command mode\n"
1669 "Address Family Modifier\n")
1671 vty
->node
= BGP_FLOWSPECV6_NODE
;
1675 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_multicast
,
1676 address_family_ipv4_multicast_cmd
, "address-family ipv4 multicast",
1677 "Enter Address Family command mode\n"
1679 "Address Family modifier\n")
1681 vty
->node
= BGP_IPV4M_NODE
;
1685 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_vpn
, address_family_ipv4_vpn_cmd
,
1686 "address-family ipv4 vpn",
1687 "Enter Address Family command mode\n"
1689 "Address Family modifier\n")
1691 vty
->node
= BGP_VPNV4_NODE
;
1695 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_labeled_unicast
,
1696 address_family_ipv4_labeled_unicast_cmd
,
1697 "address-family ipv4 labeled-unicast",
1698 "Enter Address Family command mode\n"
1700 "Address Family modifier\n")
1702 vty
->node
= BGP_IPV4L_NODE
;
1706 DEFUNSH(VTYSH_BGPD
, address_family_ipv6
, address_family_ipv6_cmd
,
1707 "address-family ipv6 [unicast]",
1708 "Enter Address Family command mode\n"
1710 "Address Family modifier\n")
1712 vty
->node
= BGP_IPV6_NODE
;
1716 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_multicast
,
1717 address_family_ipv6_multicast_cmd
, "address-family ipv6 multicast",
1718 "Enter Address Family command mode\n"
1720 "Address Family modifier\n")
1722 vty
->node
= BGP_IPV6M_NODE
;
1726 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_vpn
, address_family_ipv6_vpn_cmd
,
1727 "address-family ipv6 vpn",
1728 "Enter Address Family command mode\n"
1730 "Address Family modifier\n")
1732 vty
->node
= BGP_VPNV6_NODE
;
1736 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_labeled_unicast
,
1737 address_family_ipv6_labeled_unicast_cmd
,
1738 "address-family ipv6 labeled-unicast",
1739 "Enter Address Family command mode\n"
1741 "Address Family modifier\n")
1743 vty
->node
= BGP_IPV6L_NODE
;
1751 "Enable rpki and enter rpki configuration mode\n")
1753 vty
->node
= RPKI_NODE
;
1760 "bmp targets BMPTARGETS",
1761 "BGP Monitoring Protocol\n"
1762 "Create BMP target group\n"
1763 "Name of the BMP target group\n")
1765 vty
->node
= BMP_NODE
;
1772 "segment-routing srv6",
1773 "Segment-Routing configuration\n"
1774 "Segment-Routing SRv6 configuration\n")
1776 vty
->node
= BGP_SRV6_NODE
;
1784 "exit Segment-Routing SRv6 configuration\n")
1786 if (vty
->node
== BGP_SRV6_NODE
)
1787 vty
->node
= BGP_NODE
;
1795 "quit Segment-Routing SRv6 configuration\n")
1797 if (vty
->node
== BGP_SRV6_NODE
)
1798 vty
->node
= BGP_NODE
;
1802 DEFUNSH(VTYSH_BGPD
, address_family_evpn
, address_family_evpn_cmd
,
1803 "address-family <l2vpn evpn>",
1804 "Enter Address Family command mode\n"
1806 "Address Family modifier\n")
1808 vty
->node
= BGP_EVPN_NODE
;
1812 DEFUNSH(VTYSH_BGPD
, bgp_evpn_vni
, bgp_evpn_vni_cmd
, "vni " CMD_VNI_RANGE
,
1813 "VXLAN Network Identifier\n"
1816 vty
->node
= BGP_EVPN_VNI_NODE
;
1820 #if defined(ENABLE_BGP_VNC)
1821 DEFUNSH(VTYSH_BGPD
, vnc_defaults
, vnc_defaults_cmd
, "vnc defaults",
1822 "VNC/RFP related configuration\n"
1823 "Configure default NVE group\n")
1825 vty
->node
= BGP_VNC_DEFAULTS_NODE
;
1829 DEFUNSH(VTYSH_BGPD
, vnc_nve_group
, vnc_nve_group_cmd
, "vnc nve-group NAME",
1830 "VNC/RFP related configuration\n"
1831 "Configure a NVE group\n"
1834 vty
->node
= BGP_VNC_NVE_GROUP_NODE
;
1838 DEFUNSH(VTYSH_BGPD
, vnc_vrf_policy
, vnc_vrf_policy_cmd
, "vrf-policy NAME",
1839 "Configure a VRF policy group\n"
1842 vty
->node
= BGP_VRF_POLICY_NODE
;
1846 DEFUNSH(VTYSH_BGPD
, vnc_l2_group
, vnc_l2_group_cmd
, "vnc l2-group NAME",
1847 "VNC/RFP related configuration\n"
1848 "Configure a L2 group\n"
1851 vty
->node
= BGP_VNC_L2_GROUP_NODE
;
1855 DEFUNSH(VTYSH_BGPD
, exit_vnc_config
, exit_vnc_config_cmd
, "exit-vnc",
1856 "Exit from VNC configuration mode\n")
1858 if (vty
->node
== BGP_VNC_DEFAULTS_NODE
1859 || vty
->node
== BGP_VNC_NVE_GROUP_NODE
1860 || vty
->node
== BGP_VNC_L2_GROUP_NODE
)
1861 vty
->node
= BGP_NODE
;
1865 DEFUNSH(VTYSH_BGPD
, exit_vrf_policy
, exit_vrf_policy_cmd
, "exit-vrf-policy",
1866 "Exit from VRF policy configuration mode\n")
1868 if (vty
->node
== BGP_VRF_POLICY_NODE
)
1869 vty
->node
= BGP_NODE
;
1873 #endif /* HAVE_BGPD */
1875 DEFUNSH(VTYSH_KEYS
, key_chain
, key_chain_cmd
, "key chain WORD",
1876 "Authentication key management\n"
1877 "Key-chain management\n"
1880 vty
->node
= KEYCHAIN_NODE
;
1884 DEFUNSH(VTYSH_KEYS
, key
, key_cmd
, "key (0-2147483647)",
1886 "Key identifier number\n")
1888 vty
->node
= KEYCHAIN_KEY_NODE
;
1893 DEFUNSH(VTYSH_RIPD
, router_rip
, router_rip_cmd
, "router rip [vrf NAME]",
1894 ROUTER_STR
"RIP\n" VRF_CMD_HELP_STR
)
1896 vty
->node
= RIP_NODE
;
1899 #endif /* HAVE_RIPD */
1902 DEFUNSH(VTYSH_RIPNGD
, router_ripng
, router_ripng_cmd
, "router ripng [vrf NAME]",
1903 ROUTER_STR
"RIPng\n" VRF_CMD_HELP_STR
)
1905 vty
->node
= RIPNG_NODE
;
1908 #endif /* HAVE_RIPNGD */
1911 DEFUNSH(VTYSH_OSPFD
, router_ospf
, router_ospf_cmd
,
1912 "router ospf [(1-65535)] [vrf NAME]",
1913 "Enable a routing process\n"
1914 "Start OSPF configuration\n"
1918 vty
->node
= OSPF_NODE
;
1921 #endif /* HAVE_OSPFD */
1924 DEFUNSH(VTYSH_EIGRPD
, router_eigrp
, router_eigrp_cmd
, "router eigrp (1-65535) [vrf NAME]",
1925 "Enable a routing process\n"
1926 "Start EIGRP configuration\n"
1927 "AS number to use\n"
1930 vty
->node
= EIGRP_NODE
;
1933 #endif /* HAVE_EIGRPD */
1936 DEFUNSH(VTYSH_BABELD
, router_babel
, router_babel_cmd
, "router babel",
1937 "Enable a routing process\n"
1938 "Make Babel instance command\n")
1940 vty
->node
= BABEL_NODE
;
1943 #endif /* HAVE_BABELD */
1946 DEFUNSH(VTYSH_OSPF6D
, router_ospf6
, router_ospf6_cmd
, "router ospf6 [vrf NAME]",
1947 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
1949 vty
->node
= OSPF6_NODE
;
1954 #if defined(HAVE_LDPD)
1955 DEFUNSH(VTYSH_LDPD
, ldp_mpls_ldp
, ldp_mpls_ldp_cmd
, "mpls ldp",
1956 "Global MPLS configuration subcommands\n"
1957 "Label Distribution Protocol\n")
1959 vty
->node
= LDP_NODE
;
1963 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv4
, ldp_address_family_ipv4_cmd
,
1964 "address-family ipv4",
1965 "Configure Address Family and its parameters\n"
1968 vty
->node
= LDP_IPV4_NODE
;
1972 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv6
, ldp_address_family_ipv6_cmd
,
1973 "address-family ipv6",
1974 "Configure Address Family and its parameters\n"
1977 vty
->node
= LDP_IPV6_NODE
;
1981 DEFUNSH(VTYSH_LDPD
, ldp_exit_address_family
, ldp_exit_address_family_cmd
,
1982 "exit-address-family", "Exit from Address Family configuration mode\n")
1984 if (vty
->node
== LDP_IPV4_NODE
|| vty
->node
== LDP_IPV6_NODE
)
1985 vty
->node
= LDP_NODE
;
1989 DEFUNSH(VTYSH_LDPD
, ldp_interface_ifname
, ldp_interface_ifname_cmd
,
1991 "Enable LDP on an interface and enter interface submode\n"
1992 "Interface's name\n")
1994 switch (vty
->node
) {
1996 vty
->node
= LDP_IPV4_IFACE_NODE
;
1999 vty
->node
= LDP_IPV6_IFACE_NODE
;
2008 DEFUNSH(VTYSH_LDPD
, ldp_l2vpn_word_type_vpls
, ldp_l2vpn_word_type_vpls_cmd
,
2009 "l2vpn WORD type vpls",
2010 "Configure l2vpn commands\n"
2013 "Virtual Private LAN Service\n")
2015 vty
->node
= LDP_L2VPN_NODE
;
2019 DEFUNSH(VTYSH_LDPD
, ldp_member_pseudowire_ifname
,
2020 ldp_member_pseudowire_ifname_cmd
, "member pseudowire IFNAME",
2021 "L2VPN member configuration\n"
2022 "Pseudowire interface\n"
2023 "Interface's name\n")
2025 vty
->node
= LDP_PSEUDOWIRE_NODE
;
2031 DEFUNSH(VTYSH_ISISD
, router_isis
, router_isis_cmd
,
2032 "router isis WORD [vrf NAME]",
2035 "ISO Routing area tag\n" VRF_CMD_HELP_STR
)
2037 vty
->node
= ISIS_NODE
;
2040 #endif /* HAVE_ISISD */
2043 DEFUNSH(VTYSH_FABRICD
, router_openfabric
, router_openfabric_cmd
, "router openfabric WORD",
2045 "OpenFabric routing protocol\n"
2046 "ISO Routing area tag\n")
2048 vty
->node
= OPENFABRIC_NODE
;
2051 #endif /* HAVE_FABRICD */
2053 DEFUNSH(VTYSH_SR
, segment_routing
, segment_routing_cmd
,
2055 "Configure segment routing\n")
2057 vty
->node
= SEGMENT_ROUTING_NODE
;
2061 #if defined (HAVE_PATHD)
2062 DEFUNSH(VTYSH_PATHD
, sr_traffic_eng
, sr_traffic_eng_cmd
,
2064 "Configure SR traffic engineering\n")
2066 vty
->node
= SR_TRAFFIC_ENG_NODE
;
2070 DEFUNSH(VTYSH_PATHD
, srte_segment_list
, srte_segment_list_cmd
,
2071 "segment-list WORD$name",
2073 "Segment List Name\n")
2075 vty
->node
= SR_SEGMENT_LIST_NODE
;
2079 DEFUNSH(VTYSH_PATHD
, srte_policy
, srte_policy_cmd
,
2080 "policy color (0-4294967295) endpoint <A.B.C.D|X:X::X:X>",
2081 "Segment Routing Policy\n"
2083 "SR Policy color value\n"
2084 "SR Policy endpoint\n"
2085 "SR Policy endpoint IPv4 address\n"
2086 "SR Policy endpoint IPv6 address\n")
2088 vty
->node
= SR_POLICY_NODE
;
2092 DEFUNSH(VTYSH_PATHD
, srte_policy_candidate_dyn_path
,
2093 srte_policy_candidate_dyn_path_cmd
,
2094 "candidate-path preference (0-4294967295) name WORD dynamic",
2095 "Segment Routing Policy Candidate Path\n"
2096 "Segment Routing Policy Candidate Path Preference\n"
2097 "Administrative Preference\n"
2098 "Segment Routing Policy Candidate Path Name\n"
2102 vty
->node
= SR_CANDIDATE_DYN_NODE
;
2106 DEFUNSH(VTYSH_PATHD
, pcep
, pcep_cmd
,
2108 "Configure SR pcep\n")
2110 vty
->node
= PCEP_NODE
;
2114 DEFUNSH(VTYSH_PATHD
, pcep_cli_pcc
, pcep_cli_pcc_cmd
,
2116 "PCC configuration\n")
2118 vty
->node
= PCEP_PCC_NODE
;
2122 DEFUNSH(VTYSH_PATHD
, pcep_cli_pce
, pcep_cli_pce_cmd
,
2124 "PCE configuration\n"
2127 vty
->node
= PCEP_PCE_NODE
;
2131 DEFUNSH(VTYSH_PATHD
, pcep_cli_pcep_pce_config
, pcep_cli_pcep_pce_config_cmd
,
2133 "PCEP peer Configuration Group\n"
2134 "PCEP peer Configuration Group name\n")
2136 vty
->node
= PCEP_PCE_CONFIG_NODE
;
2140 #endif /* HAVE_PATHD */
2142 DEFUNSH(VTYSH_RMAP
, vtysh_route_map
, vtysh_route_map_cmd
,
2143 "route-map RMAP_NAME <deny|permit> (1-65535)",
2144 "Create route-map or enter route-map command mode\n"
2146 "Route map denies set operations\n"
2147 "Route map permits set operations\n"
2148 "Sequence to insert to/delete from existing route-map entry\n")
2150 vty
->node
= RMAP_NODE
;
2155 DEFUNSH(VTYSH_PBRD
, vtysh_pbr_map
, vtysh_pbr_map_cmd
,
2156 "pbr-map PBRMAP seq (1-700)",
2157 "Create pbr-map or enter pbr-map command mode\n"
2158 "The name of the PBR MAP\n"
2159 "Sequence to insert to/delete from existing pbr-map entry\n"
2160 "Sequence number\n")
2162 vty
->node
= PBRMAP_NODE
;
2166 DEFSH(VTYSH_PBRD
, vtysh_no_pbr_map_cmd
, "no pbr-map PBRMAP [seq (1-700)]",
2169 "The name of the PBR MAP\n"
2170 "Sequence to delete from existing pbr-map entry\n"
2171 "Sequence number\n")
2172 #endif /* HAVE_PBRD */
2175 DEFUNSH(VTYSH_BFDD
, bfd_enter
, bfd_enter_cmd
, "bfd", "Configure BFD peers\n")
2177 vty
->node
= BFD_NODE
;
2181 DEFUNSH(VTYSH_BFDD
, bfd_peer_enter
, bfd_peer_enter_cmd
,
2182 "peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
2184 "IPv4 peer address\n"
2185 "IPv6 peer address\n"
2186 "Configure multihop\n"
2187 "Configure local address\n"
2188 "IPv4 local address\n"
2189 "IPv6 local address\n"
2191 "Configure interface name to use\n"
2193 "Configure VRF name\n")
2195 vty
->node
= BFD_PEER_NODE
;
2199 DEFUNSH(VTYSH_BFDD
, bfd_profile_enter
, bfd_profile_enter_cmd
,
2202 BFD_PROFILE_NAME_STR
)
2204 vty
->node
= BFD_PROFILE_NODE
;
2207 #endif /* HAVE_BFDD */
2209 DEFUNSH(VTYSH_ALL
, vtysh_line_vty
, vtysh_line_vty_cmd
, "line vty",
2210 "Configure a terminal line\n"
2211 "Virtual terminal\n")
2213 vty
->node
= VTY_NODE
;
2217 DEFUNSH(VTYSH_REALLYALL
, vtysh_enable
, vtysh_enable_cmd
, "enable",
2218 "Turn on privileged mode command\n")
2220 vty
->node
= ENABLE_NODE
;
2224 DEFUNSH(VTYSH_REALLYALL
, vtysh_disable
, vtysh_disable_cmd
, "disable",
2225 "Turn off privileged mode command\n")
2227 if (vty
->node
== ENABLE_NODE
)
2228 vty
->node
= VIEW_NODE
;
2232 DEFUNSH(VTYSH_REALLYALL
, vtysh_config_terminal
, vtysh_config_terminal_cmd
,
2233 "configure [terminal]",
2234 "Configuration from vty interface\n"
2235 "Configuration terminal\n")
2237 vty
->node
= CONFIG_NODE
;
2241 static int vtysh_exit(struct vty
*vty
)
2243 struct cmd_node
*cnode
= vector_lookup(cmdvec
, vty
->node
);
2245 if (vty
->node
== VIEW_NODE
|| vty
->node
== ENABLE_NODE
)
2247 if (cnode
->node_exit
)
2248 cnode
->node_exit(vty
);
2249 if (cnode
->parent_node
)
2250 vty
->node
= cnode
->parent_node
;
2252 if (vty
->node
== CONFIG_NODE
) {
2253 /* resync in case one of the daemons is somewhere else */
2254 vtysh_execute("end");
2255 vtysh_execute("configure");
2260 DEFUNSH(VTYSH_REALLYALL
, vtysh_exit_all
, vtysh_exit_all_cmd
, "exit",
2261 "Exit current mode and down to previous mode\n")
2263 return vtysh_exit(vty
);
2266 DEFUNSH(VTYSH_REALLYALL
, vtysh_quit_all
, vtysh_quit_all_cmd
, "quit",
2267 "Exit current mode and down to previous mode\n")
2269 return vtysh_exit_all(self
, vty
, argc
, argv
);
2273 DEFUNSH(VTYSH_BGPD
, exit_address_family
, exit_address_family_cmd
,
2274 "exit-address-family", "Exit from Address Family configuration mode\n")
2276 if (vty
->node
== BGP_IPV4_NODE
|| vty
->node
== BGP_IPV4M_NODE
2277 || vty
->node
== BGP_IPV4L_NODE
|| vty
->node
== BGP_VPNV4_NODE
2278 || vty
->node
== BGP_VPNV6_NODE
|| vty
->node
== BGP_IPV6_NODE
2279 || vty
->node
== BGP_IPV6L_NODE
|| vty
->node
== BGP_IPV6M_NODE
2280 || vty
->node
== BGP_EVPN_NODE
2281 || vty
->node
== BGP_FLOWSPECV4_NODE
2282 || vty
->node
== BGP_FLOWSPECV6_NODE
)
2283 vty
->node
= BGP_NODE
;
2287 DEFUNSH(VTYSH_BGPD
, exit_vni
, exit_vni_cmd
, "exit-vni", "Exit from VNI mode\n")
2289 if (vty
->node
== BGP_EVPN_VNI_NODE
)
2290 vty
->node
= BGP_EVPN_NODE
;
2294 DEFUNSH(VTYSH_BGPD
, rpki_exit
, rpki_exit_cmd
, "exit",
2295 "Exit current mode and down to previous mode\n")
2301 DEFUNSH(VTYSH_BGPD
, rpki_quit
, rpki_quit_cmd
, "quit",
2302 "Exit current mode and down to previous mode\n")
2304 return rpki_exit(self
, vty
, argc
, argv
);
2307 DEFUNSH(VTYSH_BGPD
, bmp_exit
, bmp_exit_cmd
, "exit",
2308 "Exit current mode and down to previous mode\n")
2314 DEFUNSH(VTYSH_BGPD
, bmp_quit
, bmp_quit_cmd
, "quit",
2315 "Exit current mode and down to previous mode\n")
2317 return bmp_exit(self
, vty
, argc
, argv
);
2319 #endif /* HAVE_BGPD */
2321 DEFUNSH(VTYSH_VRF
, exit_vrf_config
, exit_vrf_config_cmd
, "exit-vrf",
2322 "Exit from VRF configuration mode\n")
2324 if (vty
->node
== VRF_NODE
)
2325 vty
->node
= CONFIG_NODE
;
2329 DEFUNSH(VTYSH_ZEBRA
, exit_srv6_config
, exit_srv6_config_cmd
, "exit",
2330 "Exit from SRv6 configuration mode\n")
2332 if (vty
->node
== SRV6_NODE
)
2333 vty
->node
= SEGMENT_ROUTING_NODE
;
2337 DEFUNSH(VTYSH_ZEBRA
, exit_srv6_locs_config
, exit_srv6_locs_config_cmd
, "exit",
2338 "Exit from SRv6-locator configuration mode\n")
2340 if (vty
->node
== SRV6_LOCS_NODE
)
2341 vty
->node
= SRV6_NODE
;
2345 DEFUNSH(VTYSH_ZEBRA
, exit_srv6_loc_config
, exit_srv6_loc_config_cmd
, "exit",
2346 "Exit from SRv6-locators configuration mode\n")
2348 if (vty
->node
== SRV6_LOC_NODE
)
2349 vty
->node
= SRV6_LOCS_NODE
;
2354 DEFUNSH(VTYSH_RIPD
, vtysh_exit_ripd
, vtysh_exit_ripd_cmd
, "exit",
2355 "Exit current mode and down to previous mode\n")
2357 return vtysh_exit(vty
);
2360 DEFUNSH(VTYSH_RIPD
, vtysh_quit_ripd
, vtysh_quit_ripd_cmd
, "quit",
2361 "Exit current mode and down to previous mode\n")
2363 return vtysh_exit_ripd(self
, vty
, argc
, argv
);
2365 #endif /* HAVE_RIPD */
2368 DEFUNSH(VTYSH_RIPNGD
, vtysh_exit_ripngd
, vtysh_exit_ripngd_cmd
, "exit",
2369 "Exit current mode and down to previous mode\n")
2371 return vtysh_exit(vty
);
2374 DEFUNSH(VTYSH_RIPNGD
, vtysh_quit_ripngd
, vtysh_quit_ripngd_cmd
, "quit",
2375 "Exit current mode and down to previous mode\n")
2377 return vtysh_exit_ripngd(self
, vty
, argc
, argv
);
2379 #endif /* HAVE_RIPNGD */
2381 DEFUNSH(VTYSH_RMAP
, vtysh_exit_rmap
, vtysh_exit_rmap_cmd
, "exit",
2382 "Exit current mode and down to previous mode\n")
2384 return vtysh_exit(vty
);
2387 DEFUNSH(VTYSH_RMAP
, vtysh_quit_rmap
, vtysh_quit_rmap_cmd
, "quit",
2388 "Exit current mode and down to previous mode\n")
2390 return vtysh_exit_rmap(self
, vty
, argc
, argv
);
2394 DEFUNSH(VTYSH_PBRD
, vtysh_exit_pbr_map
, vtysh_exit_pbr_map_cmd
, "exit",
2395 "Exit current mode and down to previous mode\n")
2397 return vtysh_exit(vty
);
2400 DEFUNSH(VTYSH_PBRD
, vtysh_quit_pbr_map
, vtysh_quit_pbr_map_cmd
, "quit",
2401 "Exit current mode and down to previous mode\n")
2403 return vtysh_exit_rmap(self
, vty
, argc
, argv
);
2405 #endif /* HAVE_PBRD */
2408 DEFUNSH(VTYSH_BGPD
, vtysh_exit_bgpd
, vtysh_exit_bgpd_cmd
, "exit",
2409 "Exit current mode and down to previous mode\n")
2411 return vtysh_exit(vty
);
2414 DEFUNSH(VTYSH_BGPD
, vtysh_quit_bgpd
, vtysh_quit_bgpd_cmd
, "quit",
2415 "Exit current mode and down to previous mode\n")
2417 return vtysh_exit_bgpd(self
, vty
, argc
, argv
);
2419 #endif /* HAVE_BGPD */
2422 DEFUNSH(VTYSH_OSPFD
, vtysh_exit_ospfd
, vtysh_exit_ospfd_cmd
, "exit",
2423 "Exit current mode and down to previous mode\n")
2425 return vtysh_exit(vty
);
2428 DEFUNSH(VTYSH_OSPFD
, vtysh_quit_ospfd
, vtysh_quit_ospfd_cmd
, "quit",
2429 "Exit current mode and down to previous mode\n")
2431 return vtysh_exit_ospfd(self
, vty
, argc
, argv
);
2433 #endif /* HAVE_OSPFD */
2436 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_eigrpd
, vtysh_exit_eigrpd_cmd
, "exit",
2437 "Exit current mode and down to previous mode\n")
2439 return vtysh_exit(vty
);
2442 DEFUNSH(VTYSH_EIGRPD
, vtysh_quit_eigrpd
, vtysh_quit_eigrpd_cmd
, "quit",
2443 "Exit current mode and down to previous mode\n")
2445 return vtysh_exit(vty
);
2447 #endif /* HAVE_EIGRPD */
2450 DEFUNSH(VTYSH_BABELD
, vtysh_exit_babeld
, vtysh_exit_babeld_cmd
, "exit",
2451 "Exit current mode and down to previous mode\n")
2453 return vtysh_exit(vty
);
2456 DEFUNSH(VTYSH_BABELD
, vtysh_quit_babeld
, vtysh_quit_babeld_cmd
, "quit",
2457 "Exit current mode and down to previous mode\n")
2459 return vtysh_exit(vty
);
2461 #endif /* HAVE_BABELD */
2464 DEFUNSH(VTYSH_OSPF6D
, vtysh_exit_ospf6d
, vtysh_exit_ospf6d_cmd
, "exit",
2465 "Exit current mode and down to previous mode\n")
2467 return vtysh_exit(vty
);
2470 DEFUNSH(VTYSH_OSPF6D
, vtysh_quit_ospf6d
, vtysh_quit_ospf6d_cmd
, "quit",
2471 "Exit current mode and down to previous mode\n")
2473 return vtysh_exit_ospf6d(self
, vty
, argc
, argv
);
2475 #endif /* HAVE_OSPF6D */
2477 #if defined(HAVE_LDPD)
2478 DEFUNSH(VTYSH_LDPD
, vtysh_exit_ldpd
, vtysh_exit_ldpd_cmd
, "exit",
2479 "Exit current mode and down to previous mode\n")
2481 return vtysh_exit(vty
);
2484 ALIAS(vtysh_exit_ldpd
, vtysh_quit_ldpd_cmd
, "quit",
2485 "Exit current mode and down to previous mode\n")
2489 DEFUNSH(VTYSH_ISISD
, vtysh_exit_isisd
, vtysh_exit_isisd_cmd
, "exit",
2490 "Exit current mode and down to previous mode\n")
2492 return vtysh_exit(vty
);
2495 DEFUNSH(VTYSH_ISISD
, vtysh_quit_isisd
, vtysh_quit_isisd_cmd
, "quit",
2496 "Exit current mode and down to previous mode\n")
2498 return vtysh_exit_isisd(self
, vty
, argc
, argv
);
2500 #endif /* HAVE_ISISD */
2503 DEFUNSH(VTYSH_BFDD
, vtysh_exit_bfdd
, vtysh_exit_bfdd_cmd
, "exit",
2504 "Exit current mode and down to previous mode\n")
2506 return vtysh_exit(vty
);
2509 ALIAS(vtysh_exit_bfdd
, vtysh_quit_bfdd_cmd
, "quit",
2510 "Exit current mode and down to previous mode\n")
2514 DEFUNSH(VTYSH_FABRICD
, vtysh_exit_fabricd
, vtysh_exit_fabricd_cmd
, "exit",
2515 "Exit current mode and down to previous mode\n")
2517 return vtysh_exit(vty
);
2520 DEFUNSH(VTYSH_FABRICD
, vtysh_quit_fabricd
, vtysh_quit_fabricd_cmd
, "quit",
2521 "Exit current mode and down to previous mode\n")
2523 return vtysh_exit_fabricd(self
, vty
, argc
, argv
);
2525 #endif /* HAVE_FABRICD */
2527 DEFUNSH(VTYSH_KEYS
, vtysh_exit_keys
, vtysh_exit_keys_cmd
, "exit",
2528 "Exit current mode and down to previous mode\n")
2530 return vtysh_exit(vty
);
2533 DEFUNSH(VTYSH_KEYS
, vtysh_quit_keys
, vtysh_quit_keys_cmd
, "quit",
2534 "Exit current mode and down to previous mode\n")
2536 return vtysh_exit_keys(self
, vty
, argc
, argv
);
2539 DEFUNSH(VTYSH_SR
, vtysh_exit_sr
, vtysh_exit_sr_cmd
, "exit",
2540 "Exit current mode and down to previous mode\n")
2542 return vtysh_exit(vty
);
2545 DEFUNSH(VTYSH_SR
, vtysh_quit_sr
, vtysh_quit_sr_cmd
, "quit",
2546 "Exit current mode and down to previous mode\n")
2548 return vtysh_exit(vty
);
2551 #if defined(HAVE_PATHD)
2552 DEFUNSH(VTYSH_PATHD
, vtysh_exit_pathd
, vtysh_exit_pathd_cmd
, "exit",
2553 "Exit current mode and down to previous mode\n")
2555 return vtysh_exit(vty
);
2558 DEFUNSH(VTYSH_PATHD
, vtysh_quit_pathd
, vtysh_quit_pathd_cmd
, "quit",
2559 "Exit current mode and down to previous mode\n")
2561 return vtysh_exit_pathd(self
, vty
, argc
, argv
);
2563 #endif /* HAVE_PATHD */
2565 DEFUNSH(VTYSH_ALL
, vtysh_exit_line_vty
, vtysh_exit_line_vty_cmd
, "exit",
2566 "Exit current mode and down to previous mode\n")
2568 return vtysh_exit(vty
);
2571 DEFUNSH(VTYSH_ALL
, vtysh_quit_line_vty
, vtysh_quit_line_vty_cmd
, "quit",
2572 "Exit current mode and down to previous mode\n")
2574 return vtysh_exit_line_vty(self
, vty
, argc
, argv
);
2577 DEFUNSH(VTYSH_INTERFACE
, vtysh_interface
, vtysh_interface_cmd
,
2578 "interface IFNAME [vrf NAME]",
2579 "Select an interface to configure\n"
2580 "Interface's name\n" VRF_CMD_HELP_STR
)
2582 vty
->node
= INTERFACE_NODE
;
2586 DEFUNSH(VTYSH_ZEBRA
, vtysh_pseudowire
, vtysh_pseudowire_cmd
,
2587 "pseudowire IFNAME",
2588 "Static pseudowire configuration\n"
2589 "Pseudowire name\n")
2591 vty
->node
= PW_NODE
;
2595 DEFUNSH(VTYSH_NH_GROUP
,
2596 vtysh_nexthop_group
, vtysh_nexthop_group_cmd
,
2597 "nexthop-group NHGNAME",
2598 "Nexthop Group configuration\n"
2599 "Name of the Nexthop Group\n")
2601 vty
->node
= NH_GROUP_NODE
;
2605 DEFSH(VTYSH_NH_GROUP
, vtysh_no_nexthop_group_cmd
,
2606 "no nexthop-group NHGNAME",
2608 "Nexthop Group Configuration\n"
2609 "Name of the Nexthop Group\n")
2611 DEFUNSH(VTYSH_VRF
, vtysh_vrf
, vtysh_vrf_cmd
, "vrf NAME",
2612 "Select a VRF to configure\n"
2615 vty
->node
= VRF_NODE
;
2619 DEFUNSH(VTYSH_VRF
, vtysh_exit_vrf
, vtysh_exit_vrf_cmd
, "exit",
2620 "Exit current mode and down to previous mode\n")
2622 return vtysh_exit(vty
);
2625 DEFUNSH(VTYSH_VRF
, vtysh_quit_vrf
, vtysh_quit_vrf_cmd
, "quit",
2626 "Exit current mode and down to previous mode\n")
2628 return vtysh_exit_vrf(self
, vty
, argc
, argv
);
2631 DEFUNSH(VTYSH_NH_GROUP
,
2632 vtysh_exit_nexthop_group
, vtysh_exit_nexthop_group_cmd
,
2633 "exit", "Exit current mode and down to previous mode\n")
2635 return vtysh_exit(vty
);
2638 DEFUNSH(VTYSH_NH_GROUP
,
2639 vtysh_quit_nexthop_group
, vtysh_quit_nexthop_group_cmd
,
2640 "quit", "Exit current mode and down to previous mode\n")
2642 return vtysh_exit_nexthop_group(self
, vty
, argc
, argv
);
2645 DEFUNSH(VTYSH_INTERFACE
, vtysh_exit_interface
, vtysh_exit_interface_cmd
, "exit",
2646 "Exit current mode and down to previous mode\n")
2648 return vtysh_exit(vty
);
2651 DEFUNSH(VTYSH_INTERFACE
, vtysh_quit_interface
, vtysh_quit_interface_cmd
, "quit",
2652 "Exit current mode and down to previous mode\n")
2654 return vtysh_exit_interface(self
, vty
, argc
, argv
);
2657 DEFUNSH(VTYSH_ZEBRA
, vtysh_exit_pseudowire
, vtysh_exit_pseudowire_cmd
, "exit",
2658 "Exit current mode and down to previous mode\n")
2660 return vtysh_exit(vty
);
2663 DEFUNSH(VTYSH_ZEBRA
, vtysh_quit_pseudowire
, vtysh_quit_pseudowire_cmd
, "quit",
2664 "Exit current mode and down to previous mode\n")
2666 return vtysh_exit_pseudowire(self
, vty
, argc
, argv
);
2669 static char *do_prepend(struct vty
*vty
, struct cmd_token
**argv
, int argc
)
2671 const char *argstr
[argc
+ 1];
2674 if (vty
->node
!= VIEW_NODE
) {
2679 for (i
= 0; i
< argc
; i
++)
2680 argstr
[i
+ off
] = argv
[i
]->arg
;
2682 return frrstr_join(argstr
, argc
+ off
, " ");
2685 static int show_per_daemon(struct vty
*vty
, struct cmd_token
**argv
, int argc
,
2686 const char *headline
)
2689 int ret
= CMD_SUCCESS
;
2690 char *line
= do_prepend(vty
, argv
, argc
);
2692 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2693 if (vtysh_client
[i
].fd
>= 0 || vtysh_client
[i
].next
) {
2694 vty_out(vty
, headline
, vtysh_client
[i
].name
);
2695 ret
= vtysh_client_execute(&vtysh_client
[i
], line
);
2699 XFREE(MTYPE_TMP
, line
);
2704 static int show_one_daemon(struct vty
*vty
, struct cmd_token
**argv
, int argc
,
2708 char *line
= do_prepend(vty
, argv
, argc
);
2710 ret
= vtysh_client_execute_name(name
, line
);
2712 XFREE(MTYPE_TMP
, line
);
2717 DEFUN (vtysh_show_poll
,
2718 vtysh_show_poll_cmd
,
2721 "Thread information\n"
2722 "Thread Poll Information\n")
2724 return show_per_daemon(vty
, argv
, argc
, "Thread statistics for %s:\n");
2727 DEFUN (vtysh_show_thread
,
2728 vtysh_show_thread_cmd
,
2729 "show thread cpu [FILTER]",
2731 "Thread information\n"
2732 "Thread CPU usage\n"
2733 "Display filter (rwtexb)\n")
2735 return show_per_daemon(vty
, argv
, argc
, "Thread statistics for %s:\n");
2738 DEFUN (vtysh_show_work_queues
,
2739 vtysh_show_work_queues_cmd
,
2742 "Work Queue information\n")
2744 return show_per_daemon(vty
, argv
, argc
,
2745 "Work queue statistics for %s:\n");
2748 DEFUN (vtysh_show_work_queues_daemon
,
2749 vtysh_show_work_queues_daemon_cmd
,
2750 "show work-queues " DAEMONS_LIST
,
2752 "Work Queue information\n"
2755 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
2758 DEFUNSH(VTYSH_ZEBRA
, vtysh_link_params
, vtysh_link_params_cmd
, "link-params",
2761 vty
->node
= LINK_PARAMS_NODE
;
2765 DEFUNSH(VTYSH_ZEBRA
, exit_link_params
, exit_link_params_cmd
, "exit-link-params",
2766 "Exit from Link Params configuration node\n")
2768 if (vty
->node
== LINK_PARAMS_NODE
)
2769 vty
->node
= INTERFACE_NODE
;
2773 DEFUNSH(VTYSH_ZEBRA
, vtysh_exit_link_params
, vtysh_exit_link_params_cmd
, "exit",
2774 "Exit current mode and down to previous mode\n")
2776 if (vty
->node
== LINK_PARAMS_NODE
)
2777 vty
->node
= INTERFACE_NODE
;
2781 DEFUNSH(VTYSH_ZEBRA
, vtysh_quit_link_params
, vtysh_quit_link_params_cmd
, "quit",
2782 "Exit current mode and down to previous mode\n")
2784 return vtysh_exit_link_params(self
, vty
, argc
, argv
);
2787 DEFUNSH_HIDDEN (0x00,
2789 vtysh_debug_all_cmd
,
2793 "Toggle all debugs on or off\n")
2798 DEFUN (vtysh_show_debugging
,
2799 vtysh_show_debugging_cmd
,
2804 return show_per_daemon(vty
, argv
, argc
, "");
2807 DEFUN (vtysh_show_debugging_hashtable
,
2808 vtysh_show_debugging_hashtable_cmd
,
2809 "show debugging hashtable [statistics]",
2812 "Statistics about hash tables\n"
2813 "Statistics about hash tables\n")
2815 bool stats
= strmatch(argv
[argc
- 1]->text
, "statistics");
2819 "Load factor (LF) - average number of elements across all buckets\n");
2821 "Full load factor (FLF) - average number of elements across full buckets\n\n");
2823 "Standard deviation (SD) is calculated for both the LF and FLF\n");
2825 "and indicates the typical deviation of bucket chain length\n");
2826 vty_out(vty
, "from the value in the corresponding load factor.\n\n");
2828 return show_per_daemon(vty
, argv
, stats
? argc
- 1 : argc
,
2829 "Hashtable statistics for %s:\n");
2832 DEFUN (vtysh_show_error_code
,
2833 vtysh_show_error_code_cmd
,
2834 "show error <(1-4294967296)|all> [json]",
2836 "Information on errors\n"
2837 "Error code to get info about\n"
2838 "Information on all errors\n"
2843 if (!strmatch(argv
[2]->text
, "all"))
2844 arg
= strtoul(argv
[2]->arg
, NULL
, 10);
2846 /* If it's not a shared code, send it to all the daemons */
2847 if (arg
< LIB_FERR_START
|| arg
> LIB_FERR_END
) {
2848 show_per_daemon(vty
, argv
, argc
, "");
2849 /* Otherwise, print it ourselves to avoid duplication */
2851 bool json
= strmatch(argv
[argc
- 1]->text
, "json");
2853 if (!strmatch(argv
[2]->text
, "all"))
2854 arg
= strtoul(argv
[2]->arg
, NULL
, 10);
2856 log_ref_display(vty
, arg
, json
);
2863 DEFUN_HIDDEN (show_config_running
,
2864 show_config_running_cmd
,
2865 "show configuration running\
2866 [<json|xml> [translate WORD]]\
2867 [with-defaults]" DAEMONS_LIST
,
2869 "Configuration information\n"
2870 "Running configuration\n"
2871 "Change output format to JSON\n"
2872 "Change output format to XML\n"
2873 "Translate output\n"
2874 "YANG module translator\n"
2875 "Show default values\n"
2878 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
2881 DEFUN (show_yang_operational_data
,
2882 show_yang_operational_data_cmd
,
2883 "show yang operational-data XPATH\
2889 "YANG information\n"
2890 "Show YANG operational data\n"
2891 "XPath expression specifying the YANG data path\n"
2892 "Set the output format\n"
2893 "JavaScript Object Notation\n"
2894 "Extensible Markup Language\n"
2895 "Translate operational data\n"
2896 "YANG module translator\n"
2899 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
2902 DEFUN(show_yang_module
, show_yang_module_cmd
,
2903 "show yang module [module-translator WORD] " DAEMONS_LIST
,
2905 "YANG information\n"
2906 "Show loaded modules\n"
2907 "YANG module translator\n"
2908 "YANG module translator\n" DAEMONS_STR
)
2910 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
2913 DEFUN(show_yang_module_detail
, show_yang_module_detail_cmd
,
2915 [module-translator WORD]\
2916 WORD <compiled|summary|tree|yang|yin> " DAEMONS_LIST
,
2918 "YANG information\n"
2919 "Show loaded modules\n"
2920 "YANG module translator\n"
2921 "YANG module translator\n"
2923 "Display compiled module in YANG format\n"
2924 "Display summary information about the module\n"
2925 "Display module in the tree (RFC 8340) format\n"
2926 "Display module in the YANG format\n"
2927 "Display module in the YIN format\n" DAEMONS_STR
)
2929 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
2933 DEFUNSH(VTYSH_ALL
, debug_nb
,
2935 "[no] debug northbound\
2937 callbacks [{configuration|state|rpc}]\
2944 "Northbound debugging\n"
2951 "libyang debugging\n")
2956 DEFUN (vtysh_show_history
,
2957 vtysh_show_history_cmd
,
2960 "The list of commands stored in history\n")
2962 HIST_ENTRY
**hlist
= history_list();
2966 vty_out(vty
, "%s\n", hlist
[i
]->line
);
2973 DEFUN (vtysh_show_memory
,
2974 vtysh_show_memory_cmd
,
2975 "show memory [" DAEMONS_LIST
"]",
2977 "Memory statistics\n"
2981 return show_one_daemon(vty
, argv
, argc
- 1,
2982 argv
[argc
- 1]->text
);
2984 return show_per_daemon(vty
, argv
, argc
, "Memory statistics for %s:\n");
2987 DEFUN (vtysh_show_modules
,
2988 vtysh_show_modules_cmd
,
2993 return show_per_daemon(vty
, argv
, argc
, "Module information for %s:\n");
2996 /* Logging commands. */
2997 DEFUN (vtysh_show_logging
,
2998 vtysh_show_logging_cmd
,
3001 "Show current logging configuration\n")
3003 return show_per_daemon(vty
, argv
, argc
,
3004 "Logging configuration for %s:\n");
3007 DEFUNSH(VTYSH_ALL
, vtysh_debug_memstats
,
3008 vtysh_debug_memstats_cmd
, "[no] debug memstats-at-exit",
3011 "Print memory statistics at exit\n")
3016 DEFUN(vtysh_debug_uid_backtrace
,
3017 vtysh_debug_uid_backtrace_cmd
,
3018 "[no] debug unique-id UID backtrace",
3021 "Options per individual log message, by unique ID\n"
3022 "Log message unique ID (XXXXX-XXXXX)\n"
3023 "Add backtrace to log when message is printed\n")
3025 unsigned int i
, ok
= 0;
3026 int err
= CMD_SUCCESS
, ret
;
3030 if (!strcmp(argv
[0]->text
, "no")) {
3032 snprintfrr(line
, sizeof(line
),
3033 "no debug unique-id %s backtrace", uid
);
3036 snprintfrr(line
, sizeof(line
), "debug unique-id %s backtrace",
3040 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3041 if (vtysh_client
[i
].fd
>= 0 || vtysh_client
[i
].next
) {
3042 ret
= vtysh_client_execute(&vtysh_client
[i
], line
);
3047 case CMD_ERR_NOTHING_TODO
:
3048 /* ignore this daemon
3050 * note this doesn't need to handle instances
3051 * of the same daemon individually because
3052 * the same daemon will have the same UIDs
3056 if (err
== CMD_SUCCESS
)
3062 if (err
== CMD_SUCCESS
&& !ok
) {
3063 vty_out(vty
, "%% no running daemon recognizes unique-ID %s\n",
3070 DEFUNSH(VTYSH_ALL
, vtysh_service_password_encrypt
,
3071 vtysh_service_password_encrypt_cmd
, "service password-encryption",
3072 "Set up miscellaneous service\n"
3073 "Enable encrypted passwords\n")
3078 DEFUNSH(VTYSH_ALL
, no_vtysh_service_password_encrypt
,
3079 no_vtysh_service_password_encrypt_cmd
, "no service password-encryption",
3081 "Set up miscellaneous service\n"
3082 "Enable encrypted passwords\n")
3087 DEFUNSH(VTYSH_ALL
, vtysh_config_password
, vtysh_password_cmd
,
3088 "password [(8-8)] LINE",
3089 "Modify the terminal connection password\n"
3090 "Specifies a HIDDEN password will follow\n"
3091 "The password string\n")
3096 DEFUNSH(VTYSH_ALL
, no_vtysh_config_password
, no_vtysh_password_cmd
,
3097 "no password", NO_STR
3098 "Modify the terminal connection password\n")
3100 vty_out(vty
, NO_PASSWD_CMD_WARNING
);
3105 DEFUNSH(VTYSH_ALL
, vtysh_config_enable_password
, vtysh_enable_password_cmd
,
3106 "enable password [(8-8)] LINE",
3107 "Modify enable password parameters\n"
3108 "Assign the privileged level password\n"
3109 "Specifies a HIDDEN password will follow\n"
3110 "The 'enable' password string\n")
3115 DEFUNSH(VTYSH_ALL
, no_vtysh_config_enable_password
,
3116 no_vtysh_enable_password_cmd
, "no enable password", NO_STR
3117 "Modify enable password parameters\n"
3118 "Assign the privileged level password\n")
3120 vty_out(vty
, NO_PASSWD_CMD_WARNING
);
3125 DEFUN (vtysh_write_terminal
,
3126 vtysh_write_terminal_cmd
,
3127 "write terminal ["DAEMONS_LIST
"] [no-header]",
3128 "Write running configuration to memory, network, or terminal\n"
3129 "Write to terminal\n"
3131 "Skip \"Building configuration...\" header\n")
3134 char line
[] = "do write terminal\n";
3136 if (!strcmp(argv
[argc
- 1]->arg
, "no-header"))
3139 vty_out(vty
, "Building configuration...\n");
3140 vty_out(vty
, "\nCurrent configuration:\n");
3141 vty_out(vty
, "!\n");
3144 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3146 || (strmatch(vtysh_client
[i
].name
, argv
[2]->text
)))
3147 vtysh_client_config(&vtysh_client
[i
], line
);
3149 /* Integrate vtysh specific configuration. */
3150 vty_open_pager(vty
);
3151 vtysh_config_write();
3152 vtysh_config_dump();
3153 vty_close_pager(vty
);
3154 vty_out(vty
, "end\n");
3159 DEFUN (vtysh_show_running_config
,
3160 vtysh_show_running_config_cmd
,
3161 "show running-config ["DAEMONS_LIST
"] [no-header]",
3163 "Current operating configuration\n"
3165 "Skip \"Building configuration...\" header\n")
3167 return vtysh_write_terminal(self
, vty
, argc
, argv
);
3170 DEFUN (vtysh_integrated_config
,
3171 vtysh_integrated_config_cmd
,
3172 "service integrated-vtysh-config",
3173 "Set up miscellaneous service\n"
3174 "Write configuration into integrated file\n")
3176 vtysh_write_integrated
= WRITE_INTEGRATED_YES
;
3180 DEFUN (no_vtysh_integrated_config
,
3181 no_vtysh_integrated_config_cmd
,
3182 "no service integrated-vtysh-config",
3184 "Set up miscellaneous service\n"
3185 "Write configuration into integrated file\n")
3187 vtysh_write_integrated
= WRITE_INTEGRATED_NO
;
3191 static void backup_config_file(const char *fbackup
)
3193 char *integrate_sav
= NULL
;
3195 size_t integrate_sav_sz
= strlen(fbackup
) + strlen(CONF_BACKUP_EXT
) + 1;
3196 integrate_sav
= malloc(integrate_sav_sz
);
3197 strlcpy(integrate_sav
, fbackup
, integrate_sav_sz
);
3198 strlcat(integrate_sav
, CONF_BACKUP_EXT
, integrate_sav_sz
);
3200 /* Move current configuration file to backup config file. */
3201 if (unlink(integrate_sav
) != 0 && errno
!= ENOENT
)
3202 vty_out(vty
, "Unlink failed for %s: %s\n", integrate_sav
,
3204 if (rename(fbackup
, integrate_sav
) != 0 && errno
!= ENOENT
)
3205 vty_out(vty
, "Error renaming %s to %s: %s\n", fbackup
,
3206 integrate_sav
, strerror(errno
));
3207 free(integrate_sav
);
3210 int vtysh_write_config_integrated(void)
3213 char line
[] = "do write terminal\n";
3217 struct passwd
*pwentry
;
3220 struct group
*grentry
;
3227 vty_out(vty
, "Building Configuration...\n");
3229 backup_config_file(frr_config
);
3230 fp
= fopen(frr_config
, "w");
3233 "%% Error: failed to open configuration file %s: %s\n",
3234 frr_config
, safe_strerror(errno
));
3235 return CMD_WARNING_CONFIG_FAILED
;
3239 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3240 vtysh_client_config(&vtysh_client
[i
], line
);
3242 vtysh_config_write();
3243 vty
->of_saved
= vty
->of
;
3245 vtysh_config_dump();
3246 vty
->of
= vty
->of_saved
;
3248 if (fchmod(fd
, CONFIGFILE_MASK
) != 0) {
3249 printf("%% Warning: can't chmod configuration file %s: %s\n",
3250 frr_config
, safe_strerror(errno
));
3255 pwentry
= getpwnam(FRR_USER
);
3257 uid
= pwentry
->pw_uid
;
3259 printf("%% Warning: could not look up user \"%s\"\n", FRR_USER
);
3264 grentry
= getgrnam(FRR_GROUP
);
3266 gid
= grentry
->gr_gid
;
3268 printf("%% Warning: could not look up group \"%s\"\n",
3274 if (!fstat(fd
, &st
)) {
3275 if (st
.st_uid
== uid
)
3277 if (st
.st_gid
== gid
)
3279 if ((uid
!= (uid_t
)-1 || gid
!= (gid_t
)-1)
3280 && fchown(fd
, uid
, gid
)) {
3281 printf("%% Warning: can't chown configuration file %s: %s\n",
3282 frr_config
, safe_strerror(errno
));
3286 printf("%% Warning: stat() failed on %s: %s\n", frr_config
,
3287 safe_strerror(errno
));
3293 printf("Integrated configuration saved to %s\n", frr_config
);
3301 static bool want_config_integrated(void)
3305 switch (vtysh_write_integrated
) {
3306 case WRITE_INTEGRATED_UNSPECIFIED
:
3307 if (stat(frr_config
, &s
) && errno
== ENOENT
)
3310 case WRITE_INTEGRATED_NO
:
3312 case WRITE_INTEGRATED_YES
:
3318 DEFUN (vtysh_write_memory
,
3319 vtysh_write_memory_cmd
,
3320 "write [<memory|file>]",
3321 "Write running configuration to memory, network, or terminal\n"
3322 "Write configuration to the file (same as write file)\n"
3323 "Write configuration to the file (same as write memory)\n")
3325 int ret
= CMD_SUCCESS
;
3326 char line
[] = "do write memory\n";
3329 vty_out(vty
, "Note: this version of vtysh never writes vtysh.conf\n");
3331 /* If integrated frr.conf explicitely set. */
3332 if (want_config_integrated()) {
3333 ret
= CMD_WARNING_CONFIG_FAILED
;
3335 /* first attempt to use watchfrr if it's available */
3336 bool used_watchfrr
= false;
3338 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3339 if (vtysh_client
[i
].flag
== VTYSH_WATCHFRR
)
3341 if (i
< array_size(vtysh_client
) && vtysh_client
[i
].fd
!= -1) {
3342 used_watchfrr
= true;
3343 ret
= vtysh_client_execute(&vtysh_client
[i
],
3344 "do write integrated");
3348 * If we didn't use watchfrr, fallback to writing the config
3351 if (!used_watchfrr
) {
3352 printf("\nWarning: attempting direct configuration write without watchfrr.\nFile permissions and ownership may be incorrect, or write may fail.\n\n");
3353 ret
= vtysh_write_config_integrated();
3358 vty_out(vty
, "Building Configuration...\n");
3360 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3361 ret
= vtysh_client_execute(&vtysh_client
[i
], line
);
3366 DEFUN (vtysh_copy_running_config
,
3367 vtysh_copy_running_config_cmd
,
3368 "copy running-config startup-config",
3369 "Copy from one file to another\n"
3370 "Copy from current system configuration\n"
3371 "Copy to startup configuration\n")
3373 return vtysh_write_memory(self
, vty
, argc
, argv
);
3376 DEFUN (vtysh_copy_to_running
,
3377 vtysh_copy_to_running_cmd
,
3378 "copy FILENAME running-config",
3379 "Apply a configuration file\n"
3380 "Configuration file to read\n"
3381 "Apply to current configuration\n")
3384 const char *fname
= argv
[1]->arg
;
3386 ret
= vtysh_read_config(fname
, true);
3388 /* Return to enable mode - the 'read_config' api leaves us up a level */
3389 vtysh_execute_no_pager("enable");
3394 DEFUN (vtysh_terminal_paginate
,
3395 vtysh_terminal_paginate_cmd
,
3396 "[no] terminal paginate",
3398 "Set terminal line parameters\n"
3399 "Use pager for output scrolling\n")
3401 free(vtysh_pager_name
);
3402 vtysh_pager_name
= NULL
;
3404 if (strcmp(argv
[0]->text
, "no"))
3405 vtysh_pager_envdef(true);
3409 DEFUN (vtysh_terminal_length
,
3410 vtysh_terminal_length_cmd
,
3411 "[no] terminal length (0-4294967295)",
3413 "Set terminal line parameters\n"
3414 "Set number of lines on a screen\n"
3415 "Number of lines on screen (0 for no pausing, nonzero to use pager)\n")
3418 unsigned long lines
;
3420 free(vtysh_pager_name
);
3421 vtysh_pager_name
= NULL
;
3423 if (!strcmp(argv
[0]->text
, "no") || !strcmp(argv
[1]->text
, "no")) {
3424 /* "terminal no length" = use VTYSH_PAGER */
3425 vtysh_pager_envdef(true);
3429 lines
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3432 "%% The \"terminal length\" command is deprecated and its value is ignored.\n"
3433 "%% Please use \"terminal paginate\" instead with OS TTY length handling.\n");
3434 vtysh_pager_envdef(true);
3440 ALIAS_DEPRECATED(vtysh_terminal_length
,
3441 vtysh_terminal_no_length_cmd
,
3442 "terminal no length",
3443 "Set terminal line parameters\n"
3445 "Set number of lines on a screen\n")
3447 DEFUN (vtysh_show_daemons
,
3448 vtysh_show_daemons_cmd
,
3451 "Show list of running daemons\n")
3455 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3456 if (vtysh_client
[i
].fd
>= 0)
3457 vty_out(vty
, " %s", vtysh_client
[i
].name
);
3463 /* Execute command in child process. */
3464 static void execute_command(const char *command
, int argc
, const char *arg1
,
3474 /* Failure of fork(). */
3475 fprintf(stderr
, "Can't fork: %s\n", safe_strerror(errno
));
3477 } else if (pid
== 0) {
3478 /* This is child process. */
3481 execlp(command
, command
, (const char *)NULL
);
3484 execlp(command
, command
, arg1
, (const char *)NULL
);
3487 execlp(command
, command
, arg1
, arg2
,
3488 (const char *)NULL
);
3492 /* When execlp suceed, this part is not executed. */
3493 fprintf(stderr
, "Can't execute %s: %s\n", command
,
3494 safe_strerror(errno
));
3497 /* This is parent. */
3499 wait4(pid
, &status
, 0, NULL
);
3507 "Send echo messages\n"
3508 "Ping destination address or hostname\n")
3512 argv_find(argv
, argc
, "WORD", &idx
);
3513 execute_command("ping", 1, argv
[idx
]->arg
, NULL
);
3517 ALIAS(vtysh_ping
, vtysh_ping_ip_cmd
, "ping ip WORD",
3518 "Send echo messages\n"
3520 "Ping destination address or hostname\n")
3522 DEFUN (vtysh_traceroute
,
3523 vtysh_traceroute_cmd
,
3525 "Trace route to destination\n"
3526 "Trace route to destination address or hostname\n")
3530 argv_find(argv
, argc
, "WORD", &idx
);
3531 execute_command("traceroute", 1, argv
[idx
]->arg
, NULL
);
3535 ALIAS(vtysh_traceroute
, vtysh_traceroute_ip_cmd
, "traceroute ip WORD",
3536 "Trace route to destination\n"
3538 "Trace route to destination address or hostname\n")
3540 DEFUN (vtysh_mtrace
,
3542 "mtrace WORD [WORD]",
3543 "Multicast trace route to multicast source\n"
3544 "Multicast trace route to multicast source address\n"
3545 "Multicast trace route for multicast group address\n")
3548 execute_command("mtracebis", 1, argv
[1]->arg
, NULL
);
3550 execute_command("mtracebis", 2, argv
[1]->arg
, argv
[2]->arg
);
3557 "Send echo messages\n"
3559 "Ping destination address or hostname\n")
3561 execute_command("ping6", 1, argv
[2]->arg
, NULL
);
3565 DEFUN (vtysh_traceroute6
,
3566 vtysh_traceroute6_cmd
,
3567 "traceroute ipv6 WORD",
3568 "Trace route to destination\n"
3570 "Trace route to destination address or hostname\n")
3572 execute_command("traceroute6", 1, argv
[2]->arg
, NULL
);
3576 #if defined(HAVE_SHELL_ACCESS)
3577 DEFUN (vtysh_telnet
,
3580 "Open a telnet connection\n"
3581 "IP address or hostname of a remote system\n")
3583 execute_command("telnet", 1, argv
[1]->arg
, NULL
);
3587 DEFUN (vtysh_telnet_port
,
3588 vtysh_telnet_port_cmd
,
3590 "Open a telnet connection\n"
3591 "IP address or hostname of a remote system\n"
3592 "TCP Port number\n")
3594 execute_command("telnet", 2, argv
[1]->arg
, argv
[2]->arg
);
3601 "Open an ssh connection\n"
3604 execute_command("ssh", 1, argv
[1]->arg
, NULL
);
3608 DEFUN (vtysh_start_shell
,
3609 vtysh_start_shell_cmd
,
3611 "Start UNIX shell\n")
3613 execute_command("sh", 0, NULL
, NULL
);
3617 DEFUN (vtysh_start_bash
,
3618 vtysh_start_bash_cmd
,
3620 "Start UNIX shell\n"
3623 execute_command("bash", 0, NULL
, NULL
);
3627 DEFUN (vtysh_start_zsh
,
3628 vtysh_start_zsh_cmd
,
3630 "Start UNIX shell\n"
3633 execute_command("zsh", 0, NULL
, NULL
);
3640 "list [permutations]",
3641 "Print command list\n"
3642 "Print all possible command permutations\n")
3644 return cmd_list_cmds(vty
, argc
== 2);
3647 DEFUN (vtysh_output_file
,
3648 vtysh_output_file_cmd
,
3650 "Direct vtysh output to file\n"
3651 "Direct vtysh output to file\n"
3652 "Path to dump output to\n")
3654 const char *path
= argv
[argc
- 1]->arg
;
3655 vty
->of
= fopen(path
, "a");
3657 vty_out(vty
, "Failed to open file '%s': %s\n", path
,
3658 safe_strerror(errno
));
3664 DEFUN (no_vtysh_output_file
,
3665 no_vtysh_output_file_cmd
,
3666 "no output file [FILE]",
3668 "Direct vtysh output to file\n"
3669 "Direct vtysh output to file\n"
3670 "Path to dump output to\n")
3672 if (vty
->of
!= stdout
) {
3682 "Find CLI command matching a regular expression\n"
3683 "Search pattern (POSIX regex)\n")
3685 return cmd_find_cmds(vty
, argv
, argc
);
3688 DEFUN_HIDDEN(show_cli_graph_vtysh
,
3689 show_cli_graph_vtysh_cmd
,
3693 "Dump current command space as DOT graph\n")
3695 struct cmd_node
*cn
= vector_slot(cmdvec
, vty
->node
);
3696 char *dot
= cmd_graph_dump_dot(cn
->cmdgraph
);
3698 vty_out(vty
, "%s\n", dot
);
3699 XFREE(MTYPE_TMP
, dot
);
3703 static void vtysh_install_default(enum node_type node
)
3705 _install_element(node
, &config_list_cmd
);
3706 _install_element(node
, &find_cmd
);
3707 _install_element(node
, &show_cli_graph_vtysh_cmd
);
3708 _install_element(node
, &vtysh_output_file_cmd
);
3709 _install_element(node
, &no_vtysh_output_file_cmd
);
3712 /* Making connection to protocol daemon. */
3713 static int vtysh_connect(struct vtysh_client
*vclient
)
3717 struct sockaddr_un addr
;
3721 if (!vclient
->path
[0])
3722 snprintf(vclient
->path
, sizeof(vclient
->path
), "%s/%s.vty",
3723 vtydir
, vclient
->name
);
3724 path
= vclient
->path
;
3726 /* Stat socket to see if we have permission to access it. */
3727 ret
= stat(path
, &s_stat
);
3728 if (ret
< 0 && errno
!= ENOENT
) {
3729 fprintf(stderr
, "vtysh_connect(%s): stat = %s\n", path
,
3730 safe_strerror(errno
));
3735 if (!S_ISSOCK(s_stat
.st_mode
)) {
3736 fprintf(stderr
, "vtysh_connect(%s): Not a socket\n",
3742 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3745 fprintf(stderr
, "vtysh_connect(%s): socket = %s\n", path
,
3746 safe_strerror(errno
));
3751 memset(&addr
, 0, sizeof(struct sockaddr_un
));
3752 addr
.sun_family
= AF_UNIX
;
3753 strlcpy(addr
.sun_path
, path
, sizeof(addr
.sun_path
));
3754 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
3755 len
= addr
.sun_len
= SUN_LEN(&addr
);
3757 len
= sizeof(addr
.sun_family
) + strlen(addr
.sun_path
);
3758 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
3760 ret
= connect(sock
, (struct sockaddr
*)&addr
, len
);
3763 fprintf(stderr
, "vtysh_connect(%s): connect = %s\n", path
,
3764 safe_strerror(errno
));
3774 static int vtysh_reconnect(struct vtysh_client
*vclient
)
3778 fprintf(stderr
, "Warning: connecting to %s...", vclient
->name
);
3779 ret
= vtysh_connect(vclient
);
3781 fprintf(stderr
, "failed!\n");
3784 fprintf(stderr
, "success!\n");
3785 if (vtysh_client_execute(vclient
, "enable") < 0)
3787 return vtysh_execute_no_pager("end");
3790 /* Return true if str ends with suffix, else return false */
3791 static int ends_with(const char *str
, const char *suffix
)
3793 if (!str
|| !suffix
)
3795 size_t lenstr
= strlen(str
);
3796 size_t lensuffix
= strlen(suffix
);
3797 if (lensuffix
> lenstr
)
3799 return strncmp(str
+ lenstr
- lensuffix
, suffix
, lensuffix
) == 0;
3802 static void vtysh_client_sorted_insert(struct vtysh_client
*head_client
,
3803 struct vtysh_client
*client
)
3805 struct vtysh_client
*prev_node
, *current_node
;
3807 prev_node
= head_client
;
3808 current_node
= head_client
->next
;
3809 while (current_node
) {
3810 if (strcmp(current_node
->path
, client
->path
) > 0)
3813 prev_node
= current_node
;
3814 current_node
= current_node
->next
;
3816 client
->next
= current_node
;
3817 prev_node
->next
= client
;
3820 #define MAXIMUM_INSTANCES 10
3822 static void vtysh_update_all_instances(struct vtysh_client
*head_client
)
3824 struct vtysh_client
*client
;
3826 struct dirent
*file
;
3829 if (head_client
->flag
!= VTYSH_OSPFD
)
3832 /* ls vty_sock_dir and look for all files ending in .vty */
3833 dir
= opendir(vtydir
);
3835 while ((file
= readdir(dir
)) != NULL
) {
3836 if (frrstr_startswith(file
->d_name
, "ospfd-")
3837 && ends_with(file
->d_name
, ".vty")) {
3838 if (n
== MAXIMUM_INSTANCES
) {
3840 "Parsing %s, client limit(%d) reached!\n",
3844 client
= (struct vtysh_client
*)malloc(
3845 sizeof(struct vtysh_client
));
3847 client
->name
= "ospfd";
3848 client
->flag
= VTYSH_OSPFD
;
3849 snprintf(client
->path
, sizeof(client
->path
),
3850 "%s/%s", vtydir
, file
->d_name
);
3851 client
->next
= NULL
;
3852 vtysh_client_sorted_insert(head_client
, client
);
3860 static int vtysh_connect_all_instances(struct vtysh_client
*head_client
)
3862 struct vtysh_client
*client
;
3865 vtysh_update_all_instances(head_client
);
3867 client
= head_client
->next
;
3869 if (vtysh_connect(client
) == 0)
3871 client
= client
->next
;
3877 int vtysh_connect_all(const char *daemon_name
)
3883 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
3885 || !strcmp(daemon_name
, vtysh_client
[i
].name
)) {
3887 if (vtysh_connect(&vtysh_client
[i
]) == 0)
3890 rc
+= vtysh_connect_all_instances(&vtysh_client
[i
]);
3894 fprintf(stderr
, "Error: no daemons match name %s!\n",
3899 /* To disable readline's filename completion. */
3900 static char *vtysh_completion_entry_function(const char *ignore
,
3906 void vtysh_readline_init(void)
3908 /* readline related settings. */
3909 char *disable_bracketed_paste
=
3910 XSTRDUP(MTYPE_TMP
, "set enable-bracketed-paste off");
3913 rl_parse_and_bind(disable_bracketed_paste
);
3914 rl_bind_key('?', (rl_command_func_t
*)vtysh_rl_describe
);
3915 rl_completion_entry_function
= vtysh_completion_entry_function
;
3916 rl_attempted_completion_function
= new_completion
;
3918 XFREE(MTYPE_TMP
, disable_bracketed_paste
);
3921 char *vtysh_prompt(void)
3923 static char buf
[512];
3925 snprintf(buf
, sizeof(buf
), cmd_prompt(vty
->node
), cmd_hostname_get());
3929 static void vtysh_ac_line(void *arg
, const char *line
)
3933 for (i
= 0; i
< vector_active(comps
); i
++)
3934 if (!strcmp(line
, (char *)vector_slot(comps
, i
)))
3936 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, line
));
3939 static void vtysh_autocomplete(vector comps
, struct cmd_token
*token
)
3944 snprintf(accmd
, sizeof(accmd
), "autocomplete %d %s %s", token
->type
,
3945 token
->text
, token
->varname
? token
->varname
: "-");
3947 vty
->of_saved
= vty
->of
;
3949 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3950 vtysh_client_run_all(&vtysh_client
[i
], accmd
, 1, vtysh_ac_line
,
3952 vty
->of
= vty
->of_saved
;
3955 static const struct cmd_variable_handler vtysh_var_handler
[] = {
3959 .completions
= vtysh_autocomplete
},
3960 {.completions
= NULL
}};
3962 void vtysh_uninit(void)
3964 if (vty
->of
!= stdout
)
3968 void vtysh_init_vty(void)
3970 cmd_defer_tree(true);
3972 /* Make vty structure. */
3974 vty
->type
= VTY_SHELL
;
3975 vty
->node
= VIEW_NODE
;
3977 /* set default output */
3979 vtysh_pager_envdef(false);
3981 /* Initialize commands. */
3983 cmd_variable_handler_register(vtysh_var_handler
);
3987 install_node(&bgp_node
);
3988 install_element(CONFIG_NODE
, &router_bgp_cmd
);
3989 install_element(BGP_NODE
, &vtysh_exit_bgpd_cmd
);
3990 install_element(BGP_NODE
, &vtysh_quit_bgpd_cmd
);
3991 install_element(BGP_NODE
, &vtysh_end_all_cmd
);
3993 install_node(&bgp_vpnv4_node
);
3994 install_element(BGP_NODE
, &address_family_ipv4_vpn_cmd
);
3995 #ifdef KEEP_OLD_VPN_COMMANDS
3996 install_element(BGP_NODE
, &address_family_vpnv4_cmd
);
3997 #endif /* KEEP_OLD_VPN_COMMANDS */
3998 install_element(BGP_VPNV4_NODE
, &vtysh_exit_bgpd_cmd
);
3999 install_element(BGP_VPNV4_NODE
, &vtysh_quit_bgpd_cmd
);
4000 install_element(BGP_VPNV4_NODE
, &vtysh_end_all_cmd
);
4001 install_element(BGP_VPNV4_NODE
, &exit_address_family_cmd
);
4003 install_node(&bgp_vpnv6_node
);
4004 install_element(BGP_NODE
, &address_family_ipv6_vpn_cmd
);
4005 #ifdef KEEP_OLD_VPN_COMMANDS
4006 install_element(BGP_NODE
, &address_family_vpnv6_cmd
);
4007 #endif /* KEEP_OLD_VPN_COMMANDS */
4008 install_element(BGP_VPNV6_NODE
, &vtysh_exit_bgpd_cmd
);
4009 install_element(BGP_VPNV6_NODE
, &vtysh_quit_bgpd_cmd
);
4010 install_element(BGP_VPNV6_NODE
, &vtysh_end_all_cmd
);
4011 install_element(BGP_VPNV6_NODE
, &exit_address_family_cmd
);
4013 install_node(&bgp_flowspecv4_node
);
4014 install_element(BGP_NODE
, &address_family_flowspecv4_cmd
);
4015 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_exit_bgpd_cmd
);
4016 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_quit_bgpd_cmd
);
4017 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_end_all_cmd
);
4018 install_element(BGP_FLOWSPECV4_NODE
, &exit_address_family_cmd
);
4020 install_node(&bgp_flowspecv6_node
);
4021 install_element(BGP_NODE
, &address_family_flowspecv6_cmd
);
4022 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_exit_bgpd_cmd
);
4023 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_quit_bgpd_cmd
);
4024 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_end_all_cmd
);
4025 install_element(BGP_FLOWSPECV6_NODE
, &exit_address_family_cmd
);
4027 install_node(&bgp_ipv4_node
);
4028 install_element(BGP_NODE
, &address_family_ipv4_cmd
);
4029 install_element(BGP_IPV4_NODE
, &vtysh_exit_bgpd_cmd
);
4030 install_element(BGP_IPV4_NODE
, &vtysh_quit_bgpd_cmd
);
4031 install_element(BGP_IPV4_NODE
, &vtysh_end_all_cmd
);
4032 install_element(BGP_IPV4_NODE
, &exit_address_family_cmd
);
4034 install_node(&bgp_ipv4m_node
);
4035 install_element(BGP_NODE
, &address_family_ipv4_multicast_cmd
);
4036 install_element(BGP_IPV4M_NODE
, &vtysh_exit_bgpd_cmd
);
4037 install_element(BGP_IPV4M_NODE
, &vtysh_quit_bgpd_cmd
);
4038 install_element(BGP_IPV4M_NODE
, &vtysh_end_all_cmd
);
4039 install_element(BGP_IPV4M_NODE
, &exit_address_family_cmd
);
4041 install_node(&bgp_ipv4l_node
);
4042 install_element(BGP_NODE
, &address_family_ipv4_labeled_unicast_cmd
);
4043 install_element(BGP_IPV4L_NODE
, &vtysh_exit_bgpd_cmd
);
4044 install_element(BGP_IPV4L_NODE
, &vtysh_quit_bgpd_cmd
);
4045 install_element(BGP_IPV4L_NODE
, &vtysh_end_all_cmd
);
4046 install_element(BGP_IPV4L_NODE
, &exit_address_family_cmd
);
4048 install_node(&bgp_ipv6_node
);
4049 install_element(BGP_NODE
, &address_family_ipv6_cmd
);
4050 install_element(BGP_IPV6_NODE
, &vtysh_exit_bgpd_cmd
);
4051 install_element(BGP_IPV6_NODE
, &vtysh_quit_bgpd_cmd
);
4052 install_element(BGP_IPV6_NODE
, &vtysh_end_all_cmd
);
4053 install_element(BGP_IPV6_NODE
, &exit_address_family_cmd
);
4055 install_node(&bgp_ipv6m_node
);
4056 install_element(BGP_NODE
, &address_family_ipv6_multicast_cmd
);
4057 install_element(BGP_IPV6M_NODE
, &vtysh_exit_bgpd_cmd
);
4058 install_element(BGP_IPV6M_NODE
, &vtysh_quit_bgpd_cmd
);
4059 install_element(BGP_IPV6M_NODE
, &vtysh_end_all_cmd
);
4060 install_element(BGP_IPV6M_NODE
, &exit_address_family_cmd
);
4062 install_node(&bgp_ipv6l_node
);
4063 install_element(BGP_NODE
, &address_family_ipv6_labeled_unicast_cmd
);
4064 install_element(BGP_IPV6L_NODE
, &vtysh_exit_bgpd_cmd
);
4065 install_element(BGP_IPV6L_NODE
, &vtysh_quit_bgpd_cmd
);
4066 install_element(BGP_IPV6L_NODE
, &vtysh_end_all_cmd
);
4067 install_element(BGP_IPV6L_NODE
, &exit_address_family_cmd
);
4069 #if defined(ENABLE_BGP_VNC)
4070 install_node(&bgp_vrf_policy_node
);
4071 install_element(BGP_NODE
, &vnc_vrf_policy_cmd
);
4072 install_element(BGP_VRF_POLICY_NODE
, &vtysh_exit_bgpd_cmd
);
4073 install_element(BGP_VRF_POLICY_NODE
, &vtysh_quit_bgpd_cmd
);
4074 install_element(BGP_VRF_POLICY_NODE
, &vtysh_end_all_cmd
);
4075 install_element(BGP_VRF_POLICY_NODE
, &exit_vrf_policy_cmd
);
4077 install_node(&bgp_vnc_defaults_node
);
4078 install_element(BGP_NODE
, &vnc_defaults_cmd
);
4079 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_exit_bgpd_cmd
);
4080 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_quit_bgpd_cmd
);
4081 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_end_all_cmd
);
4082 install_element(BGP_VNC_DEFAULTS_NODE
, &exit_vnc_config_cmd
);
4084 install_node(&bgp_vnc_nve_group_node
);
4085 install_element(BGP_NODE
, &vnc_nve_group_cmd
);
4086 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
4087 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
4088 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_end_all_cmd
);
4089 install_element(BGP_VNC_NVE_GROUP_NODE
, &exit_vnc_config_cmd
);
4091 install_node(&bgp_vnc_l2_group_node
);
4092 install_element(BGP_NODE
, &vnc_l2_group_cmd
);
4093 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
4094 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
4095 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_end_all_cmd
);
4096 install_element(BGP_VNC_L2_GROUP_NODE
, &exit_vnc_config_cmd
);
4099 install_node(&bgp_evpn_node
);
4100 install_element(BGP_NODE
, &address_family_evpn_cmd
);
4101 install_element(BGP_EVPN_NODE
, &vtysh_quit_bgpd_cmd
);
4102 install_element(BGP_EVPN_NODE
, &vtysh_exit_bgpd_cmd
);
4103 install_element(BGP_EVPN_NODE
, &vtysh_end_all_cmd
);
4104 install_element(BGP_EVPN_NODE
, &exit_address_family_cmd
);
4106 install_node(&bgp_evpn_vni_node
);
4107 install_element(BGP_EVPN_NODE
, &bgp_evpn_vni_cmd
);
4108 install_element(BGP_EVPN_VNI_NODE
, &vtysh_exit_bgpd_cmd
);
4109 install_element(BGP_EVPN_VNI_NODE
, &vtysh_quit_bgpd_cmd
);
4110 install_element(BGP_EVPN_VNI_NODE
, &vtysh_end_all_cmd
);
4111 install_element(BGP_EVPN_VNI_NODE
, &exit_vni_cmd
);
4113 install_node(&rpki_node
);
4114 install_element(CONFIG_NODE
, &rpki_cmd
);
4115 install_element(RPKI_NODE
, &rpki_exit_cmd
);
4116 install_element(RPKI_NODE
, &rpki_quit_cmd
);
4117 install_element(RPKI_NODE
, &vtysh_end_all_cmd
);
4119 install_node(&bmp_node
);
4120 install_element(BGP_NODE
, &bmp_targets_cmd
);
4121 install_element(BMP_NODE
, &bmp_exit_cmd
);
4122 install_element(BMP_NODE
, &bmp_quit_cmd
);
4123 install_element(BMP_NODE
, &vtysh_end_all_cmd
);
4125 install_node(&bgp_srv6_node
);
4126 install_element(BGP_NODE
, &bgp_srv6_cmd
);
4127 install_element(BGP_SRV6_NODE
, &exit_bgp_srv6_cmd
);
4128 install_element(BGP_SRV6_NODE
, &quit_bgp_srv6_cmd
);
4129 install_element(BGP_SRV6_NODE
, &vtysh_end_all_cmd
);
4130 #endif /* HAVE_BGPD */
4133 install_node(&rip_node
);
4135 install_element(CONFIG_NODE
, &router_rip_cmd
);
4136 install_element(RIP_NODE
, &vtysh_exit_ripd_cmd
);
4137 install_element(RIP_NODE
, &vtysh_quit_ripd_cmd
);
4138 install_element(RIP_NODE
, &vtysh_end_all_cmd
);
4139 #endif /* HAVE_RIPD */
4142 install_node(&ripng_node
);
4144 install_element(CONFIG_NODE
, &router_ripng_cmd
);
4145 install_element(RIPNG_NODE
, &vtysh_exit_ripngd_cmd
);
4146 install_element(RIPNG_NODE
, &vtysh_quit_ripngd_cmd
);
4147 install_element(RIPNG_NODE
, &vtysh_end_all_cmd
);
4148 #endif /* HAVE_RIPNGD */
4152 install_node(&ospf_node
);
4153 install_element(CONFIG_NODE
, &router_ospf_cmd
);
4154 install_element(OSPF_NODE
, &vtysh_exit_ospfd_cmd
);
4155 install_element(OSPF_NODE
, &vtysh_quit_ospfd_cmd
);
4156 install_element(OSPF_NODE
, &vtysh_end_all_cmd
);
4157 #endif /* HAVE_OSPFD */
4161 install_node(&ospf6_node
);
4162 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
4163 install_element(OSPF6_NODE
, &vtysh_exit_ospf6d_cmd
);
4164 install_element(OSPF6_NODE
, &vtysh_quit_ospf6d_cmd
);
4165 install_element(OSPF6_NODE
, &vtysh_end_all_cmd
);
4166 #endif /* HAVE_OSPF6D */
4169 #if defined(HAVE_LDPD)
4170 install_node(&ldp_node
);
4171 install_element(CONFIG_NODE
, &ldp_mpls_ldp_cmd
);
4172 install_element(LDP_NODE
, &vtysh_exit_ldpd_cmd
);
4173 install_element(LDP_NODE
, &vtysh_quit_ldpd_cmd
);
4174 install_element(LDP_NODE
, &vtysh_end_all_cmd
);
4176 install_node(&ldp_ipv4_node
);
4177 install_element(LDP_NODE
, &ldp_address_family_ipv4_cmd
);
4178 install_element(LDP_IPV4_NODE
, &vtysh_exit_ldpd_cmd
);
4179 install_element(LDP_IPV4_NODE
, &vtysh_quit_ldpd_cmd
);
4180 install_element(LDP_IPV4_NODE
, &ldp_exit_address_family_cmd
);
4181 install_element(LDP_IPV4_NODE
, &vtysh_end_all_cmd
);
4183 install_node(&ldp_ipv6_node
);
4184 install_element(LDP_NODE
, &ldp_address_family_ipv6_cmd
);
4185 install_element(LDP_IPV6_NODE
, &vtysh_exit_ldpd_cmd
);
4186 install_element(LDP_IPV6_NODE
, &vtysh_quit_ldpd_cmd
);
4187 install_element(LDP_IPV6_NODE
, &ldp_exit_address_family_cmd
);
4188 install_element(LDP_IPV6_NODE
, &vtysh_end_all_cmd
);
4190 install_node(&ldp_ipv4_iface_node
);
4191 install_element(LDP_IPV4_NODE
, &ldp_interface_ifname_cmd
);
4192 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
4193 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
4194 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_end_all_cmd
);
4196 install_node(&ldp_ipv6_iface_node
);
4197 install_element(LDP_IPV6_NODE
, &ldp_interface_ifname_cmd
);
4198 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
4199 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
4200 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_end_all_cmd
);
4202 install_node(&ldp_l2vpn_node
);
4203 install_element(CONFIG_NODE
, &ldp_l2vpn_word_type_vpls_cmd
);
4204 install_element(LDP_L2VPN_NODE
, &vtysh_exit_ldpd_cmd
);
4205 install_element(LDP_L2VPN_NODE
, &vtysh_quit_ldpd_cmd
);
4206 install_element(LDP_L2VPN_NODE
, &vtysh_end_all_cmd
);
4208 install_node(&ldp_pseudowire_node
);
4209 install_element(LDP_L2VPN_NODE
, &ldp_member_pseudowire_ifname_cmd
);
4210 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_exit_ldpd_cmd
);
4211 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_quit_ldpd_cmd
);
4212 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_end_all_cmd
);
4217 install_node(&eigrp_node
);
4218 install_element(CONFIG_NODE
, &router_eigrp_cmd
);
4219 install_element(EIGRP_NODE
, &vtysh_exit_eigrpd_cmd
);
4220 install_element(EIGRP_NODE
, &vtysh_quit_eigrpd_cmd
);
4221 install_element(EIGRP_NODE
, &vtysh_end_all_cmd
);
4222 #endif /* HAVE_EIGRPD */
4226 install_node(&babel_node
);
4227 install_element(CONFIG_NODE
, &router_babel_cmd
);
4228 install_element(BABEL_NODE
, &vtysh_exit_babeld_cmd
);
4229 install_element(BABEL_NODE
, &vtysh_quit_babeld_cmd
);
4230 install_element(BABEL_NODE
, &vtysh_end_all_cmd
);
4231 #endif /* HAVE_BABELD */
4235 install_node(&isis_node
);
4236 install_element(CONFIG_NODE
, &router_isis_cmd
);
4237 install_element(ISIS_NODE
, &vtysh_exit_isisd_cmd
);
4238 install_element(ISIS_NODE
, &vtysh_quit_isisd_cmd
);
4239 install_element(ISIS_NODE
, &vtysh_end_all_cmd
);
4240 #endif /* HAVE_ISISD */
4244 install_node(&openfabric_node
);
4245 install_element(CONFIG_NODE
, &router_openfabric_cmd
);
4246 install_element(OPENFABRIC_NODE
, &vtysh_exit_fabricd_cmd
);
4247 install_element(OPENFABRIC_NODE
, &vtysh_quit_fabricd_cmd
);
4248 install_element(OPENFABRIC_NODE
, &vtysh_end_all_cmd
);
4249 #endif /* HAVE_FABRICD */
4253 install_node(&pbr_map_node
);
4254 install_element(CONFIG_NODE
, &vtysh_pbr_map_cmd
);
4255 install_element(CONFIG_NODE
, &vtysh_no_pbr_map_cmd
);
4256 install_element(PBRMAP_NODE
, &vtysh_exit_pbr_map_cmd
);
4257 install_element(PBRMAP_NODE
, &vtysh_quit_pbr_map_cmd
);
4258 install_element(PBRMAP_NODE
, &vtysh_end_all_cmd
);
4259 #endif /* HAVE_PBRD */
4263 install_node(&bfd_node
);
4264 install_element(CONFIG_NODE
, &bfd_enter_cmd
);
4265 install_element(BFD_NODE
, &vtysh_exit_bfdd_cmd
);
4266 install_element(BFD_NODE
, &vtysh_quit_bfdd_cmd
);
4267 install_element(BFD_NODE
, &vtysh_end_all_cmd
);
4269 install_node(&bfd_peer_node
);
4270 install_element(BFD_NODE
, &bfd_peer_enter_cmd
);
4271 install_element(BFD_PEER_NODE
, &vtysh_exit_bfdd_cmd
);
4272 install_element(BFD_PEER_NODE
, &vtysh_quit_bfdd_cmd
);
4273 install_element(BFD_PEER_NODE
, &vtysh_end_all_cmd
);
4275 install_node(&bfd_profile_node
);
4276 install_element(BFD_NODE
, &bfd_profile_enter_cmd
);
4277 install_element(BFD_PROFILE_NODE
, &vtysh_exit_bfdd_cmd
);
4278 install_element(BFD_PROFILE_NODE
, &vtysh_quit_bfdd_cmd
);
4279 install_element(BFD_PROFILE_NODE
, &vtysh_end_all_cmd
);
4280 #endif /* HAVE_BFDD */
4282 install_node(&segment_routing_node
);
4283 install_element(CONFIG_NODE
, &segment_routing_cmd
);
4284 install_element(SEGMENT_ROUTING_NODE
, &vtysh_exit_sr_cmd
);
4285 install_element(SEGMENT_ROUTING_NODE
, &vtysh_quit_sr_cmd
);
4286 install_element(SEGMENT_ROUTING_NODE
, &vtysh_end_all_cmd
);
4288 #if defined(HAVE_PATHD)
4289 install_node(&sr_traffic_eng_node
);
4290 install_node(&srte_segment_list_node
);
4291 install_node(&srte_policy_node
);
4292 install_node(&srte_candidate_dyn_node
);
4294 install_element(SR_TRAFFIC_ENG_NODE
, &vtysh_exit_pathd_cmd
);
4295 install_element(SR_TRAFFIC_ENG_NODE
, &vtysh_quit_pathd_cmd
);
4296 install_element(SR_SEGMENT_LIST_NODE
, &vtysh_exit_pathd_cmd
);
4297 install_element(SR_SEGMENT_LIST_NODE
, &vtysh_quit_pathd_cmd
);
4298 install_element(SR_POLICY_NODE
, &vtysh_exit_pathd_cmd
);
4299 install_element(SR_POLICY_NODE
, &vtysh_quit_pathd_cmd
);
4300 install_element(SR_CANDIDATE_DYN_NODE
, &vtysh_exit_pathd_cmd
);
4301 install_element(SR_CANDIDATE_DYN_NODE
, &vtysh_quit_pathd_cmd
);
4304 install_element(SR_TRAFFIC_ENG_NODE
, &vtysh_end_all_cmd
);
4305 install_element(SR_SEGMENT_LIST_NODE
, &vtysh_end_all_cmd
);
4306 install_element(SR_POLICY_NODE
, &vtysh_end_all_cmd
);
4307 install_element(SR_CANDIDATE_DYN_NODE
, &vtysh_end_all_cmd
);
4309 install_element(SEGMENT_ROUTING_NODE
, &sr_traffic_eng_cmd
);
4310 install_element(SR_TRAFFIC_ENG_NODE
, &srte_segment_list_cmd
);
4311 install_element(SR_TRAFFIC_ENG_NODE
, &srte_policy_cmd
);
4312 install_element(SR_POLICY_NODE
, &srte_policy_candidate_dyn_path_cmd
);
4314 install_node(&pcep_node
);
4315 install_node(&pcep_pcc_node
);
4316 install_node(&pcep_pce_node
);
4317 install_node(&pcep_pce_config_node
);
4319 install_element(PCEP_NODE
, &vtysh_exit_pathd_cmd
);
4320 install_element(PCEP_NODE
, &vtysh_quit_pathd_cmd
);
4321 install_element(PCEP_PCC_NODE
, &vtysh_exit_pathd_cmd
);
4322 install_element(PCEP_PCC_NODE
, &vtysh_quit_pathd_cmd
);
4323 install_element(PCEP_PCE_NODE
, &vtysh_exit_pathd_cmd
);
4324 install_element(PCEP_PCE_NODE
, &vtysh_quit_pathd_cmd
);
4325 install_element(PCEP_PCE_CONFIG_NODE
, &vtysh_exit_pathd_cmd
);
4326 install_element(PCEP_PCE_CONFIG_NODE
, &vtysh_quit_pathd_cmd
);
4328 install_element(PCEP_NODE
, &vtysh_end_all_cmd
);
4329 install_element(PCEP_PCC_NODE
, &vtysh_end_all_cmd
);
4330 install_element(PCEP_PCE_NODE
, &vtysh_end_all_cmd
);
4331 install_element(PCEP_PCE_CONFIG_NODE
, &vtysh_end_all_cmd
);
4333 install_element(SR_TRAFFIC_ENG_NODE
, &pcep_cmd
);
4334 install_element(PCEP_NODE
, &pcep_cli_pcc_cmd
);
4335 install_element(PCEP_NODE
, &pcep_cli_pcep_pce_config_cmd
);
4336 install_element(PCEP_NODE
, &pcep_cli_pce_cmd
);
4338 #endif /* HAVE_PATHD */
4341 install_node(&keychain_node
);
4342 install_element(CONFIG_NODE
, &key_chain_cmd
);
4343 install_element(KEYCHAIN_NODE
, &key_chain_cmd
);
4344 install_element(KEYCHAIN_NODE
, &vtysh_exit_keys_cmd
);
4345 install_element(KEYCHAIN_NODE
, &vtysh_quit_keys_cmd
);
4346 install_element(KEYCHAIN_NODE
, &vtysh_end_all_cmd
);
4348 install_node(&keychain_key_node
);
4349 install_element(KEYCHAIN_NODE
, &key_cmd
);
4350 install_element(KEYCHAIN_KEY_NODE
, &key_chain_cmd
);
4351 install_element(KEYCHAIN_KEY_NODE
, &vtysh_exit_keys_cmd
);
4352 install_element(KEYCHAIN_KEY_NODE
, &vtysh_quit_keys_cmd
);
4353 install_element(KEYCHAIN_KEY_NODE
, &vtysh_end_all_cmd
);
4356 install_node(&nh_group_node
);
4357 install_element(CONFIG_NODE
, &vtysh_nexthop_group_cmd
);
4358 install_element(CONFIG_NODE
, &vtysh_no_nexthop_group_cmd
);
4359 install_element(NH_GROUP_NODE
, &vtysh_end_all_cmd
);
4360 install_element(NH_GROUP_NODE
, &vtysh_exit_nexthop_group_cmd
);
4361 install_element(NH_GROUP_NODE
, &vtysh_quit_nexthop_group_cmd
);
4364 install_node(&zebra_node
);
4366 install_node(&interface_node
);
4367 install_element(CONFIG_NODE
, &vtysh_interface_cmd
);
4368 install_element(INTERFACE_NODE
, &vtysh_end_all_cmd
);
4369 install_element(INTERFACE_NODE
, &vtysh_exit_interface_cmd
);
4370 install_element(INTERFACE_NODE
, &vtysh_quit_interface_cmd
);
4372 install_node(&link_params_node
);
4373 install_element(INTERFACE_NODE
, &vtysh_link_params_cmd
);
4374 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);
4375 install_element(LINK_PARAMS_NODE
, &vtysh_end_all_cmd
);
4376 install_element(LINK_PARAMS_NODE
, &vtysh_exit_link_params_cmd
);
4377 install_element(LINK_PARAMS_NODE
, &vtysh_quit_link_params_cmd
);
4379 install_node(&pw_node
);
4380 install_element(CONFIG_NODE
, &vtysh_pseudowire_cmd
);
4381 install_element(PW_NODE
, &vtysh_end_all_cmd
);
4382 install_element(PW_NODE
, &vtysh_exit_pseudowire_cmd
);
4383 install_element(PW_NODE
, &vtysh_quit_pseudowire_cmd
);
4385 install_node(&vrf_node
);
4386 install_element(CONFIG_NODE
, &vtysh_vrf_cmd
);
4387 install_element(VRF_NODE
, &exit_vrf_config_cmd
);
4388 install_element(VRF_NODE
, &vtysh_end_all_cmd
);
4389 install_element(VRF_NODE
, &vtysh_exit_vrf_cmd
);
4390 install_element(VRF_NODE
, &vtysh_quit_vrf_cmd
);
4392 install_node(&rmap_node
);
4393 install_element(CONFIG_NODE
, &vtysh_route_map_cmd
);
4394 install_element(RMAP_NODE
, &vtysh_exit_rmap_cmd
);
4395 install_element(RMAP_NODE
, &vtysh_quit_rmap_cmd
);
4396 install_element(RMAP_NODE
, &vtysh_end_all_cmd
);
4398 install_node(&vty_node
);
4399 install_element(CONFIG_NODE
, &vtysh_line_vty_cmd
);
4400 install_element(VTY_NODE
, &vtysh_exit_line_vty_cmd
);
4401 install_element(VTY_NODE
, &vtysh_quit_line_vty_cmd
);
4402 install_element(VTY_NODE
, &vtysh_end_all_cmd
);
4405 struct cmd_node
*node
;
4406 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
4407 node
= vector_slot(cmdvec
, i
);
4408 if (!node
|| node
->node
== VIEW_NODE
)
4410 vtysh_install_default(node
->node
);
4416 install_element(VIEW_NODE
, &vtysh_enable_cmd
);
4417 install_element(ENABLE_NODE
, &vtysh_config_terminal_cmd
);
4418 install_element(ENABLE_NODE
, &vtysh_disable_cmd
);
4420 /* "exit" command. */
4421 install_element(VIEW_NODE
, &vtysh_exit_all_cmd
);
4422 install_element(CONFIG_NODE
, &vtysh_exit_all_cmd
);
4423 install_element(VIEW_NODE
, &vtysh_quit_all_cmd
);
4424 install_element(CONFIG_NODE
, &vtysh_quit_all_cmd
);
4426 /* "end" command. */
4427 install_element(CONFIG_NODE
, &vtysh_end_all_cmd
);
4428 install_element(ENABLE_NODE
, &vtysh_end_all_cmd
);
4430 /* SRv6 Data-plane */
4431 install_node(&srv6_node
);
4432 install_element(SEGMENT_ROUTING_NODE
, &srv6_cmd
);
4433 install_element(SRV6_NODE
, &srv6_locators_cmd
);
4434 install_element(SRV6_NODE
, &exit_srv6_config_cmd
);
4435 install_element(SRV6_NODE
, &vtysh_end_all_cmd
);
4437 install_node(&srv6_locs_node
);
4438 install_element(SRV6_LOCS_NODE
, &srv6_locator_cmd
);
4439 install_element(SRV6_LOCS_NODE
, &exit_srv6_locs_config_cmd
);
4440 install_element(SRV6_LOCS_NODE
, &vtysh_end_all_cmd
);
4442 install_node(&srv6_loc_node
);
4443 install_element(SRV6_LOC_NODE
, &exit_srv6_loc_config_cmd
);
4444 install_element(SRV6_LOC_NODE
, &vtysh_end_all_cmd
);
4446 install_element(ENABLE_NODE
, &vtysh_show_running_config_cmd
);
4447 install_element(ENABLE_NODE
, &vtysh_copy_running_config_cmd
);
4448 install_element(ENABLE_NODE
, &vtysh_copy_to_running_cmd
);
4450 /* "write terminal" command. */
4451 install_element(ENABLE_NODE
, &vtysh_write_terminal_cmd
);
4453 install_element(CONFIG_NODE
, &vtysh_integrated_config_cmd
);
4454 install_element(CONFIG_NODE
, &no_vtysh_integrated_config_cmd
);
4456 /* "write memory" command. */
4457 install_element(ENABLE_NODE
, &vtysh_write_memory_cmd
);
4459 install_element(CONFIG_NODE
, &vtysh_terminal_paginate_cmd
);
4460 install_element(VIEW_NODE
, &vtysh_terminal_paginate_cmd
);
4461 install_element(VIEW_NODE
, &vtysh_terminal_length_cmd
);
4462 install_element(VIEW_NODE
, &vtysh_terminal_no_length_cmd
);
4463 install_element(VIEW_NODE
, &vtysh_show_daemons_cmd
);
4465 install_element(VIEW_NODE
, &vtysh_ping_cmd
);
4466 install_element(VIEW_NODE
, &vtysh_ping_ip_cmd
);
4467 install_element(VIEW_NODE
, &vtysh_traceroute_cmd
);
4468 install_element(VIEW_NODE
, &vtysh_traceroute_ip_cmd
);
4469 install_element(VIEW_NODE
, &vtysh_mtrace_cmd
);
4470 install_element(VIEW_NODE
, &vtysh_ping6_cmd
);
4471 install_element(VIEW_NODE
, &vtysh_traceroute6_cmd
);
4472 #if defined(HAVE_SHELL_ACCESS)
4473 install_element(VIEW_NODE
, &vtysh_telnet_cmd
);
4474 install_element(VIEW_NODE
, &vtysh_telnet_port_cmd
);
4475 install_element(VIEW_NODE
, &vtysh_ssh_cmd
);
4477 #if defined(HAVE_SHELL_ACCESS)
4478 install_element(ENABLE_NODE
, &vtysh_start_shell_cmd
);
4479 install_element(ENABLE_NODE
, &vtysh_start_bash_cmd
);
4480 install_element(ENABLE_NODE
, &vtysh_start_zsh_cmd
);
4484 install_element(VIEW_NODE
, &vtysh_show_error_code_cmd
);
4485 install_element(ENABLE_NODE
, &vtysh_show_debugging_cmd
);
4486 install_element(ENABLE_NODE
, &vtysh_show_debugging_hashtable_cmd
);
4487 install_element(ENABLE_NODE
, &vtysh_debug_all_cmd
);
4488 install_element(CONFIG_NODE
, &vtysh_debug_all_cmd
);
4489 install_element(ENABLE_NODE
, &vtysh_debug_memstats_cmd
);
4490 install_element(CONFIG_NODE
, &vtysh_debug_memstats_cmd
);
4491 install_element(ENABLE_NODE
, &vtysh_debug_uid_backtrace_cmd
);
4492 install_element(CONFIG_NODE
, &vtysh_debug_uid_backtrace_cmd
);
4495 install_element(ENABLE_NODE
, &show_config_running_cmd
);
4496 install_element(ENABLE_NODE
, &show_yang_operational_data_cmd
);
4497 install_element(ENABLE_NODE
, &show_yang_module_cmd
);
4498 install_element(ENABLE_NODE
, &show_yang_module_detail_cmd
);
4499 install_element(ENABLE_NODE
, &debug_nb_cmd
);
4500 install_element(CONFIG_NODE
, &debug_nb_cmd
);
4502 /* misc lib show commands */
4503 install_element(VIEW_NODE
, &vtysh_show_history_cmd
);
4504 install_element(VIEW_NODE
, &vtysh_show_memory_cmd
);
4505 install_element(VIEW_NODE
, &vtysh_show_modules_cmd
);
4506 install_element(VIEW_NODE
, &vtysh_show_work_queues_cmd
);
4507 install_element(VIEW_NODE
, &vtysh_show_work_queues_daemon_cmd
);
4508 install_element(VIEW_NODE
, &vtysh_show_thread_cmd
);
4509 install_element(VIEW_NODE
, &vtysh_show_poll_cmd
);
4512 install_element(VIEW_NODE
, &vtysh_show_logging_cmd
);
4514 install_element(CONFIG_NODE
, &vtysh_service_password_encrypt_cmd
);
4515 install_element(CONFIG_NODE
, &no_vtysh_service_password_encrypt_cmd
);
4517 install_element(CONFIG_NODE
, &vtysh_password_cmd
);
4518 install_element(CONFIG_NODE
, &no_vtysh_password_cmd
);
4519 install_element(CONFIG_NODE
, &vtysh_enable_password_cmd
);
4520 install_element(CONFIG_NODE
, &no_vtysh_enable_password_cmd
);