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 #include <readline/readline.h>
30 #include <readline/history.h>
40 #include "vtysh/vtysh.h"
41 #include "vtysh/vtysh_daemons.h"
46 #include "command_graph.h"
51 DEFINE_MTYPE_STATIC(MVTYSH
, VTYSH_CMD
, "Vtysh cmd copy");
56 /* VTY shell pager name. */
57 char *vtysh_pager_name
= NULL
;
59 /* VTY shell client structure */
64 char path
[MAXPATHLEN
];
65 struct vtysh_client
*next
;
68 /* Some utility functions for working on vtysh-specific vty tasks */
70 static FILE *vty_open_pager(struct vty
*vty
)
75 if (!vtysh_pager_name
)
78 vty
->of_saved
= vty
->of
;
79 vty
->of
= popen(vtysh_pager_name
, "w");
80 if (vty
->of
== NULL
) {
81 vty
->of
= vty
->of_saved
;
91 static int vty_close_pager(struct vty
*vty
)
97 if (pclose(vty
->of
) == -1) {
102 vty
->of
= vty
->of_saved
;
103 vty
->is_paged
= false;
108 static void vtysh_pager_envdef(bool fallback
)
112 pager_defined
= getenv("VTYSH_PAGER");
115 vtysh_pager_name
= strdup(pager_defined
);
117 vtysh_pager_name
= strdup(VTYSH_PAGER
);
122 struct vtysh_client vtysh_client
[] = {
123 {.fd
= -1, .name
= "zebra", .flag
= VTYSH_ZEBRA
, .next
= NULL
},
124 {.fd
= -1, .name
= "ripd", .flag
= VTYSH_RIPD
, .next
= NULL
},
125 {.fd
= -1, .name
= "ripngd", .flag
= VTYSH_RIPNGD
, .next
= NULL
},
126 {.fd
= -1, .name
= "ospfd", .flag
= VTYSH_OSPFD
, .next
= NULL
},
127 {.fd
= -1, .name
= "ospf6d", .flag
= VTYSH_OSPF6D
, .next
= NULL
},
128 {.fd
= -1, .name
= "ldpd", .flag
= VTYSH_LDPD
, .next
= NULL
},
129 {.fd
= -1, .name
= "bgpd", .flag
= VTYSH_BGPD
, .next
= NULL
},
130 {.fd
= -1, .name
= "isisd", .flag
= VTYSH_ISISD
, .next
= NULL
},
131 {.fd
= -1, .name
= "pimd", .flag
= VTYSH_PIMD
, .next
= NULL
},
132 {.fd
= -1, .name
= "nhrpd", .flag
= VTYSH_NHRPD
, .next
= NULL
},
133 {.fd
= -1, .name
= "eigrpd", .flag
= VTYSH_EIGRPD
, .next
= NULL
},
134 {.fd
= -1, .name
= "babeld", .flag
= VTYSH_BABELD
, .next
= NULL
},
135 {.fd
= -1, .name
= "sharpd", .flag
= VTYSH_SHARPD
, .next
= NULL
},
136 {.fd
= -1, .name
= "fabricd", .flag
= VTYSH_FABRICD
, .next
= NULL
},
137 {.fd
= -1, .name
= "watchfrr", .flag
= VTYSH_WATCHFRR
, .next
= NULL
},
138 {.fd
= -1, .name
= "pbrd", .flag
= VTYSH_PBRD
, .next
= NULL
},
139 {.fd
= -1, .name
= "staticd", .flag
= VTYSH_STATICD
, .next
= NULL
},
140 {.fd
= -1, .name
= "bfdd", .flag
= VTYSH_BFDD
, .next
= NULL
},
141 {.fd
= -1, .name
= "vrrpd", .flag
= VTYSH_VRRPD
, .next
= NULL
},
142 {.fd
= -1, .name
= "pathd", .flag
= VTYSH_PATHD
, .next
= NULL
},
145 /* Searches for client by name, returns index */
146 static int vtysh_client_lookup(const char *name
)
150 for (unsigned int i
= 0; i
< array_size(vtysh_client
); i
++) {
151 if (strmatch(vtysh_client
[i
].name
, name
)) {
160 enum vtysh_write_integrated vtysh_write_integrated
=
161 WRITE_INTEGRATED_UNSPECIFIED
;
163 static int vtysh_reconnect(struct vtysh_client
*vclient
);
165 static void vclient_close(struct vtysh_client
*vclient
)
167 if (vclient
->fd
>= 0) {
170 "Warning: closing connection to %s because of an I/O error!\n",
173 /* indicate as candidate for reconnect */
174 vclient
->fd
= VTYSH_WAS_ACTIVE
;
179 * Send a CLI command to a client and read the response.
181 * Output will be printed to vty->of. If you want to suppress output, set that
185 * the client to send the command to
188 * the command to send
191 * if non-null, this will be called with each line of output received from
192 * the client passed in the second parameter
195 * optional first argument to pass to callback
200 static int vtysh_client_run(struct vtysh_client
*vclient
, const char *line
,
201 void (*callback
)(void *, const char *), void *cbarg
)
205 char *buf
= stackbuf
;
206 size_t bufsz
= sizeof(stackbuf
);
207 char *bufvalid
, *end
= NULL
;
208 char terminator
[3] = {0, 0, 0};
210 /* vclinet was previously active, try to reconnect */
211 if (vclient
->fd
== VTYSH_WAS_ACTIVE
) {
212 ret
= vtysh_reconnect(vclient
);
220 ret
= write(vclient
->fd
, line
, strlen(line
) + 1);
222 /* close connection and try to reconnect */
223 vclient_close(vclient
);
224 ret
= vtysh_reconnect(vclient
);
228 ret
= write(vclient
->fd
, line
, strlen(line
) + 1);
236 read(vclient
->fd
, bufvalid
, buf
+ bufsz
- bufvalid
- 1);
238 if (nread
< 0 && (errno
== EINTR
|| errno
== EAGAIN
))
244 "vtysh: error reading from %s: %s (%d)",
245 vclient
->name
, safe_strerror(errno
),
252 /* Null terminate so we may pass this to *printf later. */
256 * We expect string output from daemons, so instead of looking
257 * for the full 3 null bytes of the terminator, we check for
258 * just one instead and assume it is the first byte of the
259 * terminator. The presence of the full terminator is checked
262 if (bufvalid
- buf
>= 4)
263 end
= memmem(bufvalid
- 4, 4, "\0", 1);
266 * calculate # bytes we have, up to & not including the
267 * terminator if present
269 size_t textlen
= (end
? end
: bufvalid
) - buf
;
272 /* feed line processing callback if present */
273 while (callback
&& bufvalid
> buf
&& (end
> buf
|| !end
)) {
274 textlen
= (end
? end
: bufvalid
) - buf
;
275 char *eol
= memchr(buf
, '\n', textlen
);
281 * no line break, end of input, no text left
282 * before end; nothing to write
286 /* no nl, end of input, but some text left */
288 else if (bufvalid
== buf
+ bufsz
- 1) {
290 * no nl, no end of input, no buffer space;
296 if (buf
== stackbuf
) {
297 new = XMALLOC(MTYPE_TMP
, bufsz
);
298 memcpy(new, stackbuf
, sizeof(stackbuf
));
300 new = XREALLOC(MTYPE_TMP
, buf
, bufsz
);
302 bufvalid
= bufvalid
- buf
+ new;
304 /* if end != NULL, we won't be reading more
314 /* eol is at line end now, either \n => \0 or \0\0\0 */
315 assert(eol
&& eol
<= bufvalid
);
318 vty_out(vty
, "%s\n", buf
);
320 callback(cbarg
, buf
);
322 /* shift back data and adjust bufvalid */
323 memmove(buf
, eol
, bufvalid
- eol
);
324 bufvalid
-= eol
- buf
;
329 /* else if no callback, dump raw */
332 vty_out(vty
, "%s", buf
);
333 memmove(buf
, buf
+ textlen
, bufvalid
- buf
- textlen
);
339 * ----------------------------------------------------
340 * At this point `buf` should be in one of two states:
341 * - Empty (i.e. buf == bufvalid)
342 * - Contains up to 4 bytes of the terminator
343 * ----------------------------------------------------
345 assert(((buf
== bufvalid
)
346 || (bufvalid
- buf
<= 4 && buf
[0] == 0x00)));
349 /* if we have the terminator, break */
350 if (end
&& bufvalid
- buf
== 4) {
351 assert(!memcmp(buf
, terminator
, 3));
360 vclient_close(vclient
);
364 XFREE(MTYPE_TMP
, buf
);
368 static int vtysh_client_run_all(struct vtysh_client
*head_client
,
369 const char *line
, int continue_on_err
,
370 void (*callback
)(void *, const char *),
373 struct vtysh_client
*client
;
374 int rc
, rc_all
= CMD_SUCCESS
;
375 int correct_instance
= 0, wrong_instance
= 0;
377 for (client
= head_client
; client
; client
= client
->next
) {
378 rc
= vtysh_client_run(client
, line
, callback
, cbarg
);
379 if (rc
== CMD_NOT_MY_INSTANCE
) {
385 if (rc
!= CMD_SUCCESS
) {
386 if (!continue_on_err
)
391 if (wrong_instance
&& !correct_instance
&& vty
->of
) {
393 "%% [%s]: command ignored as it targets an instance that is not running\n",
395 rc_all
= CMD_WARNING_CONFIG_FAILED
;
401 * Execute command against all daemons.
404 * where to start walking in the daemon list
407 * the specific command to execute
412 static int vtysh_client_execute(struct vtysh_client
*head_client
,
415 return vtysh_client_run_all(head_client
, line
, 0, NULL
, NULL
);
418 /* Execute by name */
419 static int vtysh_client_execute_name(const char *name
, const char *line
)
421 int ret
= CMD_SUCCESS
;
424 idx_client
= vtysh_client_lookup(name
);
425 if (idx_client
!= -1)
426 ret
= vtysh_client_execute(&vtysh_client
[idx_client
], line
);
428 vty_out(vty
, "Client not found\n");
436 * Retrieve all running config from daemons and parse it with the vtysh config
437 * parser. Returned output is not displayed to the user.
440 * where to start walking in the daemon list
443 * the specific command to execute
445 static void vtysh_client_config(struct vtysh_client
*head_client
, char *line
)
447 /* watchfrr currently doesn't load any config, and has some hardcoded
448 * settings that show up in "show run". skip it here (for now at
449 * least) so we don't get that mangled up in config-write.
451 if (head_client
->flag
== VTYSH_WATCHFRR
)
454 /* suppress output to user */
455 vty
->of_saved
= vty
->of
;
457 vtysh_client_run_all(head_client
, line
, 1, vtysh_config_parse_line
,
459 vty
->of
= vty
->of_saved
;
462 /* Command execution over the vty interface. */
463 static int vtysh_execute_func(const char *line
, int pager
)
468 const struct cmd_element
*cmd
;
470 int saved_ret
, saved_node
;
472 /* Split readline string up into the vector. */
473 vline
= cmd_make_strvec(line
);
479 if (strncmp("en", vector_slot(vline
, 0), 2) == 0) {
480 cmd_free_strvec(vline
);
481 vty_out(vty
, "%% Command not allowed: enable\n");
486 saved_ret
= ret
= cmd_execute(vty
, line
, &cmd
, 1);
487 saved_node
= vty
->node
;
490 * If command doesn't succeeded in current node, try to walk up in node
491 * tree. Changing vty->node is enough to try it just out without actual
492 * walkup in the vtysh.
494 while (ret
!= CMD_SUCCESS
&& ret
!= CMD_SUCCESS_DAEMON
495 && ret
!= CMD_WARNING
&& ret
!= CMD_WARNING_CONFIG_FAILED
496 && ret
!= CMD_ERR_AMBIGUOUS
&& ret
!= CMD_ERR_INCOMPLETE
497 && vty
->node
> CONFIG_NODE
) {
498 vty
->node
= node_parent(vty
->node
);
499 ret
= cmd_execute(vty
, line
, &cmd
, 1);
503 vty
->node
= saved_node
;
506 * If command succeeded in any other node than current (tried > 0) we
507 * have to move into node in the vtysh where it succeeded.
509 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
510 || ret
== CMD_WARNING
) {
511 if ((saved_node
== BGP_VPNV4_NODE
512 || saved_node
== BGP_VPNV6_NODE
513 || saved_node
== BGP_IPV4_NODE
514 || saved_node
== BGP_IPV6_NODE
515 || saved_node
== BGP_FLOWSPECV4_NODE
516 || saved_node
== BGP_FLOWSPECV6_NODE
517 || saved_node
== BGP_IPV4M_NODE
518 || saved_node
== BGP_IPV4L_NODE
519 || saved_node
== BGP_IPV6L_NODE
520 || saved_node
== BGP_IPV6M_NODE
521 || saved_node
== BGP_EVPN_NODE
522 || saved_node
== LDP_IPV4_NODE
523 || saved_node
== LDP_IPV6_NODE
)
525 vtysh_execute("exit-address-family");
526 } else if ((saved_node
== BGP_EVPN_VNI_NODE
) && (tried
== 1)) {
527 vtysh_execute("exit-vni");
528 } else if (saved_node
== BGP_VRF_POLICY_NODE
&& (tried
== 1)) {
529 vtysh_execute("exit-vrf-policy");
530 } else if ((saved_node
== BGP_VNC_DEFAULTS_NODE
531 || saved_node
== BGP_VNC_NVE_GROUP_NODE
532 || saved_node
== BGP_VNC_L2_GROUP_NODE
)
534 vtysh_execute("exit-vnc");
535 } else if (saved_node
== VRF_NODE
&& (tried
== 1)) {
536 vtysh_execute("exit-vrf");
537 } else if ((saved_node
== KEYCHAIN_KEY_NODE
538 || saved_node
== LDP_PSEUDOWIRE_NODE
539 || saved_node
== LDP_IPV4_IFACE_NODE
540 || saved_node
== LDP_IPV6_IFACE_NODE
)
542 vtysh_execute("exit");
543 } else if ((saved_node
== SR_SEGMENT_LIST_NODE
544 || saved_node
== SR_POLICY_NODE
545 || saved_node
== SR_CANDIDATE_DYN_NODE
546 || saved_node
== PCEP_NODE
547 || saved_node
== PCEP_PCE_CONFIG_NODE
548 || saved_node
== PCEP_PCE_NODE
549 || saved_node
== PCEP_PCC_NODE
)
551 vtysh_execute("exit");
553 vtysh_execute("end");
554 vtysh_execute("configure");
558 * If command didn't succeed in any node, continue with return value
565 cmd_free_strvec(vline
);
570 case CMD_WARNING_CONFIG_FAILED
:
571 if (vty
->type
== VTY_FILE
)
572 vty_out(vty
, "Warning...\n");
574 case CMD_ERR_AMBIGUOUS
:
575 vty_out(vty
, "%% Ambiguous command: %s\n", line
);
577 case CMD_ERR_NO_MATCH
:
578 vty_out(vty
, "%% Unknown command: %s\n", line
);
580 case CMD_ERR_INCOMPLETE
:
581 vty_out(vty
, "%% Command incomplete: %s\n", line
);
583 case CMD_SUCCESS_DAEMON
: {
585 * FIXME: Don't open pager for exit commands. popen() causes
586 * problems if exited from vtysh at all. This hack shouldn't
587 * cause any problem but is really ugly.
589 if (pager
&& strncmp(line
, "exit", 4))
592 if (!strcmp(cmd
->string
, "configure")) {
593 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
594 cmd_stat
= vtysh_client_execute(
595 &vtysh_client
[i
], line
);
596 if (cmd_stat
== CMD_WARNING
)
602 vline
= cmd_make_strvec(line
);
607 vty_close_pager(vty
);
611 ret
= cmd_execute_command(vline
, vty
, &cmd
, 1);
612 cmd_free_strvec(vline
);
613 if (ret
!= CMD_SUCCESS_DAEMON
)
615 } else if (cmd
->func
) {
616 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
621 cmd_stat
= CMD_SUCCESS
;
622 struct vtysh_client
*vc
;
623 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
624 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
625 if (vtysh_client
[i
].fd
< 0
626 && (cmd
->daemon
== vtysh_client
[i
].flag
)) {
627 for (vc
= &vtysh_client
[i
]; vc
;
629 if (vc
->fd
== VTYSH_WAS_ACTIVE
)
632 if (vtysh_client
[i
].fd
< 0
633 && (cmd
->daemon
== vtysh_client
[i
].flag
)) {
634 bool any_inst
= false;
635 for (vc
= &vtysh_client
[i
]; vc
;
641 "%s is not running\n",
642 vtysh_client
[i
].name
);
646 cmd_stat
= vtysh_client_execute(
647 &vtysh_client
[i
], line
);
648 if (cmd_stat
!= CMD_SUCCESS
)
652 if (cmd_stat
!= CMD_SUCCESS
)
656 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
660 vty_close_pager(vty
);
665 int vtysh_execute_no_pager(const char *line
)
667 return vtysh_execute_func(line
, 0);
670 int vtysh_execute(const char *line
)
672 return vtysh_execute_func(line
, 1);
675 static char *trim(char *s
)
686 while (end
>= s
&& isspace((unsigned char)*end
))
690 while (*s
&& isspace((unsigned char)*s
))
696 int vtysh_mark_file(const char *filename
)
704 const struct cmd_element
*cmd
;
705 int saved_ret
, prev_node
;
707 char *vty_buf_copy
= NULL
;
708 char *vty_buf_trimmed
= NULL
;
710 if (strncmp("-", filename
, 1) == 0)
713 confp
= fopen(filename
, "r");
716 fprintf(stderr
, "%% Can't open config file %s due to '%s'.\n",
717 filename
, safe_strerror(errno
));
718 return CMD_ERR_NO_FILE
;
722 vty
->wfd
= STDOUT_FILENO
;
723 vty
->type
= VTY_TERM
;
724 vty
->node
= CONFIG_NODE
;
726 vtysh_execute_no_pager("enable");
727 vtysh_execute_no_pager("configure");
728 vty_buf_copy
= XCALLOC(MTYPE_VTYSH_CMD
, VTY_BUFSIZ
);
730 while (fgets(vty
->buf
, VTY_BUFSIZ
, confp
)) {
733 strlcpy(vty_buf_copy
, vty
->buf
, VTY_BUFSIZ
);
734 vty_buf_trimmed
= trim(vty_buf_copy
);
737 case LDP_IPV4_IFACE_NODE
:
738 if (strncmp(vty_buf_copy
, " ", 3)) {
739 vty_out(vty
, " exit-ldp-if\n");
740 vty
->node
= LDP_IPV4_NODE
;
743 case LDP_IPV6_IFACE_NODE
:
744 if (strncmp(vty_buf_copy
, " ", 3)) {
745 vty_out(vty
, " exit-ldp-if\n");
746 vty
->node
= LDP_IPV6_NODE
;
749 case LDP_PSEUDOWIRE_NODE
:
750 if (strncmp(vty_buf_copy
, " ", 2)) {
751 vty_out(vty
, " exit\n");
752 vty
->node
= LDP_L2VPN_NODE
;
755 case SR_CANDIDATE_DYN_NODE
:
756 if (strncmp(vty_buf_copy
, " ", 2)) {
757 vty_out(vty
, " exit\n");
758 vty
->node
= SR_POLICY_NODE
;
765 if (vty_buf_trimmed
[0] == '!' || vty_buf_trimmed
[0] == '#') {
766 vty_out(vty
, "%s", vty
->buf
);
770 /* Split readline string up into the vector. */
771 vline
= cmd_make_strvec(vty
->buf
);
774 vty_out(vty
, "%s", vty
->buf
);
779 * Ignore the "end" lines, we will generate these where
782 if (strlen(vty_buf_trimmed
) == 3
783 && strncmp("end", vty_buf_trimmed
, 3) == 0) {
784 cmd_free_strvec(vline
);
788 prev_node
= vty
->node
;
789 saved_ret
= ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
792 * If command doesn't succeeded in current node, try to walk up
793 * in node tree. Changing vty->node is enough to try it just
794 * out without actual walkup in the vtysh.
796 while (ret
!= CMD_SUCCESS
&& ret
!= CMD_SUCCESS_DAEMON
797 && ret
!= CMD_WARNING
&& ret
!= CMD_WARNING_CONFIG_FAILED
798 && ret
!= CMD_ERR_AMBIGUOUS
&& ret
!= CMD_ERR_INCOMPLETE
799 && vty
->node
> CONFIG_NODE
) {
800 vty
->node
= node_parent(vty
->node
);
801 ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
806 * If command succeeded in any other node than current (tried >
807 * 0) we have to move into node in the vtysh where it
810 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
811 || ret
== CMD_WARNING
) {
812 if ((prev_node
== BGP_VPNV4_NODE
813 || prev_node
== BGP_VPNV6_NODE
814 || prev_node
== BGP_IPV4_NODE
815 || prev_node
== BGP_IPV6_NODE
816 || prev_node
== BGP_FLOWSPECV4_NODE
817 || prev_node
== BGP_FLOWSPECV6_NODE
818 || prev_node
== BGP_IPV4L_NODE
819 || prev_node
== BGP_IPV6L_NODE
820 || prev_node
== BGP_IPV4M_NODE
821 || prev_node
== BGP_IPV6M_NODE
822 || prev_node
== BGP_EVPN_NODE
)
824 vty_out(vty
, "exit-address-family\n");
825 } else if ((prev_node
== BGP_EVPN_VNI_NODE
)
827 vty_out(vty
, "exit-vni\n");
828 } else if ((prev_node
== KEYCHAIN_KEY_NODE
)
830 vty_out(vty
, "exit\n");
831 } else if ((prev_node
== BFD_PEER_NODE
)
833 vty_out(vty
, "exit\n");
834 } else if (((prev_node
== SEGMENT_ROUTING_NODE
)
835 || (prev_node
== SR_TRAFFIC_ENG_NODE
)
836 || (prev_node
== SR_SEGMENT_LIST_NODE
)
837 || (prev_node
== SR_POLICY_NODE
)
838 || (prev_node
== SR_CANDIDATE_DYN_NODE
)
839 || (prev_node
== PCEP_NODE
)
840 || (prev_node
== PCEP_PCE_CONFIG_NODE
)
841 || (prev_node
== PCEP_PCE_NODE
)
842 || (prev_node
== PCEP_PCC_NODE
))
844 ending
= (vty
->node
!= SEGMENT_ROUTING_NODE
)
845 && (vty
->node
!= SR_TRAFFIC_ENG_NODE
)
846 && (vty
->node
!= SR_SEGMENT_LIST_NODE
)
847 && (vty
->node
!= SR_POLICY_NODE
)
848 && (vty
->node
!= SR_CANDIDATE_DYN_NODE
)
849 && (vty
->node
!= PCEP_NODE
)
850 && (vty
->node
!= PCEP_PCE_CONFIG_NODE
)
851 && (vty
->node
!= PCEP_PCE_NODE
)
852 && (vty
->node
!= PCEP_PCC_NODE
);
856 vty_out(vty
, "exit\n");
858 vty_out(vty
, "end\n");
860 vty_out(vty
, "end\n");
864 * If command didn't succeed in any node, continue with return
865 * value from first try.
869 vty
->node
= prev_node
;
872 cmd_free_strvec(vline
);
875 case CMD_WARNING_CONFIG_FAILED
:
876 if (vty
->type
== VTY_FILE
)
877 fprintf(stderr
, "line %d: Warning...: %s\n",
881 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
883 case CMD_ERR_AMBIGUOUS
:
884 fprintf(stderr
, "line %d: %% Ambiguous command: %s\n",
888 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
889 return CMD_ERR_AMBIGUOUS
;
890 case CMD_ERR_NO_MATCH
:
891 fprintf(stderr
, "line %d: %% Unknown command: %s\n",
895 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
896 return CMD_ERR_NO_MATCH
;
897 case CMD_ERR_INCOMPLETE
:
898 fprintf(stderr
, "line %d: %% Command incomplete: %s\n",
902 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
903 return CMD_ERR_INCOMPLETE
;
905 vty_out(vty
, "%s", vty
->buf
);
906 if (strmatch(vty_buf_trimmed
, "exit-vrf"))
907 vty_out(vty
, "end\n");
909 case CMD_SUCCESS_DAEMON
: {
912 vty_out(vty
, "%s", vty
->buf
);
913 if (strmatch(vty_buf_trimmed
, "exit-vrf"))
914 vty_out(vty
, "end\n");
915 cmd_stat
= vtysh_client_execute(&vtysh_client
[0],
917 if (cmd_stat
!= CMD_SUCCESS
)
921 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
925 /* This is the end */
926 vty_out(vty
, "\nend\n");
928 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
936 /* Configration make from file. */
937 int vtysh_config_from_file(struct vty
*vty
, FILE *fp
)
940 const struct cmd_element
*cmd
;
942 /* once we have an error, we remember & return that */
943 int retcode
= CMD_SUCCESS
;
945 while (fgets(vty
->buf
, VTY_BUFSIZ
, fp
)) {
948 ret
= command_config_read_one_line(vty
, &cmd
, lineno
, 1);
952 case CMD_WARNING_CONFIG_FAILED
:
953 if (vty
->type
== VTY_FILE
)
954 fprintf(stderr
, "line %d: Warning[%d]...: %s\n",
955 lineno
, vty
->node
, vty
->buf
);
959 case CMD_ERR_AMBIGUOUS
:
961 "line %d: %% Ambiguous command[%d]: %s\n",
962 lineno
, vty
->node
, vty
->buf
);
963 retcode
= CMD_ERR_AMBIGUOUS
;
965 case CMD_ERR_NO_MATCH
:
966 fprintf(stderr
, "line %d: %% Unknown command[%d]: %s",
967 lineno
, vty
->node
, vty
->buf
);
968 retcode
= CMD_ERR_NO_MATCH
;
970 case CMD_ERR_INCOMPLETE
:
972 "line %d: %% Command incomplete[%d]: %s\n",
973 lineno
, vty
->node
, vty
->buf
);
974 retcode
= CMD_ERR_INCOMPLETE
;
976 case CMD_SUCCESS_DAEMON
: {
978 int cmd_stat
= CMD_SUCCESS
;
980 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
981 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
982 cmd_stat
= vtysh_client_execute(
983 &vtysh_client
[i
], vty
->buf
);
985 * CMD_WARNING - Can mean that the
986 * command was parsed successfully but
987 * it was already entered in a few
988 * spots. As such if we receive a
989 * CMD_WARNING from a daemon we
990 * shouldn't stop talking to the other
991 * daemons for the particular command.
993 if (cmd_stat
!= CMD_SUCCESS
994 && cmd_stat
!= CMD_WARNING
) {
996 "line %d: Failure to communicate[%d] to %s, line: %s\n",
998 vtysh_client
[i
].name
,
1005 if (cmd_stat
!= CMD_SUCCESS
)
1009 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
1018 * Function processes cli commands terminated with '?' character when entered
1019 * through either 'vtysh' or 'vtysh -c' interfaces.
1021 static int vtysh_process_questionmark(const char *input
, int input_len
)
1025 vector vline
, describe
;
1026 struct cmd_token
*token
;
1031 vline
= cmd_make_strvec(input
);
1033 /* In case of '> ?'. */
1034 if (vline
== NULL
) {
1035 vline
= vector_init(1);
1036 vector_set(vline
, NULL
);
1037 } else if (input_len
&& isspace((unsigned char)input
[input_len
- 1]))
1038 vector_set(vline
, NULL
);
1040 describe
= cmd_describe_command(vline
, vty
, &ret
);
1042 /* Ambiguous and no match error. */
1044 case CMD_ERR_AMBIGUOUS
:
1045 cmd_free_strvec(vline
);
1046 vector_free(describe
);
1047 vty_out(vty
, "%% Ambiguous command.\n");
1050 case CMD_ERR_NO_MATCH
:
1051 cmd_free_strvec(vline
);
1053 vector_free(describe
);
1054 vty_out(vty
, "%% There is no matched command.\n");
1059 /* Get width of command string. */
1061 for (i
= 0; i
< vector_active(describe
); i
++)
1062 if ((token
= vector_slot(describe
, i
)) != NULL
) {
1063 if (token
->text
[0] == '\0')
1066 int len
= strlen(token
->text
);
1072 for (i
= 0; i
< vector_active(describe
); i
++)
1073 if ((token
= vector_slot(describe
, i
)) != NULL
) {
1075 vty_out(vty
, " %-s\n", token
->text
);
1077 vty_out(vty
, " %-*s %s\n", width
, token
->text
,
1080 if (IS_VARYING_TOKEN(token
->type
)) {
1081 const char *ref
= vector_slot(
1082 vline
, vector_active(vline
) - 1);
1084 vector varcomps
= vector_init(VECTOR_MIN_SIZE
);
1085 cmd_variable_complete(token
, ref
, varcomps
);
1087 if (vector_active(varcomps
) > 0) {
1089 rl_get_screen_size(&rows
, &cols
);
1091 char *ac
= cmd_variable_comp2str(
1093 vty_out(vty
, "%s\n", ac
);
1094 XFREE(MTYPE_TMP
, ac
);
1097 vector_free(varcomps
);
1101 cmd_free_strvec(vline
);
1102 vector_free(describe
);
1108 * Entry point for user commands terminated with '?' character and typed through
1109 * the usual vtysh's stdin interface. This is the function being registered with
1112 static int vtysh_rl_describe(int a
, int b
)
1118 ret
= vtysh_process_questionmark(rl_line_buffer
, rl_end
);
1125 * Function in charged of processing vtysh instructions terminating with '?'
1126 * character and received through the 'vtysh -c' interface. If user's
1127 * instruction is well-formatted, we will call the same processing routine
1128 * utilized by the traditional vtysh's stdin interface.
1130 int vtysh_execute_command_questionmark(char *input
)
1132 int input_len
, qmark_count
= 0;
1135 if (!(input
&& *input
))
1138 /* Finding out question_mark count and strlen */
1139 for (str
= input
; *str
; ++str
) {
1143 input_len
= str
- input
;
1146 * Verify that user's input terminates in '?' and that patterns such as
1147 * 'cmd ? subcmd ?' are prevented.
1149 if (qmark_count
!= 1 || input
[input_len
- 1] != '?')
1153 * Questionmark-processing function is not expecting to receive '?'
1154 * character in input string.
1156 input
[input_len
- 1] = '\0';
1158 return vtysh_process_questionmark(input
, input_len
- 1);
1161 /* Result of cmd_complete_command() call will be stored here
1162 * and used in new_completion() in order to put the space in
1163 * correct places only. */
1164 int complete_status
;
1166 static char *command_generator(const char *text
, int state
)
1169 static char **matched
= NULL
;
1170 static int index
= 0;
1176 if (vty
->node
== AUTH_NODE
|| vty
->node
== AUTH_ENABLE_NODE
)
1179 vline
= cmd_make_strvec(rl_line_buffer
);
1184 isspace((unsigned char)rl_line_buffer
[rl_end
- 1]))
1185 vector_set(vline
, NULL
);
1187 matched
= cmd_complete_command(vline
, vty
, &complete_status
);
1188 cmd_free_strvec(vline
);
1191 if (matched
&& matched
[index
]) {
1192 XCOUNTFREE(MTYPE_COMPLETION
, matched
[index
]);
1193 return matched
[index
++];
1196 XFREE(MTYPE_TMP
, matched
);
1201 static char **new_completion(const char *text
, int start
, int end
)
1205 matches
= rl_completion_matches(text
, command_generator
);
1209 if (complete_status
!= CMD_COMPLETE_FULL_MATCH
)
1210 /* only append a space on full match */
1211 rl_completion_append_character
= '\0';
1217 /* Vty node structures. */
1219 static struct cmd_node bgp_node
= {
1222 .parent_node
= CONFIG_NODE
,
1223 .prompt
= "%s(config-router)# ",
1225 #endif /* HAVE_BGPD */
1227 static struct cmd_node rip_node
= {
1230 .parent_node
= CONFIG_NODE
,
1231 .prompt
= "%s(config-router)# ",
1235 static struct cmd_node isis_node
= {
1238 .parent_node
= CONFIG_NODE
,
1239 .prompt
= "%s(config-router)# ",
1241 #endif /* HAVE_ISISD */
1244 static struct cmd_node openfabric_node
= {
1245 .name
= "openfabric",
1246 .node
= OPENFABRIC_NODE
,
1247 .parent_node
= CONFIG_NODE
,
1248 .prompt
= "%s(config-router)# ",
1250 #endif /* HAVE_FABRICD */
1252 static struct cmd_node interface_node
= {
1253 .name
= "interface",
1254 .node
= INTERFACE_NODE
,
1255 .parent_node
= CONFIG_NODE
,
1256 .prompt
= "%s(config-if)# ",
1259 static struct cmd_node pw_node
= {
1262 .parent_node
= CONFIG_NODE
,
1263 .prompt
= "%s(config-pw)# ",
1266 static struct cmd_node segment_routing_node
= {
1267 .name
= "segment-routing",
1268 .node
= SEGMENT_ROUTING_NODE
,
1269 .parent_node
= CONFIG_NODE
,
1270 .prompt
= "%s(config-sr)# ",
1273 #if defined(HAVE_PATHD)
1274 static struct cmd_node sr_traffic_eng_node
= {
1275 .name
= "sr traffic-eng",
1276 .node
= SR_TRAFFIC_ENG_NODE
,
1277 .parent_node
= SEGMENT_ROUTING_NODE
,
1278 .prompt
= "%s(config-sr-te)# ",
1281 static struct cmd_node srte_segment_list_node
= {
1282 .name
= "srte segment-list",
1283 .node
= SR_SEGMENT_LIST_NODE
,
1284 .parent_node
= SR_TRAFFIC_ENG_NODE
,
1285 .prompt
= "%s(config-sr-te-segment-list)# ",
1288 static struct cmd_node srte_policy_node
= {
1289 .name
= "srte policy",
1290 .node
= SR_POLICY_NODE
,
1291 .parent_node
= SR_TRAFFIC_ENG_NODE
,
1292 .prompt
= "%s(config-sr-te-policy)# ",
1295 static struct cmd_node srte_candidate_dyn_node
= {
1296 .name
= "srte candidate-dyn",
1297 .node
= SR_CANDIDATE_DYN_NODE
,
1298 .parent_node
= SR_POLICY_NODE
,
1299 .prompt
= "%s(config-sr-te-candidate)# ",
1302 #if defined(HAVE_PATHD_PCEP)
1303 static struct cmd_node pcep_node
= {
1304 .name
= "srte pcep",
1306 .parent_node
= SR_TRAFFIC_ENG_NODE
,
1307 .prompt
= "%s(config-sr-te-pcep)# "
1310 static struct cmd_node pcep_pcc_node
= {
1311 .name
= "srte pcep pcc",
1312 .node
= PCEP_PCC_NODE
,
1313 .parent_node
= PCEP_NODE
,
1314 .prompt
= "%s(config-sr-te-pcep-pcc)# ",
1317 static struct cmd_node pcep_pce_node
= {
1318 .name
= "srte pcep pce-peer",
1319 .node
= PCEP_PCE_NODE
,
1320 .parent_node
= PCEP_NODE
,
1321 .prompt
= "%s(config-sr-te-pcep-pce-peer)# ",
1324 static struct cmd_node pcep_pce_config_node
= {
1325 .name
= "srte pcep pce-config",
1326 .node
= PCEP_PCE_CONFIG_NODE
,
1327 .parent_node
= PCEP_NODE
,
1328 .prompt
= "%s(pcep-sr-te-pcep-pce-config)# ",
1330 #endif /* HAVE_PATHD_PCEP */
1331 #endif /* HAVE_PATHD */
1333 static struct cmd_node vrf_node
= {
1336 .parent_node
= CONFIG_NODE
,
1337 .prompt
= "%s(config-vrf)# ",
1340 static struct cmd_node nh_group_node
= {
1341 .name
= "nexthop-group",
1342 .node
= NH_GROUP_NODE
,
1343 .parent_node
= CONFIG_NODE
,
1344 .prompt
= "%s(config-nh-group)# ",
1347 static struct cmd_node rmap_node
= {
1350 .parent_node
= CONFIG_NODE
,
1351 .prompt
= "%s(config-route-map)# ",
1354 static struct cmd_node srv6_node
= {
1357 .parent_node
= SEGMENT_ROUTING_NODE
,
1358 .prompt
= "%s(config-srv6)# ",
1361 static struct cmd_node srv6_locs_node
= {
1362 .name
= "srv6-locators",
1363 .node
= SRV6_LOCS_NODE
,
1364 .parent_node
= SRV6_NODE
,
1365 .prompt
= "%s(config-srv6-locators)# ",
1368 static struct cmd_node srv6_loc_node
= {
1369 .name
= "srv6-locator",
1370 .node
= SRV6_LOC_NODE
,
1371 .parent_node
= SRV6_LOCS_NODE
,
1372 .prompt
= "%s(config-srv6-locator)# ",
1376 static struct cmd_node pbr_map_node
= {
1378 .node
= PBRMAP_NODE
,
1379 .parent_node
= CONFIG_NODE
,
1380 .prompt
= "%s(config-pbr-map)# ",
1382 #endif /* HAVE_PBRD */
1384 static struct cmd_node zebra_node
= {
1387 .parent_node
= CONFIG_NODE
,
1388 .prompt
= "%s(config-router)# ",
1392 static struct cmd_node bgp_vpnv4_node
= {
1393 .name
= "bgp vpnv4",
1394 .node
= BGP_VPNV4_NODE
,
1395 .parent_node
= BGP_NODE
,
1396 .prompt
= "%s(config-router-af)# ",
1399 static struct cmd_node bgp_vpnv6_node
= {
1400 .name
= "bgp vpnv6",
1401 .node
= BGP_VPNV6_NODE
,
1402 .parent_node
= BGP_NODE
,
1403 .prompt
= "%s(config-router-af)# ",
1406 static struct cmd_node bgp_flowspecv4_node
= {
1407 .name
= "bgp ipv4 flowspec",
1408 .node
= BGP_FLOWSPECV4_NODE
,
1409 .parent_node
= BGP_NODE
,
1410 .prompt
= "%s(config-router-af)# ",
1413 static struct cmd_node bgp_flowspecv6_node
= {
1414 .name
= "bgp ipv6 flowspec",
1415 .node
= BGP_FLOWSPECV6_NODE
,
1416 .parent_node
= BGP_NODE
,
1417 .prompt
= "%s(config-router-af)# ",
1420 static struct cmd_node bgp_ipv4_node
= {
1421 .name
= "bgp ipv4 unicast",
1422 .node
= BGP_IPV4_NODE
,
1423 .parent_node
= BGP_NODE
,
1424 .prompt
= "%s(config-router-af)# ",
1427 static struct cmd_node bgp_ipv4m_node
= {
1428 .name
= "bgp ipv4 multicast",
1429 .node
= BGP_IPV4M_NODE
,
1430 .parent_node
= BGP_NODE
,
1431 .prompt
= "%s(config-router-af)# ",
1434 static struct cmd_node bgp_ipv4l_node
= {
1435 .name
= "bgp ipv4 labeled unicast",
1436 .node
= BGP_IPV4L_NODE
,
1437 .parent_node
= BGP_NODE
,
1438 .prompt
= "%s(config-router-af)# ",
1441 static struct cmd_node bgp_ipv6_node
= {
1443 .node
= BGP_IPV6_NODE
,
1444 .parent_node
= BGP_NODE
,
1445 .prompt
= "%s(config-router-af)# ",
1448 static struct cmd_node bgp_ipv6m_node
= {
1449 .name
= "bgp ipv6 multicast",
1450 .node
= BGP_IPV6M_NODE
,
1451 .parent_node
= BGP_NODE
,
1452 .prompt
= "%s(config-router-af)# ",
1455 static struct cmd_node bgp_evpn_node
= {
1457 .node
= BGP_EVPN_NODE
,
1458 .parent_node
= BGP_NODE
,
1459 .prompt
= "%s(config-router-af)# ",
1462 static struct cmd_node bgp_evpn_vni_node
= {
1463 .name
= "bgp evpn vni",
1464 .node
= BGP_EVPN_VNI_NODE
,
1465 .parent_node
= BGP_EVPN_NODE
,
1466 .prompt
= "%s(config-router-af-vni)# ",
1469 static struct cmd_node bgp_ipv6l_node
= {
1470 .name
= "bgp ipv6 labeled unicast",
1471 .node
= BGP_IPV6L_NODE
,
1472 .parent_node
= BGP_NODE
,
1473 .prompt
= "%s(config-router-af)# ",
1476 #ifdef ENABLE_BGP_VNC
1477 static struct cmd_node bgp_vnc_defaults_node
= {
1478 .name
= "bgp vnc defaults",
1479 .node
= BGP_VNC_DEFAULTS_NODE
,
1480 .parent_node
= BGP_NODE
,
1481 .prompt
= "%s(config-router-vnc-defaults)# ",
1484 static struct cmd_node bgp_vnc_nve_group_node
= {
1485 .name
= "bgp vnc nve",
1486 .node
= BGP_VNC_NVE_GROUP_NODE
,
1487 .parent_node
= BGP_NODE
,
1488 .prompt
= "%s(config-router-vnc-nve-group)# ",
1491 static struct cmd_node bgp_vrf_policy_node
= {
1492 .name
= "bgp vrf policy",
1493 .node
= BGP_VRF_POLICY_NODE
,
1494 .parent_node
= BGP_NODE
,
1495 .prompt
= "%s(config-router-vrf-policy)# ",
1498 static struct cmd_node bgp_vnc_l2_group_node
= {
1499 .name
= "bgp vnc l2",
1500 .node
= BGP_VNC_L2_GROUP_NODE
,
1501 .parent_node
= BGP_NODE
,
1502 .prompt
= "%s(config-router-vnc-l2-group)# ",
1504 #endif /* ENABLE_BGP_VNC */
1506 static struct cmd_node bmp_node
= {
1509 .parent_node
= BGP_NODE
,
1510 .prompt
= "%s(config-bgp-bmp)# "
1513 static struct cmd_node bgp_srv6_node
= {
1515 .node
= BGP_SRV6_NODE
,
1516 .parent_node
= BGP_NODE
,
1517 .prompt
= "%s(config-router-srv6)# ",
1519 #endif /* HAVE_BGPD */
1522 static struct cmd_node ospf_node
= {
1525 .parent_node
= CONFIG_NODE
,
1526 .prompt
= "%s(config-router)# ",
1528 #endif /* HAVE_OSPFD */
1531 static struct cmd_node eigrp_node
= {
1534 .parent_node
= CONFIG_NODE
,
1535 .prompt
= "%s(config-router)# ",
1537 #endif /* HAVE_EIGRPD */
1540 static struct cmd_node babel_node
= {
1543 .parent_node
= CONFIG_NODE
,
1544 .prompt
= "%s(config-router)# ",
1546 #endif /* HAVE_BABELD */
1548 static struct cmd_node ripng_node
= {
1551 .parent_node
= CONFIG_NODE
,
1552 .prompt
= "%s(config-router)# ",
1556 static struct cmd_node ospf6_node
= {
1559 .parent_node
= CONFIG_NODE
,
1560 .prompt
= "%s(config-ospf6)# ",
1562 #endif /* HAVE_OSPF6D */
1565 static struct cmd_node ldp_node
= {
1568 .parent_node
= CONFIG_NODE
,
1569 .prompt
= "%s(config-ldp)# ",
1572 static struct cmd_node ldp_ipv4_node
= {
1574 .node
= LDP_IPV4_NODE
,
1575 .parent_node
= LDP_NODE
,
1576 .prompt
= "%s(config-ldp-af)# ",
1579 static struct cmd_node ldp_ipv6_node
= {
1581 .node
= LDP_IPV6_NODE
,
1582 .parent_node
= LDP_NODE
,
1583 .prompt
= "%s(config-ldp-af)# ",
1586 static struct cmd_node ldp_ipv4_iface_node
= {
1587 .name
= "ldp ipv4 interface",
1588 .node
= LDP_IPV4_IFACE_NODE
,
1589 .parent_node
= LDP_IPV4_NODE
,
1590 .prompt
= "%s(config-ldp-af-if)# ",
1593 static struct cmd_node ldp_ipv6_iface_node
= {
1594 .name
= "ldp ipv6 interface",
1595 .node
= LDP_IPV6_IFACE_NODE
,
1596 .parent_node
= LDP_IPV6_NODE
,
1597 .prompt
= "%s(config-ldp-af-if)# ",
1600 static struct cmd_node ldp_l2vpn_node
= {
1601 .name
= "ldp l2vpn",
1602 .node
= LDP_L2VPN_NODE
,
1603 .parent_node
= CONFIG_NODE
,
1604 .prompt
= "%s(config-l2vpn)# ",
1607 static struct cmd_node ldp_pseudowire_node
= {
1609 .node
= LDP_PSEUDOWIRE_NODE
,
1610 .parent_node
= LDP_L2VPN_NODE
,
1611 .prompt
= "%s(config-l2vpn-pw)# ",
1613 #endif /* HAVE_LDPD */
1615 static struct cmd_node keychain_node
= {
1617 .node
= KEYCHAIN_NODE
,
1618 .parent_node
= CONFIG_NODE
,
1619 .prompt
= "%s(config-keychain)# ",
1622 static struct cmd_node keychain_key_node
= {
1623 .name
= "keychain key",
1624 .node
= KEYCHAIN_KEY_NODE
,
1625 .parent_node
= KEYCHAIN_NODE
,
1626 .prompt
= "%s(config-keychain-key)# ",
1629 struct cmd_node link_params_node
= {
1630 .name
= "link-params",
1631 .node
= LINK_PARAMS_NODE
,
1632 .parent_node
= INTERFACE_NODE
,
1633 .prompt
= "%s(config-link-params)# ",
1637 static struct cmd_node rpki_node
= {
1640 .parent_node
= CONFIG_NODE
,
1641 .prompt
= "%s(config-rpki)# ",
1643 #endif /* HAVE_BGPD */
1646 static struct cmd_node bfd_node
= {
1649 .parent_node
= CONFIG_NODE
,
1650 .prompt
= "%s(config-bfd)# ",
1653 static struct cmd_node bfd_peer_node
= {
1655 .node
= BFD_PEER_NODE
,
1656 .parent_node
= BFD_NODE
,
1657 .prompt
= "%s(config-bfd-peer)# ",
1660 static struct cmd_node bfd_profile_node
= {
1661 .name
= "bfd profile",
1662 .node
= BFD_PROFILE_NODE
,
1663 .parent_node
= BFD_NODE
,
1664 .prompt
= "%s(config-bfd-profile)# ",
1666 #endif /* HAVE_BFDD */
1668 /* Defined in lib/vty.c */
1669 extern struct cmd_node vty_node
;
1671 /* When '^Z' is received from vty, move down to the enable mode. */
1672 static int vtysh_end(void)
1674 switch (vty
->node
) {
1677 /* Nothing to do. */
1680 vty
->node
= ENABLE_NODE
;
1686 DEFUNSH(VTYSH_REALLYALL
, vtysh_end_all
, vtysh_end_all_cmd
, "end",
1687 "End current mode and change to enable mode\n")
1692 DEFUNSH(VTYSH_SR
, srv6
, srv6_cmd
,
1694 "Segment-Routing SRv6 configration\n")
1696 vty
->node
= SRV6_NODE
;
1700 DEFUNSH(VTYSH_SR
, srv6_locators
, srv6_locators_cmd
,
1702 "Segment-Routing SRv6 locators configration\n")
1704 vty
->node
= SRV6_LOCS_NODE
;
1708 DEFUNSH(VTYSH_SR
, srv6_locator
, srv6_locator_cmd
,
1710 "Segment Routing SRv6 locator\n"
1711 "Specify locator-name\n")
1713 vty
->node
= SRV6_LOC_NODE
;
1718 DEFUNSH(VTYSH_BGPD
, router_bgp
, router_bgp_cmd
,
1719 "router bgp [(1-4294967295) [<view|vrf> WORD]]",
1720 ROUTER_STR BGP_STR AS_STR
1721 "BGP view\nBGP VRF\n"
1724 vty
->node
= BGP_NODE
;
1728 #ifdef KEEP_OLD_VPN_COMMANDS
1729 DEFUNSH(VTYSH_BGPD
, address_family_vpnv4
, address_family_vpnv4_cmd
,
1730 "address-family vpnv4 [unicast]",
1731 "Enter Address Family command mode\n"
1733 "Address Family modifier\n")
1735 vty
->node
= BGP_VPNV4_NODE
;
1739 DEFUNSH(VTYSH_BGPD
, address_family_vpnv6
, address_family_vpnv6_cmd
,
1740 "address-family vpnv6 [unicast]",
1741 "Enter Address Family command mode\n"
1743 "Address Family modifier\n")
1745 vty
->node
= BGP_VPNV6_NODE
;
1748 #endif /* KEEP_OLD_VPN_COMMANDS */
1750 DEFUNSH(VTYSH_BGPD
, address_family_ipv4
, address_family_ipv4_cmd
,
1751 "address-family ipv4 [unicast]",
1752 "Enter Address Family command mode\n"
1754 "Address Family Modifier\n")
1756 vty
->node
= BGP_IPV4_NODE
;
1760 DEFUNSH(VTYSH_BGPD
, address_family_flowspecv4
, address_family_flowspecv4_cmd
,
1761 "address-family ipv4 flowspec",
1762 "Enter Address Family command mode\n"
1764 "Address Family Modifier\n")
1766 vty
->node
= BGP_FLOWSPECV4_NODE
;
1770 DEFUNSH(VTYSH_BGPD
, address_family_flowspecv6
, address_family_flowspecv6_cmd
,
1771 "address-family ipv6 flowspec",
1772 "Enter Address Family command mode\n"
1774 "Address Family Modifier\n")
1776 vty
->node
= BGP_FLOWSPECV6_NODE
;
1780 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_multicast
,
1781 address_family_ipv4_multicast_cmd
, "address-family ipv4 multicast",
1782 "Enter Address Family command mode\n"
1784 "Address Family modifier\n")
1786 vty
->node
= BGP_IPV4M_NODE
;
1790 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_vpn
, address_family_ipv4_vpn_cmd
,
1791 "address-family ipv4 vpn",
1792 "Enter Address Family command mode\n"
1794 "Address Family modifier\n")
1796 vty
->node
= BGP_VPNV4_NODE
;
1800 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_labeled_unicast
,
1801 address_family_ipv4_labeled_unicast_cmd
,
1802 "address-family ipv4 labeled-unicast",
1803 "Enter Address Family command mode\n"
1805 "Address Family modifier\n")
1807 vty
->node
= BGP_IPV4L_NODE
;
1811 DEFUNSH(VTYSH_BGPD
, address_family_ipv6
, address_family_ipv6_cmd
,
1812 "address-family ipv6 [unicast]",
1813 "Enter Address Family command mode\n"
1815 "Address Family modifier\n")
1817 vty
->node
= BGP_IPV6_NODE
;
1821 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_multicast
,
1822 address_family_ipv6_multicast_cmd
, "address-family ipv6 multicast",
1823 "Enter Address Family command mode\n"
1825 "Address Family modifier\n")
1827 vty
->node
= BGP_IPV6M_NODE
;
1831 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_vpn
, address_family_ipv6_vpn_cmd
,
1832 "address-family ipv6 vpn",
1833 "Enter Address Family command mode\n"
1835 "Address Family modifier\n")
1837 vty
->node
= BGP_VPNV6_NODE
;
1841 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_labeled_unicast
,
1842 address_family_ipv6_labeled_unicast_cmd
,
1843 "address-family ipv6 labeled-unicast",
1844 "Enter Address Family command mode\n"
1846 "Address Family modifier\n")
1848 vty
->node
= BGP_IPV6L_NODE
;
1856 "Enable rpki and enter rpki configuration mode\n")
1858 vty
->node
= RPKI_NODE
;
1865 "bmp targets BMPTARGETS",
1866 "BGP Monitoring Protocol\n"
1867 "Create BMP target group\n"
1868 "Name of the BMP target group\n")
1870 vty
->node
= BMP_NODE
;
1877 "segment-routing srv6",
1878 "Segment-Routing configuration\n"
1879 "Segment-Routing SRv6 configuration\n")
1881 vty
->node
= BGP_SRV6_NODE
;
1889 "exit Segment-Routing SRv6 configuration\n")
1891 if (vty
->node
== BGP_SRV6_NODE
)
1892 vty
->node
= BGP_NODE
;
1900 "quit Segment-Routing SRv6 configuration\n")
1902 if (vty
->node
== BGP_SRV6_NODE
)
1903 vty
->node
= BGP_NODE
;
1907 DEFUNSH(VTYSH_BGPD
, address_family_evpn
, address_family_evpn_cmd
,
1908 "address-family <l2vpn evpn>",
1909 "Enter Address Family command mode\n"
1911 "Address Family modifier\n")
1913 vty
->node
= BGP_EVPN_NODE
;
1917 #if defined(HAVE_CUMULUS)
1918 #if CONFDATE > 20211115
1919 CPP_NOTICE("Use of `address-family evpn` is deprecated please remove don't forget frr-reload.py")
1921 DEFUNSH_HIDDEN(VTYSH_BGPD
, address_family_evpn2
, address_family_evpn2_cmd
,
1922 "address-family evpn",
1923 "Enter Address Family command mode\n"
1924 "EVPN Address family\n")
1927 "This command is deprecated please convert to `address-family l2vpn evpn`\n");
1928 vty
->node
= BGP_EVPN_NODE
;
1933 DEFUNSH(VTYSH_BGPD
, bgp_evpn_vni
, bgp_evpn_vni_cmd
, "vni " CMD_VNI_RANGE
,
1934 "VXLAN Network Identifier\n"
1937 vty
->node
= BGP_EVPN_VNI_NODE
;
1941 #if defined(ENABLE_BGP_VNC)
1942 DEFUNSH(VTYSH_BGPD
, vnc_defaults
, vnc_defaults_cmd
, "vnc defaults",
1943 "VNC/RFP related configuration\n"
1944 "Configure default NVE group\n")
1946 vty
->node
= BGP_VNC_DEFAULTS_NODE
;
1950 DEFUNSH(VTYSH_BGPD
, vnc_nve_group
, vnc_nve_group_cmd
, "vnc nve-group NAME",
1951 "VNC/RFP related configuration\n"
1952 "Configure a NVE group\n"
1955 vty
->node
= BGP_VNC_NVE_GROUP_NODE
;
1959 DEFUNSH(VTYSH_BGPD
, vnc_vrf_policy
, vnc_vrf_policy_cmd
, "vrf-policy NAME",
1960 "Configure a VRF policy group\n"
1963 vty
->node
= BGP_VRF_POLICY_NODE
;
1967 DEFUNSH(VTYSH_BGPD
, vnc_l2_group
, vnc_l2_group_cmd
, "vnc l2-group NAME",
1968 "VNC/RFP related configuration\n"
1969 "Configure a L2 group\n"
1972 vty
->node
= BGP_VNC_L2_GROUP_NODE
;
1976 DEFUNSH(VTYSH_BGPD
, exit_vnc_config
, exit_vnc_config_cmd
, "exit-vnc",
1977 "Exit from VNC configuration mode\n")
1979 if (vty
->node
== BGP_VNC_DEFAULTS_NODE
1980 || vty
->node
== BGP_VNC_NVE_GROUP_NODE
1981 || vty
->node
== BGP_VNC_L2_GROUP_NODE
)
1982 vty
->node
= BGP_NODE
;
1986 DEFUNSH(VTYSH_BGPD
, exit_vrf_policy
, exit_vrf_policy_cmd
, "exit-vrf-policy",
1987 "Exit from VRF policy configuration mode\n")
1989 if (vty
->node
== BGP_VRF_POLICY_NODE
)
1990 vty
->node
= BGP_NODE
;
1994 #endif /* HAVE_BGPD */
1996 DEFUNSH(VTYSH_KEYS
, key_chain
, key_chain_cmd
, "key chain WORD",
1997 "Authentication key management\n"
1998 "Key-chain management\n"
2001 vty
->node
= KEYCHAIN_NODE
;
2005 DEFUNSH(VTYSH_KEYS
, key
, key_cmd
, "key (0-2147483647)",
2007 "Key identifier number\n")
2009 vty
->node
= KEYCHAIN_KEY_NODE
;
2014 DEFUNSH(VTYSH_RIPD
, router_rip
, router_rip_cmd
, "router rip [vrf NAME]",
2015 ROUTER_STR
"RIP\n" VRF_CMD_HELP_STR
)
2017 vty
->node
= RIP_NODE
;
2020 #endif /* HAVE_RIPD */
2023 DEFUNSH(VTYSH_RIPNGD
, router_ripng
, router_ripng_cmd
, "router ripng [vrf NAME]",
2024 ROUTER_STR
"RIPng\n" VRF_CMD_HELP_STR
)
2026 vty
->node
= RIPNG_NODE
;
2029 #endif /* HAVE_RIPNGD */
2032 DEFUNSH(VTYSH_OSPFD
, router_ospf
, router_ospf_cmd
,
2033 "router ospf [(1-65535)] [vrf NAME]",
2034 "Enable a routing process\n"
2035 "Start OSPF configuration\n"
2039 vty
->node
= OSPF_NODE
;
2042 #endif /* HAVE_OSPFD */
2045 DEFUNSH(VTYSH_EIGRPD
, router_eigrp
, router_eigrp_cmd
, "router eigrp (1-65535) [vrf NAME]",
2046 "Enable a routing process\n"
2047 "Start EIGRP configuration\n"
2048 "AS number to use\n"
2051 vty
->node
= EIGRP_NODE
;
2054 #endif /* HAVE_EIGRPD */
2057 DEFUNSH(VTYSH_BABELD
, router_babel
, router_babel_cmd
, "router babel",
2058 "Enable a routing process\n"
2059 "Make Babel instance command\n")
2061 vty
->node
= BABEL_NODE
;
2064 #endif /* HAVE_BABELD */
2067 DEFUNSH(VTYSH_OSPF6D
, router_ospf6
, router_ospf6_cmd
, "router ospf6 [vrf NAME]",
2068 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
2070 vty
->node
= OSPF6_NODE
;
2075 #if defined(HAVE_LDPD)
2076 DEFUNSH(VTYSH_LDPD
, ldp_mpls_ldp
, ldp_mpls_ldp_cmd
, "mpls ldp",
2077 "Global MPLS configuration subcommands\n"
2078 "Label Distribution Protocol\n")
2080 vty
->node
= LDP_NODE
;
2084 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv4
, ldp_address_family_ipv4_cmd
,
2085 "address-family ipv4",
2086 "Configure Address Family and its parameters\n"
2089 vty
->node
= LDP_IPV4_NODE
;
2093 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv6
, ldp_address_family_ipv6_cmd
,
2094 "address-family ipv6",
2095 "Configure Address Family and its parameters\n"
2098 vty
->node
= LDP_IPV6_NODE
;
2102 DEFUNSH(VTYSH_LDPD
, ldp_exit_address_family
, ldp_exit_address_family_cmd
,
2103 "exit-address-family", "Exit from Address Family configuration mode\n")
2105 if (vty
->node
== LDP_IPV4_NODE
|| vty
->node
== LDP_IPV6_NODE
)
2106 vty
->node
= LDP_NODE
;
2110 DEFUNSH(VTYSH_LDPD
, ldp_interface_ifname
, ldp_interface_ifname_cmd
,
2112 "Enable LDP on an interface and enter interface submode\n"
2113 "Interface's name\n")
2115 switch (vty
->node
) {
2117 vty
->node
= LDP_IPV4_IFACE_NODE
;
2120 vty
->node
= LDP_IPV6_IFACE_NODE
;
2129 DEFUNSH(VTYSH_LDPD
, ldp_l2vpn_word_type_vpls
, ldp_l2vpn_word_type_vpls_cmd
,
2130 "l2vpn WORD type vpls",
2131 "Configure l2vpn commands\n"
2134 "Virtual Private LAN Service\n")
2136 vty
->node
= LDP_L2VPN_NODE
;
2140 DEFUNSH(VTYSH_LDPD
, ldp_member_pseudowire_ifname
,
2141 ldp_member_pseudowire_ifname_cmd
, "member pseudowire IFNAME",
2142 "L2VPN member configuration\n"
2143 "Pseudowire interface\n"
2144 "Interface's name\n")
2146 vty
->node
= LDP_PSEUDOWIRE_NODE
;
2152 DEFUNSH(VTYSH_ISISD
, router_isis
, router_isis_cmd
,
2153 "router isis WORD [vrf NAME]",
2156 "ISO Routing area tag\n" VRF_CMD_HELP_STR
)
2158 vty
->node
= ISIS_NODE
;
2161 #endif /* HAVE_ISISD */
2164 DEFUNSH(VTYSH_FABRICD
, router_openfabric
, router_openfabric_cmd
, "router openfabric WORD",
2166 "OpenFabric routing protocol\n"
2167 "ISO Routing area tag\n")
2169 vty
->node
= OPENFABRIC_NODE
;
2172 #endif /* HAVE_FABRICD */
2174 DEFUNSH(VTYSH_SR
, segment_routing
, segment_routing_cmd
,
2176 "Configure segment routing\n")
2178 vty
->node
= SEGMENT_ROUTING_NODE
;
2182 #if defined (HAVE_PATHD)
2183 DEFUNSH(VTYSH_PATHD
, sr_traffic_eng
, sr_traffic_eng_cmd
,
2185 "Configure SR traffic engineering\n")
2187 vty
->node
= SR_TRAFFIC_ENG_NODE
;
2191 DEFUNSH(VTYSH_PATHD
, srte_segment_list
, srte_segment_list_cmd
,
2192 "segment-list WORD$name",
2194 "Segment List Name\n")
2196 vty
->node
= SR_SEGMENT_LIST_NODE
;
2200 DEFUNSH(VTYSH_PATHD
, srte_policy
, srte_policy_cmd
,
2201 "policy color (0-4294967295) endpoint <A.B.C.D|X:X::X:X>",
2202 "Segment Routing Policy\n"
2204 "SR Policy color value\n"
2205 "SR Policy endpoint\n"
2206 "SR Policy endpoint IPv4 address\n"
2207 "SR Policy endpoint IPv6 address\n")
2209 vty
->node
= SR_POLICY_NODE
;
2213 DEFUNSH(VTYSH_PATHD
, srte_policy_candidate_dyn_path
,
2214 srte_policy_candidate_dyn_path_cmd
,
2215 "candidate-path preference (0-4294967295) name WORD dynamic",
2216 "Segment Routing Policy Candidate Path\n"
2217 "Segment Routing Policy Candidate Path Preference\n"
2218 "Administrative Preference\n"
2219 "Segment Routing Policy Candidate Path Name\n"
2223 vty
->node
= SR_CANDIDATE_DYN_NODE
;
2227 #if defined(HAVE_PATHD_PCEP)
2229 DEFUNSH(VTYSH_PATHD
, pcep
, pcep_cmd
,
2231 "Configure SR pcep\n")
2233 vty
->node
= PCEP_NODE
;
2237 DEFUNSH(VTYSH_PATHD
, pcep_cli_pcc
, pcep_cli_pcc_cmd
,
2240 "PCC configuration\n")
2242 vty
->node
= PCEP_PCC_NODE
;
2246 DEFUNSH(VTYSH_PATHD
, pcep_cli_pce
, pcep_cli_pce_cmd
,
2249 "PCE configuration\n"
2252 vty
->node
= PCEP_PCE_NODE
;
2256 DEFUNSH(VTYSH_PATHD
, pcep_cli_pcep_pce_config
, pcep_cli_pcep_pce_config_cmd
,
2257 "[no] pce-config WORD",
2259 "PCEP peer Configuration Group\n"
2260 "PCEP peer Configuration Group name\n")
2262 vty
->node
= PCEP_PCE_CONFIG_NODE
;
2266 #endif /* HAVE_PATHD_PCEP */
2268 #endif /* HAVE_PATHD */
2270 DEFUNSH(VTYSH_RMAP
, vtysh_route_map
, vtysh_route_map_cmd
,
2271 "route-map WORD <deny|permit> (1-65535)",
2272 "Create route-map or enter route-map command mode\n"
2274 "Route map denies set operations\n"
2275 "Route map permits set operations\n"
2276 "Sequence to insert to/delete from existing route-map entry\n")
2278 vty
->node
= RMAP_NODE
;
2283 DEFUNSH(VTYSH_PBRD
, vtysh_pbr_map
, vtysh_pbr_map_cmd
,
2284 "pbr-map PBRMAP seq (1-700)",
2285 "Create pbr-map or enter pbr-map command mode\n"
2286 "The name of the PBR MAP\n"
2287 "Sequence to insert to/delete from existing pbr-map entry\n"
2288 "Sequence number\n")
2290 vty
->node
= PBRMAP_NODE
;
2294 DEFSH(VTYSH_PBRD
, vtysh_no_pbr_map_cmd
, "no pbr-map PBRMAP [seq (1-700)]",
2297 "The name of the PBR MAP\n"
2298 "Sequence to delete from existing pbr-map entry\n"
2299 "Sequence number\n")
2300 #endif /* HAVE_PBRD */
2303 DEFUNSH(VTYSH_BFDD
, bfd_enter
, bfd_enter_cmd
, "bfd", "Configure BFD peers\n")
2305 vty
->node
= BFD_NODE
;
2309 DEFUNSH(VTYSH_BFDD
, bfd_peer_enter
, bfd_peer_enter_cmd
,
2310 "peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
2312 "IPv4 peer address\n"
2313 "IPv6 peer address\n"
2314 "Configure multihop\n"
2315 "Configure local address\n"
2316 "IPv4 local address\n"
2317 "IPv6 local address\n"
2319 "Configure interface name to use\n"
2321 "Configure VRF name\n")
2323 vty
->node
= BFD_PEER_NODE
;
2327 DEFUNSH(VTYSH_BFDD
, bfd_profile_enter
, bfd_profile_enter_cmd
,
2330 BFD_PROFILE_NAME_STR
)
2332 vty
->node
= BFD_PROFILE_NODE
;
2335 #endif /* HAVE_BFDD */
2337 DEFUNSH(VTYSH_ALL
, vtysh_line_vty
, vtysh_line_vty_cmd
, "line vty",
2338 "Configure a terminal line\n"
2339 "Virtual terminal\n")
2341 vty
->node
= VTY_NODE
;
2345 DEFUNSH(VTYSH_REALLYALL
, vtysh_enable
, vtysh_enable_cmd
, "enable",
2346 "Turn on privileged mode command\n")
2348 vty
->node
= ENABLE_NODE
;
2352 DEFUNSH(VTYSH_REALLYALL
, vtysh_disable
, vtysh_disable_cmd
, "disable",
2353 "Turn off privileged mode command\n")
2355 if (vty
->node
== ENABLE_NODE
)
2356 vty
->node
= VIEW_NODE
;
2360 DEFUNSH(VTYSH_REALLYALL
, vtysh_config_terminal
, vtysh_config_terminal_cmd
,
2361 "configure [terminal]",
2362 "Configuration from vty interface\n"
2363 "Configuration terminal\n")
2365 vty
->node
= CONFIG_NODE
;
2369 static int vtysh_exit(struct vty
*vty
)
2371 struct cmd_node
*cnode
= vector_lookup(cmdvec
, vty
->node
);
2373 if (vty
->node
== VIEW_NODE
|| vty
->node
== ENABLE_NODE
)
2375 if (cnode
->node_exit
)
2376 cnode
->node_exit(vty
);
2377 if (cnode
->parent_node
)
2378 vty
->node
= cnode
->parent_node
;
2380 if (vty
->node
== CONFIG_NODE
) {
2381 /* resync in case one of the daemons is somewhere else */
2382 vtysh_execute("end");
2383 vtysh_execute("configure");
2388 DEFUNSH(VTYSH_REALLYALL
, vtysh_exit_all
, vtysh_exit_all_cmd
, "exit",
2389 "Exit current mode and down to previous mode\n")
2391 return vtysh_exit(vty
);
2394 DEFUNSH(VTYSH_REALLYALL
, vtysh_quit_all
, vtysh_quit_all_cmd
, "quit",
2395 "Exit current mode and down to previous mode\n")
2397 return vtysh_exit_all(self
, vty
, argc
, argv
);
2401 DEFUNSH(VTYSH_BGPD
, exit_address_family
, exit_address_family_cmd
,
2402 "exit-address-family", "Exit from Address Family configuration mode\n")
2404 if (vty
->node
== BGP_IPV4_NODE
|| vty
->node
== BGP_IPV4M_NODE
2405 || vty
->node
== BGP_IPV4L_NODE
|| vty
->node
== BGP_VPNV4_NODE
2406 || vty
->node
== BGP_VPNV6_NODE
|| vty
->node
== BGP_IPV6_NODE
2407 || vty
->node
== BGP_IPV6L_NODE
|| vty
->node
== BGP_IPV6M_NODE
2408 || vty
->node
== BGP_EVPN_NODE
2409 || vty
->node
== BGP_FLOWSPECV4_NODE
2410 || vty
->node
== BGP_FLOWSPECV6_NODE
)
2411 vty
->node
= BGP_NODE
;
2415 DEFUNSH(VTYSH_BGPD
, exit_vni
, exit_vni_cmd
, "exit-vni", "Exit from VNI mode\n")
2417 if (vty
->node
== BGP_EVPN_VNI_NODE
)
2418 vty
->node
= BGP_EVPN_NODE
;
2422 DEFUNSH(VTYSH_BGPD
, rpki_exit
, rpki_exit_cmd
, "exit",
2423 "Exit current mode and down to previous mode\n")
2429 DEFUNSH(VTYSH_BGPD
, rpki_quit
, rpki_quit_cmd
, "quit",
2430 "Exit current mode and down to previous mode\n")
2432 return rpki_exit(self
, vty
, argc
, argv
);
2435 DEFUNSH(VTYSH_BGPD
, bmp_exit
, bmp_exit_cmd
, "exit",
2436 "Exit current mode and down to previous mode\n")
2442 DEFUNSH(VTYSH_BGPD
, bmp_quit
, bmp_quit_cmd
, "quit",
2443 "Exit current mode and down to previous mode\n")
2445 return bmp_exit(self
, vty
, argc
, argv
);
2447 #endif /* HAVE_BGPD */
2449 DEFUNSH(VTYSH_VRF
, exit_vrf_config
, exit_vrf_config_cmd
, "exit-vrf",
2450 "Exit from VRF configuration mode\n")
2452 if (vty
->node
== VRF_NODE
)
2453 vty
->node
= CONFIG_NODE
;
2457 DEFUNSH(VTYSH_SR
, exit_srv6_config
, exit_srv6_config_cmd
, "exit",
2458 "Exit from SRv6 configuration mode\n")
2460 if (vty
->node
== SRV6_NODE
)
2461 vty
->node
= SEGMENT_ROUTING_NODE
;
2465 DEFUNSH(VTYSH_SR
, exit_srv6_locs_config
, exit_srv6_locs_config_cmd
, "exit",
2466 "Exit from SRv6-locator configuration mode\n")
2468 if (vty
->node
== SRV6_LOCS_NODE
)
2469 vty
->node
= SRV6_NODE
;
2473 DEFUNSH(VTYSH_SR
, exit_srv6_loc_config
, exit_srv6_loc_config_cmd
, "exit",
2474 "Exit from SRv6-locators configuration mode\n")
2476 if (vty
->node
== SRV6_LOC_NODE
)
2477 vty
->node
= SRV6_LOCS_NODE
;
2482 DEFUNSH(VTYSH_RIPD
, vtysh_exit_ripd
, vtysh_exit_ripd_cmd
, "exit",
2483 "Exit current mode and down to previous mode\n")
2485 return vtysh_exit(vty
);
2488 DEFUNSH(VTYSH_RIPD
, vtysh_quit_ripd
, vtysh_quit_ripd_cmd
, "quit",
2489 "Exit current mode and down to previous mode\n")
2491 return vtysh_exit_ripd(self
, vty
, argc
, argv
);
2493 #endif /* HAVE_RIPD */
2496 DEFUNSH(VTYSH_RIPNGD
, vtysh_exit_ripngd
, vtysh_exit_ripngd_cmd
, "exit",
2497 "Exit current mode and down to previous mode\n")
2499 return vtysh_exit(vty
);
2502 DEFUNSH(VTYSH_RIPNGD
, vtysh_quit_ripngd
, vtysh_quit_ripngd_cmd
, "quit",
2503 "Exit current mode and down to previous mode\n")
2505 return vtysh_exit_ripngd(self
, vty
, argc
, argv
);
2507 #endif /* HAVE_RIPNGD */
2509 DEFUNSH(VTYSH_RMAP
, vtysh_exit_rmap
, vtysh_exit_rmap_cmd
, "exit",
2510 "Exit current mode and down to previous mode\n")
2512 return vtysh_exit(vty
);
2515 DEFUNSH(VTYSH_RMAP
, vtysh_quit_rmap
, vtysh_quit_rmap_cmd
, "quit",
2516 "Exit current mode and down to previous mode\n")
2518 return vtysh_exit_rmap(self
, vty
, argc
, argv
);
2522 DEFUNSH(VTYSH_PBRD
, vtysh_exit_pbr_map
, vtysh_exit_pbr_map_cmd
, "exit",
2523 "Exit current mode and down to previous mode\n")
2525 return vtysh_exit(vty
);
2528 DEFUNSH(VTYSH_PBRD
, vtysh_quit_pbr_map
, vtysh_quit_pbr_map_cmd
, "quit",
2529 "Exit current mode and down to previous mode\n")
2531 return vtysh_exit_rmap(self
, vty
, argc
, argv
);
2533 #endif /* HAVE_PBRD */
2536 DEFUNSH(VTYSH_BGPD
, vtysh_exit_bgpd
, vtysh_exit_bgpd_cmd
, "exit",
2537 "Exit current mode and down to previous mode\n")
2539 return vtysh_exit(vty
);
2542 DEFUNSH(VTYSH_BGPD
, vtysh_quit_bgpd
, vtysh_quit_bgpd_cmd
, "quit",
2543 "Exit current mode and down to previous mode\n")
2545 return vtysh_exit_bgpd(self
, vty
, argc
, argv
);
2547 #endif /* HAVE_BGPD */
2550 DEFUNSH(VTYSH_OSPFD
, vtysh_exit_ospfd
, vtysh_exit_ospfd_cmd
, "exit",
2551 "Exit current mode and down to previous mode\n")
2553 return vtysh_exit(vty
);
2556 DEFUNSH(VTYSH_OSPFD
, vtysh_quit_ospfd
, vtysh_quit_ospfd_cmd
, "quit",
2557 "Exit current mode and down to previous mode\n")
2559 return vtysh_exit_ospfd(self
, vty
, argc
, argv
);
2561 #endif /* HAVE_OSPFD */
2564 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_eigrpd
, vtysh_exit_eigrpd_cmd
, "exit",
2565 "Exit current mode and down to previous mode\n")
2567 return vtysh_exit(vty
);
2570 DEFUNSH(VTYSH_EIGRPD
, vtysh_quit_eigrpd
, vtysh_quit_eigrpd_cmd
, "quit",
2571 "Exit current mode and down to previous mode\n")
2573 return vtysh_exit(vty
);
2575 #endif /* HAVE_EIGRPD */
2578 DEFUNSH(VTYSH_BABELD
, vtysh_exit_babeld
, vtysh_exit_babeld_cmd
, "exit",
2579 "Exit current mode and down to previous mode\n")
2581 return vtysh_exit(vty
);
2584 DEFUNSH(VTYSH_BABELD
, vtysh_quit_babeld
, vtysh_quit_babeld_cmd
, "quit",
2585 "Exit current mode and down to previous mode\n")
2587 return vtysh_exit(vty
);
2589 #endif /* HAVE_BABELD */
2592 DEFUNSH(VTYSH_OSPF6D
, vtysh_exit_ospf6d
, vtysh_exit_ospf6d_cmd
, "exit",
2593 "Exit current mode and down to previous mode\n")
2595 return vtysh_exit(vty
);
2598 DEFUNSH(VTYSH_OSPF6D
, vtysh_quit_ospf6d
, vtysh_quit_ospf6d_cmd
, "quit",
2599 "Exit current mode and down to previous mode\n")
2601 return vtysh_exit_ospf6d(self
, vty
, argc
, argv
);
2603 #endif /* HAVE_OSPF6D */
2605 #if defined(HAVE_LDPD)
2606 DEFUNSH(VTYSH_LDPD
, vtysh_exit_ldpd
, vtysh_exit_ldpd_cmd
, "exit",
2607 "Exit current mode and down to previous mode\n")
2609 return vtysh_exit(vty
);
2612 ALIAS(vtysh_exit_ldpd
, vtysh_quit_ldpd_cmd
, "quit",
2613 "Exit current mode and down to previous mode\n")
2617 DEFUNSH(VTYSH_ISISD
, vtysh_exit_isisd
, vtysh_exit_isisd_cmd
, "exit",
2618 "Exit current mode and down to previous mode\n")
2620 return vtysh_exit(vty
);
2623 DEFUNSH(VTYSH_ISISD
, vtysh_quit_isisd
, vtysh_quit_isisd_cmd
, "quit",
2624 "Exit current mode and down to previous mode\n")
2626 return vtysh_exit_isisd(self
, vty
, argc
, argv
);
2628 #endif /* HAVE_ISISD */
2631 DEFUNSH(VTYSH_BFDD
, vtysh_exit_bfdd
, vtysh_exit_bfdd_cmd
, "exit",
2632 "Exit current mode and down to previous mode\n")
2634 return vtysh_exit(vty
);
2637 ALIAS(vtysh_exit_bfdd
, vtysh_quit_bfdd_cmd
, "quit",
2638 "Exit current mode and down to previous mode\n")
2642 DEFUNSH(VTYSH_FABRICD
, vtysh_exit_fabricd
, vtysh_exit_fabricd_cmd
, "exit",
2643 "Exit current mode and down to previous mode\n")
2645 return vtysh_exit(vty
);
2648 DEFUNSH(VTYSH_FABRICD
, vtysh_quit_fabricd
, vtysh_quit_fabricd_cmd
, "quit",
2649 "Exit current mode and down to previous mode\n")
2651 return vtysh_exit_fabricd(self
, vty
, argc
, argv
);
2653 #endif /* HAVE_FABRICD */
2655 DEFUNSH(VTYSH_KEYS
, vtysh_exit_keys
, vtysh_exit_keys_cmd
, "exit",
2656 "Exit current mode and down to previous mode\n")
2658 return vtysh_exit(vty
);
2661 DEFUNSH(VTYSH_KEYS
, vtysh_quit_keys
, vtysh_quit_keys_cmd
, "quit",
2662 "Exit current mode and down to previous mode\n")
2664 return vtysh_exit_keys(self
, vty
, argc
, argv
);
2667 DEFUNSH(VTYSH_SR
, vtysh_exit_sr
, vtysh_exit_sr_cmd
, "exit",
2668 "Exit current mode and down to previous mode\n")
2670 return vtysh_exit(vty
);
2673 DEFUNSH(VTYSH_SR
, vtysh_quit_sr
, vtysh_quit_sr_cmd
, "quit",
2674 "Exit current mode and down to previous mode\n")
2676 return vtysh_exit(vty
);
2679 #if defined(HAVE_PATHD)
2680 DEFUNSH(VTYSH_PATHD
, vtysh_exit_pathd
, vtysh_exit_pathd_cmd
, "exit",
2681 "Exit current mode and down to previous mode\n")
2683 return vtysh_exit(vty
);
2686 DEFUNSH(VTYSH_PATHD
, vtysh_quit_pathd
, vtysh_quit_pathd_cmd
, "quit",
2687 "Exit current mode and down to previous mode\n")
2689 return vtysh_exit_pathd(self
, vty
, argc
, argv
);
2691 #endif /* HAVE_PATHD */
2693 DEFUNSH(VTYSH_ALL
, vtysh_exit_line_vty
, vtysh_exit_line_vty_cmd
, "exit",
2694 "Exit current mode and down to previous mode\n")
2696 return vtysh_exit(vty
);
2699 DEFUNSH(VTYSH_ALL
, vtysh_quit_line_vty
, vtysh_quit_line_vty_cmd
, "quit",
2700 "Exit current mode and down to previous mode\n")
2702 return vtysh_exit_line_vty(self
, vty
, argc
, argv
);
2705 DEFUNSH(VTYSH_INTERFACE
, vtysh_interface
, vtysh_interface_cmd
,
2706 "interface IFNAME [vrf NAME]",
2707 "Select an interface to configure\n"
2708 "Interface's name\n" VRF_CMD_HELP_STR
)
2710 vty
->node
= INTERFACE_NODE
;
2714 DEFUNSH(VTYSH_ZEBRA
, vtysh_pseudowire
, vtysh_pseudowire_cmd
,
2715 "pseudowire IFNAME",
2716 "Static pseudowire configuration\n"
2717 "Pseudowire name\n")
2719 vty
->node
= PW_NODE
;
2723 DEFUNSH(VTYSH_NH_GROUP
,
2724 vtysh_nexthop_group
, vtysh_nexthop_group_cmd
,
2725 "nexthop-group NHGNAME",
2726 "Nexthop Group configuration\n"
2727 "Name of the Nexthop Group\n")
2729 vty
->node
= NH_GROUP_NODE
;
2733 DEFSH(VTYSH_NH_GROUP
, vtysh_no_nexthop_group_cmd
,
2734 "no nexthop-group NHGNAME",
2736 "Nexthop Group Configuration\n"
2737 "Name of the Nexthop Group\n")
2739 DEFUNSH(VTYSH_VRF
, vtysh_vrf
, vtysh_vrf_cmd
, "vrf NAME",
2740 "Select a VRF to configure\n"
2743 vty
->node
= VRF_NODE
;
2747 DEFSH(VTYSH_ZEBRA
, vtysh_vrf_netns_cmd
,
2749 "Attach VRF to a Namespace\n"
2750 "The file name in " NS_RUN_DIR
", or a full pathname\n")
2752 DEFSH(VTYSH_ZEBRA
, vtysh_no_vrf_netns_cmd
,
2755 "Detach VRF from a Namespace\n"
2756 "The file name in " NS_RUN_DIR
", or a full pathname\n")
2758 DEFUNSH(VTYSH_VRF
, vtysh_exit_vrf
, vtysh_exit_vrf_cmd
, "exit",
2759 "Exit current mode and down to previous mode\n")
2761 return vtysh_exit(vty
);
2764 DEFUNSH(VTYSH_VRF
, vtysh_quit_vrf
, vtysh_quit_vrf_cmd
, "quit",
2765 "Exit current mode and down to previous mode\n")
2767 return vtysh_exit_vrf(self
, vty
, argc
, argv
);
2770 DEFUNSH(VTYSH_NH_GROUP
,
2771 vtysh_exit_nexthop_group
, vtysh_exit_nexthop_group_cmd
,
2772 "exit", "Exit current mode and down to previous mode\n")
2774 return vtysh_exit(vty
);
2777 DEFUNSH(VTYSH_NH_GROUP
,
2778 vtysh_quit_nexthop_group
, vtysh_quit_nexthop_group_cmd
,
2779 "quit", "Exit current mode and down to previous mode\n")
2781 return vtysh_exit_nexthop_group(self
, vty
, argc
, argv
);
2784 DEFUNSH(VTYSH_INTERFACE
, vtysh_exit_interface
, vtysh_exit_interface_cmd
, "exit",
2785 "Exit current mode and down to previous mode\n")
2787 return vtysh_exit(vty
);
2790 DEFUNSH(VTYSH_INTERFACE
, vtysh_quit_interface
, vtysh_quit_interface_cmd
, "quit",
2791 "Exit current mode and down to previous mode\n")
2793 return vtysh_exit_interface(self
, vty
, argc
, argv
);
2796 static char *do_prepend(struct vty
*vty
, struct cmd_token
**argv
, int argc
)
2798 const char *argstr
[argc
+ 1];
2801 if (vty
->node
!= VIEW_NODE
) {
2806 for (i
= 0; i
< argc
; i
++)
2807 argstr
[i
+ off
] = argv
[i
]->arg
;
2809 return frrstr_join(argstr
, argc
+ off
, " ");
2812 static int show_per_daemon(struct vty
*vty
, struct cmd_token
**argv
, int argc
,
2813 const char *headline
)
2816 int ret
= CMD_SUCCESS
;
2817 char *line
= do_prepend(vty
, argv
, argc
);
2819 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2820 if (vtysh_client
[i
].fd
>= 0 || vtysh_client
[i
].next
) {
2821 vty_out(vty
, headline
, vtysh_client
[i
].name
);
2822 ret
= vtysh_client_execute(&vtysh_client
[i
], line
);
2826 XFREE(MTYPE_TMP
, line
);
2831 static int show_one_daemon(struct vty
*vty
, struct cmd_token
**argv
, int argc
,
2835 char *line
= do_prepend(vty
, argv
, argc
);
2837 ret
= vtysh_client_execute_name(name
, line
);
2839 XFREE(MTYPE_TMP
, line
);
2844 DEFUN (vtysh_show_poll
,
2845 vtysh_show_poll_cmd
,
2848 "Thread information\n"
2849 "Thread Poll Information\n")
2851 return show_per_daemon(vty
, argv
, argc
, "Thread statistics for %s:\n");
2854 DEFUN (vtysh_show_thread
,
2855 vtysh_show_thread_cmd
,
2856 "show thread cpu [FILTER]",
2858 "Thread information\n"
2859 "Thread CPU usage\n"
2860 "Display filter (rwtexb)\n")
2862 return show_per_daemon(vty
, argv
, argc
, "Thread statistics for %s:\n");
2865 DEFUN (vtysh_show_work_queues
,
2866 vtysh_show_work_queues_cmd
,
2869 "Work Queue information\n")
2871 return show_per_daemon(vty
, argv
, argc
,
2872 "Work queue statistics for %s:\n");
2875 DEFUN (vtysh_show_work_queues_daemon
,
2876 vtysh_show_work_queues_daemon_cmd
,
2877 "show work-queues " DAEMONS_LIST
,
2879 "Work Queue information\n"
2882 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
2885 DEFUNSH(VTYSH_ZEBRA
, vtysh_link_params
, vtysh_link_params_cmd
, "link-params",
2888 vty
->node
= LINK_PARAMS_NODE
;
2892 DEFUNSH(VTYSH_ZEBRA
, exit_link_params
, exit_link_params_cmd
, "exit-link-params",
2893 "Exit from Link Params configuration node\n")
2895 if (vty
->node
== LINK_PARAMS_NODE
)
2896 vty
->node
= INTERFACE_NODE
;
2900 DEFUNSH_HIDDEN (0x00,
2902 vtysh_debug_all_cmd
,
2906 "Toggle all debugs on or off\n")
2911 DEFUN (vtysh_show_debugging
,
2912 vtysh_show_debugging_cmd
,
2917 return show_per_daemon(vty
, argv
, argc
, "");
2920 DEFUN (vtysh_show_debugging_hashtable
,
2921 vtysh_show_debugging_hashtable_cmd
,
2922 "show debugging hashtable [statistics]",
2925 "Statistics about hash tables\n"
2926 "Statistics about hash tables\n")
2928 bool stats
= strmatch(argv
[argc
- 1]->text
, "statistics");
2932 "Load factor (LF) - average number of elements across all buckets\n");
2934 "Full load factor (FLF) - average number of elements across full buckets\n\n");
2936 "Standard deviation (SD) is calculated for both the LF and FLF\n");
2938 "and indicates the typical deviation of bucket chain length\n");
2939 vty_out(vty
, "from the value in the corresponding load factor.\n\n");
2941 return show_per_daemon(vty
, argv
, stats
? argc
- 1 : argc
,
2942 "Hashtable statistics for %s:\n");
2945 DEFUN (vtysh_show_error_code
,
2946 vtysh_show_error_code_cmd
,
2947 "show error <(1-4294967296)|all> [json]",
2949 "Information on errors\n"
2950 "Error code to get info about\n"
2951 "Information on all errors\n"
2956 if (!strmatch(argv
[2]->text
, "all"))
2957 arg
= strtoul(argv
[2]->arg
, NULL
, 10);
2959 /* If it's not a shared code, send it to all the daemons */
2960 if (arg
< LIB_FERR_START
|| arg
> LIB_FERR_END
) {
2961 show_per_daemon(vty
, argv
, argc
, "");
2962 /* Otherwise, print it ourselves to avoid duplication */
2964 bool json
= strmatch(argv
[argc
- 1]->text
, "json");
2966 if (!strmatch(argv
[2]->text
, "all"))
2967 arg
= strtoul(argv
[2]->arg
, NULL
, 10);
2969 log_ref_display(vty
, arg
, json
);
2976 DEFUN_HIDDEN (show_config_running
,
2977 show_config_running_cmd
,
2978 "show configuration running\
2979 [<json|xml> [translate WORD]]\
2980 [with-defaults]" DAEMONS_LIST
,
2982 "Configuration information\n"
2983 "Running configuration\n"
2984 "Change output format to JSON\n"
2985 "Change output format to XML\n"
2986 "Translate output\n"
2987 "YANG module translator\n"
2988 "Show default values\n"
2991 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
2994 DEFUN (show_yang_operational_data
,
2995 show_yang_operational_data_cmd
,
2996 "show yang operational-data XPATH\
3002 "YANG information\n"
3003 "Show YANG operational data\n"
3004 "XPath expression specifying the YANG data path\n"
3005 "Set the output format\n"
3006 "JavaScript Object Notation\n"
3007 "Extensible Markup Language\n"
3008 "Translate operational data\n"
3009 "YANG module translator\n"
3012 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
3015 DEFUN(show_yang_module
, show_yang_module_cmd
,
3016 "show yang module [module-translator WORD] " DAEMONS_LIST
,
3018 "YANG information\n"
3019 "Show loaded modules\n"
3020 "YANG module translator\n"
3021 "YANG module translator\n" DAEMONS_STR
)
3023 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
3026 DEFUN(show_yang_module_detail
, show_yang_module_detail_cmd
,
3028 [module-translator WORD]\
3029 WORD <compiled|summary|tree|yang|yin> " DAEMONS_LIST
,
3031 "YANG information\n"
3032 "Show loaded modules\n"
3033 "YANG module translator\n"
3034 "YANG module translator\n"
3036 "Display compiled module in YANG format\n"
3037 "Display summary information about the module\n"
3038 "Display module in the tree (RFC 8340) format\n"
3039 "Display module in the YANG format\n"
3040 "Display module in the YIN format\n" DAEMONS_STR
)
3042 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
3046 DEFUNSH(VTYSH_ALL
, debug_nb
,
3048 "[no] debug northbound\
3050 callbacks [{configuration|state|rpc}]\
3057 "Northbound debugging\n"
3064 "libyang debugging\n")
3069 DEFUN (vtysh_show_history
,
3070 vtysh_show_history_cmd
,
3073 "The list of commands stored in history\n")
3075 HIST_ENTRY
**hlist
= history_list();
3079 vty_out(vty
, "%s\n", hlist
[i
]->line
);
3086 DEFUN (vtysh_show_memory
,
3087 vtysh_show_memory_cmd
,
3088 "show memory [" DAEMONS_LIST
"]",
3090 "Memory statistics\n"
3094 return show_one_daemon(vty
, argv
, argc
- 1,
3095 argv
[argc
- 1]->text
);
3097 return show_per_daemon(vty
, argv
, argc
, "Memory statistics for %s:\n");
3100 DEFUN (vtysh_show_modules
,
3101 vtysh_show_modules_cmd
,
3106 return show_per_daemon(vty
, argv
, argc
, "Module information for %s:\n");
3109 /* Logging commands. */
3110 DEFUN (vtysh_show_logging
,
3111 vtysh_show_logging_cmd
,
3114 "Show current logging configuration\n")
3116 return show_per_daemon(vty
, argv
, argc
,
3117 "Logging configuration for %s:\n");
3120 DEFUNSH(VTYSH_ALL
, vtysh_debug_memstats
,
3121 vtysh_debug_memstats_cmd
, "[no] debug memstats-at-exit",
3124 "Print memory statistics at exit\n")
3129 DEFUNSH(VTYSH_ALL
, vtysh_service_password_encrypt
,
3130 vtysh_service_password_encrypt_cmd
, "service password-encryption",
3131 "Set up miscellaneous service\n"
3132 "Enable encrypted passwords\n")
3137 DEFUNSH(VTYSH_ALL
, no_vtysh_service_password_encrypt
,
3138 no_vtysh_service_password_encrypt_cmd
, "no service password-encryption",
3140 "Set up miscellaneous service\n"
3141 "Enable encrypted passwords\n")
3146 DEFUNSH(VTYSH_ALL
, vtysh_config_password
, vtysh_password_cmd
,
3147 "password [(8-8)] LINE",
3148 "Modify the terminal connection password\n"
3149 "Specifies a HIDDEN password will follow\n"
3150 "The password string\n")
3155 DEFUNSH(VTYSH_ALL
, no_vtysh_config_password
, no_vtysh_password_cmd
,
3156 "no password", NO_STR
3157 "Modify the terminal connection password\n")
3159 vty_out(vty
, NO_PASSWD_CMD_WARNING
);
3164 DEFUNSH(VTYSH_ALL
, vtysh_config_enable_password
, vtysh_enable_password_cmd
,
3165 "enable password [(8-8)] LINE",
3166 "Modify enable password parameters\n"
3167 "Assign the privileged level password\n"
3168 "Specifies a HIDDEN password will follow\n"
3169 "The 'enable' password string\n")
3174 DEFUNSH(VTYSH_ALL
, no_vtysh_config_enable_password
,
3175 no_vtysh_enable_password_cmd
, "no enable password", NO_STR
3176 "Modify enable password parameters\n"
3177 "Assign the privileged level password\n")
3179 vty_out(vty
, NO_PASSWD_CMD_WARNING
);
3184 DEFUN (vtysh_write_terminal
,
3185 vtysh_write_terminal_cmd
,
3186 "write terminal ["DAEMONS_LIST
"] [no-header]",
3187 "Write running configuration to memory, network, or terminal\n"
3188 "Write to terminal\n"
3190 "Skip \"Building configuration...\" header\n")
3193 char line
[] = "do write terminal\n";
3195 if (!strcmp(argv
[argc
- 1]->arg
, "no-header"))
3198 vty_out(vty
, "Building configuration...\n");
3199 vty_out(vty
, "\nCurrent configuration:\n");
3200 vty_out(vty
, "!\n");
3203 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3205 || (strmatch(vtysh_client
[i
].name
, argv
[2]->text
)))
3206 vtysh_client_config(&vtysh_client
[i
], line
);
3208 /* Integrate vtysh specific configuration. */
3209 vty_open_pager(vty
);
3210 vtysh_config_write();
3211 vtysh_config_dump();
3212 vty_close_pager(vty
);
3213 vty_out(vty
, "end\n");
3218 DEFUN (vtysh_show_running_config
,
3219 vtysh_show_running_config_cmd
,
3220 "show running-config ["DAEMONS_LIST
"] [no-header]",
3222 "Current operating configuration\n"
3224 "Skip \"Building configuration...\" header\n")
3226 return vtysh_write_terminal(self
, vty
, argc
, argv
);
3229 DEFUN (vtysh_integrated_config
,
3230 vtysh_integrated_config_cmd
,
3231 "service integrated-vtysh-config",
3232 "Set up miscellaneous service\n"
3233 "Write configuration into integrated file\n")
3235 vtysh_write_integrated
= WRITE_INTEGRATED_YES
;
3239 DEFUN (no_vtysh_integrated_config
,
3240 no_vtysh_integrated_config_cmd
,
3241 "no service integrated-vtysh-config",
3243 "Set up miscellaneous service\n"
3244 "Write configuration into integrated file\n")
3246 vtysh_write_integrated
= WRITE_INTEGRATED_NO
;
3250 static void backup_config_file(const char *fbackup
)
3252 char *integrate_sav
= NULL
;
3254 size_t integrate_sav_sz
= strlen(fbackup
) + strlen(CONF_BACKUP_EXT
) + 1;
3255 integrate_sav
= malloc(integrate_sav_sz
);
3256 strlcpy(integrate_sav
, fbackup
, integrate_sav_sz
);
3257 strlcat(integrate_sav
, CONF_BACKUP_EXT
, integrate_sav_sz
);
3259 /* Move current configuration file to backup config file. */
3260 if (unlink(integrate_sav
) != 0 && errno
!= ENOENT
)
3261 vty_out(vty
, "Unlink failed for %s: %s\n", integrate_sav
,
3263 if (rename(fbackup
, integrate_sav
) != 0 && errno
!= ENOENT
)
3264 vty_out(vty
, "Error renaming %s to %s: %s\n", fbackup
,
3265 integrate_sav
, strerror(errno
));
3266 free(integrate_sav
);
3269 int vtysh_write_config_integrated(void)
3272 char line
[] = "do write terminal\n";
3276 struct passwd
*pwentry
;
3279 struct group
*grentry
;
3286 vty_out(vty
, "Building Configuration...\n");
3288 backup_config_file(frr_config
);
3289 fp
= fopen(frr_config
, "w");
3292 "%% Error: failed to open configuration file %s: %s\n",
3293 frr_config
, safe_strerror(errno
));
3294 return CMD_WARNING_CONFIG_FAILED
;
3298 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3299 vtysh_client_config(&vtysh_client
[i
], line
);
3301 vtysh_config_write();
3302 vty
->of_saved
= vty
->of
;
3304 vtysh_config_dump();
3305 vty
->of
= vty
->of_saved
;
3307 if (fchmod(fd
, CONFIGFILE_MASK
) != 0) {
3308 printf("%% Warning: can't chmod configuration file %s: %s\n",
3309 frr_config
, safe_strerror(errno
));
3314 pwentry
= getpwnam(FRR_USER
);
3316 uid
= pwentry
->pw_uid
;
3318 printf("%% Warning: could not look up user \"%s\"\n", FRR_USER
);
3323 grentry
= getgrnam(FRR_GROUP
);
3325 gid
= grentry
->gr_gid
;
3327 printf("%% Warning: could not look up group \"%s\"\n",
3333 if (!fstat(fd
, &st
)) {
3334 if (st
.st_uid
== uid
)
3336 if (st
.st_gid
== gid
)
3338 if ((uid
!= (uid_t
)-1 || gid
!= (gid_t
)-1)
3339 && fchown(fd
, uid
, gid
)) {
3340 printf("%% Warning: can't chown configuration file %s: %s\n",
3341 frr_config
, safe_strerror(errno
));
3345 printf("%% Warning: stat() failed on %s: %s\n", frr_config
,
3346 safe_strerror(errno
));
3352 printf("Integrated configuration saved to %s\n", frr_config
);
3360 static bool want_config_integrated(void)
3364 switch (vtysh_write_integrated
) {
3365 case WRITE_INTEGRATED_UNSPECIFIED
:
3366 if (stat(frr_config
, &s
) && errno
== ENOENT
)
3369 case WRITE_INTEGRATED_NO
:
3371 case WRITE_INTEGRATED_YES
:
3377 DEFUN (vtysh_write_memory
,
3378 vtysh_write_memory_cmd
,
3379 "write [<memory|file>]",
3380 "Write running configuration to memory, network, or terminal\n"
3381 "Write configuration to the file (same as write file)\n"
3382 "Write configuration to the file (same as write memory)\n")
3384 int ret
= CMD_SUCCESS
;
3385 char line
[] = "do write memory\n";
3388 vty_out(vty
, "Note: this version of vtysh never writes vtysh.conf\n");
3390 /* If integrated frr.conf explicitely set. */
3391 if (want_config_integrated()) {
3392 ret
= CMD_WARNING_CONFIG_FAILED
;
3394 /* first attempt to use watchfrr if it's available */
3395 bool used_watchfrr
= false;
3397 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3398 if (vtysh_client
[i
].flag
== VTYSH_WATCHFRR
)
3400 if (i
< array_size(vtysh_client
) && vtysh_client
[i
].fd
!= -1) {
3401 used_watchfrr
= true;
3402 ret
= vtysh_client_execute(&vtysh_client
[i
],
3403 "do write integrated");
3407 * If we didn't use watchfrr, fallback to writing the config
3410 if (!used_watchfrr
) {
3411 printf("\nWarning: attempting direct configuration write without watchfrr.\nFile permissions and ownership may be incorrect, or write may fail.\n\n");
3412 ret
= vtysh_write_config_integrated();
3417 vty_out(vty
, "Building Configuration...\n");
3419 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3420 ret
= vtysh_client_execute(&vtysh_client
[i
], line
);
3425 DEFUN (vtysh_copy_running_config
,
3426 vtysh_copy_running_config_cmd
,
3427 "copy running-config startup-config",
3428 "Copy from one file to another\n"
3429 "Copy from current system configuration\n"
3430 "Copy to startup configuration\n")
3432 return vtysh_write_memory(self
, vty
, argc
, argv
);
3435 DEFUN (vtysh_copy_to_running
,
3436 vtysh_copy_to_running_cmd
,
3437 "copy FILENAME running-config",
3438 "Apply a configuration file\n"
3439 "Configuration file to read\n"
3440 "Apply to current configuration\n")
3443 const char *fname
= argv
[1]->arg
;
3445 ret
= vtysh_read_config(fname
, true);
3447 /* Return to enable mode - the 'read_config' api leaves us up a level */
3448 vtysh_execute_no_pager("enable");
3453 DEFUN (vtysh_terminal_paginate
,
3454 vtysh_terminal_paginate_cmd
,
3455 "[no] terminal paginate",
3457 "Set terminal line parameters\n"
3458 "Use pager for output scrolling\n")
3460 free(vtysh_pager_name
);
3461 vtysh_pager_name
= NULL
;
3463 if (strcmp(argv
[0]->text
, "no"))
3464 vtysh_pager_envdef(true);
3468 DEFUN (vtysh_terminal_length
,
3469 vtysh_terminal_length_cmd
,
3470 "[no] terminal length (0-4294967295)",
3472 "Set terminal line parameters\n"
3473 "Set number of lines on a screen\n"
3474 "Number of lines on screen (0 for no pausing, nonzero to use pager)\n")
3477 unsigned long lines
;
3479 free(vtysh_pager_name
);
3480 vtysh_pager_name
= NULL
;
3482 if (!strcmp(argv
[0]->text
, "no") || !strcmp(argv
[1]->text
, "no")) {
3483 /* "terminal no length" = use VTYSH_PAGER */
3484 vtysh_pager_envdef(true);
3488 lines
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3491 "%% The \"terminal length\" command is deprecated and its value is ignored.\n"
3492 "%% Please use \"terminal paginate\" instead with OS TTY length handling.\n");
3493 vtysh_pager_envdef(true);
3499 ALIAS_DEPRECATED(vtysh_terminal_length
,
3500 vtysh_terminal_no_length_cmd
,
3501 "terminal no length",
3502 "Set terminal line parameters\n"
3504 "Set number of lines on a screen\n")
3506 DEFUN (vtysh_show_daemons
,
3507 vtysh_show_daemons_cmd
,
3510 "Show list of running daemons\n")
3514 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3515 if (vtysh_client
[i
].fd
>= 0)
3516 vty_out(vty
, " %s", vtysh_client
[i
].name
);
3522 /* Execute command in child process. */
3523 static void execute_command(const char *command
, int argc
, const char *arg1
,
3533 /* Failure of fork(). */
3534 fprintf(stderr
, "Can't fork: %s\n", safe_strerror(errno
));
3536 } else if (pid
== 0) {
3537 /* This is child process. */
3540 execlp(command
, command
, (const char *)NULL
);
3543 execlp(command
, command
, arg1
, (const char *)NULL
);
3546 execlp(command
, command
, arg1
, arg2
,
3547 (const char *)NULL
);
3551 /* When execlp suceed, this part is not executed. */
3552 fprintf(stderr
, "Can't execute %s: %s\n", command
,
3553 safe_strerror(errno
));
3556 /* This is parent. */
3558 wait4(pid
, &status
, 0, NULL
);
3566 "Send echo messages\n"
3567 "Ping destination address or hostname\n")
3571 argv_find(argv
, argc
, "WORD", &idx
);
3572 execute_command("ping", 1, argv
[idx
]->arg
, NULL
);
3576 ALIAS(vtysh_ping
, vtysh_ping_ip_cmd
, "ping ip WORD",
3577 "Send echo messages\n"
3579 "Ping destination address or hostname\n")
3581 DEFUN (vtysh_traceroute
,
3582 vtysh_traceroute_cmd
,
3584 "Trace route to destination\n"
3585 "Trace route to destination address or hostname\n")
3589 argv_find(argv
, argc
, "WORD", &idx
);
3590 execute_command("traceroute", 1, argv
[idx
]->arg
, NULL
);
3594 ALIAS(vtysh_traceroute
, vtysh_traceroute_ip_cmd
, "traceroute ip WORD",
3595 "Trace route to destination\n"
3597 "Trace route to destination address or hostname\n")
3599 DEFUN (vtysh_mtrace
,
3601 "mtrace WORD [WORD]",
3602 "Multicast trace route to multicast source\n"
3603 "Multicast trace route to multicast source address\n"
3604 "Multicast trace route for multicast group address\n")
3607 execute_command("mtracebis", 1, argv
[1]->arg
, NULL
);
3609 execute_command("mtracebis", 2, argv
[1]->arg
, argv
[2]->arg
);
3616 "Send echo messages\n"
3618 "Ping destination address or hostname\n")
3620 execute_command("ping6", 1, argv
[2]->arg
, NULL
);
3624 DEFUN (vtysh_traceroute6
,
3625 vtysh_traceroute6_cmd
,
3626 "traceroute ipv6 WORD",
3627 "Trace route to destination\n"
3629 "Trace route to destination address or hostname\n")
3631 execute_command("traceroute6", 1, argv
[2]->arg
, NULL
);
3635 #if defined(HAVE_SHELL_ACCESS)
3636 DEFUN (vtysh_telnet
,
3639 "Open a telnet connection\n"
3640 "IP address or hostname of a remote system\n")
3642 execute_command("telnet", 1, argv
[1]->arg
, NULL
);
3646 DEFUN (vtysh_telnet_port
,
3647 vtysh_telnet_port_cmd
,
3649 "Open a telnet connection\n"
3650 "IP address or hostname of a remote system\n"
3651 "TCP Port number\n")
3653 execute_command("telnet", 2, argv
[1]->arg
, argv
[2]->arg
);
3660 "Open an ssh connection\n"
3663 execute_command("ssh", 1, argv
[1]->arg
, NULL
);
3667 DEFUN (vtysh_start_shell
,
3668 vtysh_start_shell_cmd
,
3670 "Start UNIX shell\n")
3672 execute_command("sh", 0, NULL
, NULL
);
3676 DEFUN (vtysh_start_bash
,
3677 vtysh_start_bash_cmd
,
3679 "Start UNIX shell\n"
3682 execute_command("bash", 0, NULL
, NULL
);
3686 DEFUN (vtysh_start_zsh
,
3687 vtysh_start_zsh_cmd
,
3689 "Start UNIX shell\n"
3692 execute_command("zsh", 0, NULL
, NULL
);
3699 "list [permutations]",
3700 "Print command list\n"
3701 "Print all possible command permutations\n")
3703 return cmd_list_cmds(vty
, argc
== 2);
3706 DEFUN (vtysh_output_file
,
3707 vtysh_output_file_cmd
,
3709 "Direct vtysh output to file\n"
3710 "Direct vtysh output to file\n"
3711 "Path to dump output to\n")
3713 const char *path
= argv
[argc
- 1]->arg
;
3714 vty
->of
= fopen(path
, "a");
3716 vty_out(vty
, "Failed to open file '%s': %s\n", path
,
3717 safe_strerror(errno
));
3723 DEFUN (no_vtysh_output_file
,
3724 no_vtysh_output_file_cmd
,
3725 "no output file [FILE]",
3727 "Direct vtysh output to file\n"
3728 "Direct vtysh output to file\n"
3729 "Path to dump output to\n")
3731 if (vty
->of
!= stdout
) {
3741 "Find CLI command matching a regular expression\n"
3742 "Search pattern (POSIX regex)\n")
3744 return cmd_find_cmds(vty
, argv
, argc
);
3747 DEFUN_HIDDEN(show_cli_graph_vtysh
,
3748 show_cli_graph_vtysh_cmd
,
3752 "Dump current command space as DOT graph\n")
3754 struct cmd_node
*cn
= vector_slot(cmdvec
, vty
->node
);
3755 char *dot
= cmd_graph_dump_dot(cn
->cmdgraph
);
3757 vty_out(vty
, "%s\n", dot
);
3758 XFREE(MTYPE_TMP
, dot
);
3762 static void vtysh_install_default(enum node_type node
)
3764 _install_element(node
, &config_list_cmd
);
3765 _install_element(node
, &find_cmd
);
3766 _install_element(node
, &show_cli_graph_vtysh_cmd
);
3767 _install_element(node
, &vtysh_output_file_cmd
);
3768 _install_element(node
, &no_vtysh_output_file_cmd
);
3771 /* Making connection to protocol daemon. */
3772 static int vtysh_connect(struct vtysh_client
*vclient
)
3776 struct sockaddr_un addr
;
3780 if (!vclient
->path
[0])
3781 snprintf(vclient
->path
, sizeof(vclient
->path
), "%s/%s.vty",
3782 vtydir
, vclient
->name
);
3783 path
= vclient
->path
;
3785 /* Stat socket to see if we have permission to access it. */
3786 ret
= stat(path
, &s_stat
);
3787 if (ret
< 0 && errno
!= ENOENT
) {
3788 fprintf(stderr
, "vtysh_connect(%s): stat = %s\n", path
,
3789 safe_strerror(errno
));
3794 if (!S_ISSOCK(s_stat
.st_mode
)) {
3795 fprintf(stderr
, "vtysh_connect(%s): Not a socket\n",
3801 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3804 fprintf(stderr
, "vtysh_connect(%s): socket = %s\n", path
,
3805 safe_strerror(errno
));
3810 memset(&addr
, 0, sizeof(struct sockaddr_un
));
3811 addr
.sun_family
= AF_UNIX
;
3812 strlcpy(addr
.sun_path
, path
, sizeof(addr
.sun_path
));
3813 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
3814 len
= addr
.sun_len
= SUN_LEN(&addr
);
3816 len
= sizeof(addr
.sun_family
) + strlen(addr
.sun_path
);
3817 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
3819 ret
= connect(sock
, (struct sockaddr
*)&addr
, len
);
3822 fprintf(stderr
, "vtysh_connect(%s): connect = %s\n", path
,
3823 safe_strerror(errno
));
3833 static int vtysh_reconnect(struct vtysh_client
*vclient
)
3837 fprintf(stderr
, "Warning: connecting to %s...", vclient
->name
);
3838 ret
= vtysh_connect(vclient
);
3840 fprintf(stderr
, "failed!\n");
3843 fprintf(stderr
, "success!\n");
3844 if (vtysh_client_execute(vclient
, "enable") < 0)
3846 return vtysh_execute_no_pager("end");
3849 /* Return true if str ends with suffix, else return false */
3850 static int ends_with(const char *str
, const char *suffix
)
3852 if (!str
|| !suffix
)
3854 size_t lenstr
= strlen(str
);
3855 size_t lensuffix
= strlen(suffix
);
3856 if (lensuffix
> lenstr
)
3858 return strncmp(str
+ lenstr
- lensuffix
, suffix
, lensuffix
) == 0;
3861 static void vtysh_client_sorted_insert(struct vtysh_client
*head_client
,
3862 struct vtysh_client
*client
)
3864 struct vtysh_client
*prev_node
, *current_node
;
3866 prev_node
= head_client
;
3867 current_node
= head_client
->next
;
3868 while (current_node
) {
3869 if (strcmp(current_node
->path
, client
->path
) > 0)
3872 prev_node
= current_node
;
3873 current_node
= current_node
->next
;
3875 client
->next
= current_node
;
3876 prev_node
->next
= client
;
3879 #define MAXIMUM_INSTANCES 10
3881 static void vtysh_update_all_instances(struct vtysh_client
*head_client
)
3883 struct vtysh_client
*client
;
3885 struct dirent
*file
;
3888 if (head_client
->flag
!= VTYSH_OSPFD
)
3891 /* ls vty_sock_dir and look for all files ending in .vty */
3892 dir
= opendir(vtydir
);
3894 while ((file
= readdir(dir
)) != NULL
) {
3895 if (frrstr_startswith(file
->d_name
, "ospfd-")
3896 && ends_with(file
->d_name
, ".vty")) {
3897 if (n
== MAXIMUM_INSTANCES
) {
3899 "Parsing %s, client limit(%d) reached!\n",
3903 client
= (struct vtysh_client
*)malloc(
3904 sizeof(struct vtysh_client
));
3906 client
->name
= "ospfd";
3907 client
->flag
= VTYSH_OSPFD
;
3908 snprintf(client
->path
, sizeof(client
->path
),
3909 "%s/%s", vtydir
, file
->d_name
);
3910 client
->next
= NULL
;
3911 vtysh_client_sorted_insert(head_client
, client
);
3919 static int vtysh_connect_all_instances(struct vtysh_client
*head_client
)
3921 struct vtysh_client
*client
;
3924 vtysh_update_all_instances(head_client
);
3926 client
= head_client
->next
;
3928 if (vtysh_connect(client
) == 0)
3930 client
= client
->next
;
3936 int vtysh_connect_all(const char *daemon_name
)
3942 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
3944 || !strcmp(daemon_name
, vtysh_client
[i
].name
)) {
3946 if (vtysh_connect(&vtysh_client
[i
]) == 0)
3949 rc
+= vtysh_connect_all_instances(&vtysh_client
[i
]);
3953 fprintf(stderr
, "Error: no daemons match name %s!\n",
3958 /* To disable readline's filename completion. */
3959 static char *vtysh_completion_entry_function(const char *ignore
,
3965 void vtysh_readline_init(void)
3967 /* readline related settings. */
3968 char *disable_bracketed_paste
=
3969 XSTRDUP(MTYPE_TMP
, "set enable-bracketed-paste off");
3972 rl_parse_and_bind(disable_bracketed_paste
);
3973 rl_bind_key('?', (rl_command_func_t
*)vtysh_rl_describe
);
3974 rl_completion_entry_function
= vtysh_completion_entry_function
;
3975 rl_attempted_completion_function
= new_completion
;
3977 XFREE(MTYPE_TMP
, disable_bracketed_paste
);
3980 char *vtysh_prompt(void)
3982 static char buf
[512];
3984 snprintf(buf
, sizeof(buf
), cmd_prompt(vty
->node
), cmd_hostname_get());
3988 static void vtysh_ac_line(void *arg
, const char *line
)
3992 for (i
= 0; i
< vector_active(comps
); i
++)
3993 if (!strcmp(line
, (char *)vector_slot(comps
, i
)))
3995 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, line
));
3998 static void vtysh_autocomplete(vector comps
, struct cmd_token
*token
)
4003 snprintf(accmd
, sizeof(accmd
), "autocomplete %d %s %s", token
->type
,
4004 token
->text
, token
->varname
? token
->varname
: "-");
4006 vty
->of_saved
= vty
->of
;
4008 for (i
= 0; i
< array_size(vtysh_client
); i
++)
4009 vtysh_client_run_all(&vtysh_client
[i
], accmd
, 1, vtysh_ac_line
,
4011 vty
->of
= vty
->of_saved
;
4014 static const struct cmd_variable_handler vtysh_var_handler
[] = {
4018 .completions
= vtysh_autocomplete
},
4019 {.completions
= NULL
}};
4021 void vtysh_uninit(void)
4023 if (vty
->of
!= stdout
)
4027 void vtysh_init_vty(void)
4029 /* Make vty structure. */
4031 vty
->type
= VTY_SHELL
;
4032 vty
->node
= VIEW_NODE
;
4034 /* set default output */
4036 vtysh_pager_envdef(false);
4038 /* Initialize commands. */
4040 cmd_variable_handler_register(vtysh_var_handler
);
4044 install_node(&bgp_node
);
4045 install_element(CONFIG_NODE
, &router_bgp_cmd
);
4046 install_element(BGP_NODE
, &vtysh_exit_bgpd_cmd
);
4047 install_element(BGP_NODE
, &vtysh_quit_bgpd_cmd
);
4048 install_element(BGP_NODE
, &vtysh_end_all_cmd
);
4050 install_node(&bgp_vpnv4_node
);
4051 install_element(BGP_NODE
, &address_family_ipv4_vpn_cmd
);
4052 #ifdef KEEP_OLD_VPN_COMMANDS
4053 install_element(BGP_NODE
, &address_family_vpnv4_cmd
);
4054 #endif /* KEEP_OLD_VPN_COMMANDS */
4055 install_element(BGP_VPNV4_NODE
, &vtysh_exit_bgpd_cmd
);
4056 install_element(BGP_VPNV4_NODE
, &vtysh_quit_bgpd_cmd
);
4057 install_element(BGP_VPNV4_NODE
, &vtysh_end_all_cmd
);
4058 install_element(BGP_VPNV4_NODE
, &exit_address_family_cmd
);
4060 install_node(&bgp_vpnv6_node
);
4061 install_element(BGP_NODE
, &address_family_ipv6_vpn_cmd
);
4062 #ifdef KEEP_OLD_VPN_COMMANDS
4063 install_element(BGP_NODE
, &address_family_vpnv6_cmd
);
4064 #endif /* KEEP_OLD_VPN_COMMANDS */
4065 install_element(BGP_VPNV6_NODE
, &vtysh_exit_bgpd_cmd
);
4066 install_element(BGP_VPNV6_NODE
, &vtysh_quit_bgpd_cmd
);
4067 install_element(BGP_VPNV6_NODE
, &vtysh_end_all_cmd
);
4068 install_element(BGP_VPNV6_NODE
, &exit_address_family_cmd
);
4070 install_node(&bgp_flowspecv4_node
);
4071 install_element(BGP_NODE
, &address_family_flowspecv4_cmd
);
4072 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_exit_bgpd_cmd
);
4073 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_quit_bgpd_cmd
);
4074 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_end_all_cmd
);
4075 install_element(BGP_FLOWSPECV4_NODE
, &exit_address_family_cmd
);
4077 install_node(&bgp_flowspecv6_node
);
4078 install_element(BGP_NODE
, &address_family_flowspecv6_cmd
);
4079 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_exit_bgpd_cmd
);
4080 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_quit_bgpd_cmd
);
4081 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_end_all_cmd
);
4082 install_element(BGP_FLOWSPECV6_NODE
, &exit_address_family_cmd
);
4084 install_node(&bgp_ipv4_node
);
4085 install_element(BGP_NODE
, &address_family_ipv4_cmd
);
4086 install_element(BGP_IPV4_NODE
, &vtysh_exit_bgpd_cmd
);
4087 install_element(BGP_IPV4_NODE
, &vtysh_quit_bgpd_cmd
);
4088 install_element(BGP_IPV4_NODE
, &vtysh_end_all_cmd
);
4089 install_element(BGP_IPV4_NODE
, &exit_address_family_cmd
);
4091 install_node(&bgp_ipv4m_node
);
4092 install_element(BGP_NODE
, &address_family_ipv4_multicast_cmd
);
4093 install_element(BGP_IPV4M_NODE
, &vtysh_exit_bgpd_cmd
);
4094 install_element(BGP_IPV4M_NODE
, &vtysh_quit_bgpd_cmd
);
4095 install_element(BGP_IPV4M_NODE
, &vtysh_end_all_cmd
);
4096 install_element(BGP_IPV4M_NODE
, &exit_address_family_cmd
);
4098 install_node(&bgp_ipv4l_node
);
4099 install_element(BGP_NODE
, &address_family_ipv4_labeled_unicast_cmd
);
4100 install_element(BGP_IPV4L_NODE
, &vtysh_exit_bgpd_cmd
);
4101 install_element(BGP_IPV4L_NODE
, &vtysh_quit_bgpd_cmd
);
4102 install_element(BGP_IPV4L_NODE
, &vtysh_end_all_cmd
);
4103 install_element(BGP_IPV4L_NODE
, &exit_address_family_cmd
);
4105 install_node(&bgp_ipv6_node
);
4106 install_element(BGP_NODE
, &address_family_ipv6_cmd
);
4107 install_element(BGP_IPV6_NODE
, &vtysh_exit_bgpd_cmd
);
4108 install_element(BGP_IPV6_NODE
, &vtysh_quit_bgpd_cmd
);
4109 install_element(BGP_IPV6_NODE
, &vtysh_end_all_cmd
);
4110 install_element(BGP_IPV6_NODE
, &exit_address_family_cmd
);
4112 install_node(&bgp_ipv6m_node
);
4113 install_element(BGP_NODE
, &address_family_ipv6_multicast_cmd
);
4114 install_element(BGP_IPV6M_NODE
, &vtysh_exit_bgpd_cmd
);
4115 install_element(BGP_IPV6M_NODE
, &vtysh_quit_bgpd_cmd
);
4116 install_element(BGP_IPV6M_NODE
, &vtysh_end_all_cmd
);
4117 install_element(BGP_IPV6M_NODE
, &exit_address_family_cmd
);
4119 install_node(&bgp_ipv6l_node
);
4120 install_element(BGP_NODE
, &address_family_ipv6_labeled_unicast_cmd
);
4121 install_element(BGP_IPV6L_NODE
, &vtysh_exit_bgpd_cmd
);
4122 install_element(BGP_IPV6L_NODE
, &vtysh_quit_bgpd_cmd
);
4123 install_element(BGP_IPV6L_NODE
, &vtysh_end_all_cmd
);
4124 install_element(BGP_IPV6L_NODE
, &exit_address_family_cmd
);
4126 #if defined(ENABLE_BGP_VNC)
4127 install_node(&bgp_vrf_policy_node
);
4128 install_element(BGP_NODE
, &vnc_vrf_policy_cmd
);
4129 install_element(BGP_VRF_POLICY_NODE
, &vtysh_exit_bgpd_cmd
);
4130 install_element(BGP_VRF_POLICY_NODE
, &vtysh_quit_bgpd_cmd
);
4131 install_element(BGP_VRF_POLICY_NODE
, &vtysh_end_all_cmd
);
4132 install_element(BGP_VRF_POLICY_NODE
, &exit_vrf_policy_cmd
);
4134 install_node(&bgp_vnc_defaults_node
);
4135 install_element(BGP_NODE
, &vnc_defaults_cmd
);
4136 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_exit_bgpd_cmd
);
4137 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_quit_bgpd_cmd
);
4138 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_end_all_cmd
);
4139 install_element(BGP_VNC_DEFAULTS_NODE
, &exit_vnc_config_cmd
);
4141 install_node(&bgp_vnc_nve_group_node
);
4142 install_element(BGP_NODE
, &vnc_nve_group_cmd
);
4143 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
4144 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
4145 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_end_all_cmd
);
4146 install_element(BGP_VNC_NVE_GROUP_NODE
, &exit_vnc_config_cmd
);
4148 install_node(&bgp_vnc_l2_group_node
);
4149 install_element(BGP_NODE
, &vnc_l2_group_cmd
);
4150 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
4151 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
4152 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_end_all_cmd
);
4153 install_element(BGP_VNC_L2_GROUP_NODE
, &exit_vnc_config_cmd
);
4156 install_node(&bgp_evpn_node
);
4157 install_element(BGP_NODE
, &address_family_evpn_cmd
);
4158 #if defined(HAVE_CUMULUS)
4159 install_element(BGP_NODE
, &address_family_evpn2_cmd
);
4161 install_element(BGP_EVPN_NODE
, &vtysh_quit_bgpd_cmd
);
4162 install_element(BGP_EVPN_NODE
, &vtysh_exit_bgpd_cmd
);
4163 install_element(BGP_EVPN_NODE
, &vtysh_end_all_cmd
);
4164 install_element(BGP_EVPN_NODE
, &exit_address_family_cmd
);
4166 install_node(&bgp_evpn_vni_node
);
4167 install_element(BGP_EVPN_NODE
, &bgp_evpn_vni_cmd
);
4168 install_element(BGP_EVPN_VNI_NODE
, &vtysh_exit_bgpd_cmd
);
4169 install_element(BGP_EVPN_VNI_NODE
, &vtysh_quit_bgpd_cmd
);
4170 install_element(BGP_EVPN_VNI_NODE
, &vtysh_end_all_cmd
);
4171 install_element(BGP_EVPN_VNI_NODE
, &exit_vni_cmd
);
4173 install_node(&rpki_node
);
4174 install_element(CONFIG_NODE
, &rpki_cmd
);
4175 install_element(RPKI_NODE
, &rpki_exit_cmd
);
4176 install_element(RPKI_NODE
, &rpki_quit_cmd
);
4177 install_element(RPKI_NODE
, &vtysh_end_all_cmd
);
4179 install_node(&bmp_node
);
4180 install_element(BGP_NODE
, &bmp_targets_cmd
);
4181 install_element(BMP_NODE
, &bmp_exit_cmd
);
4182 install_element(BMP_NODE
, &bmp_quit_cmd
);
4183 install_element(BMP_NODE
, &vtysh_end_all_cmd
);
4185 install_node(&bgp_srv6_node
);
4186 install_element(BGP_NODE
, &bgp_srv6_cmd
);
4187 install_element(BGP_SRV6_NODE
, &exit_bgp_srv6_cmd
);
4188 install_element(BGP_SRV6_NODE
, &quit_bgp_srv6_cmd
);
4189 install_element(BGP_SRV6_NODE
, &vtysh_end_all_cmd
);
4190 #endif /* HAVE_BGPD */
4193 install_node(&rip_node
);
4195 install_element(CONFIG_NODE
, &router_rip_cmd
);
4196 install_element(RIP_NODE
, &vtysh_exit_ripd_cmd
);
4197 install_element(RIP_NODE
, &vtysh_quit_ripd_cmd
);
4198 install_element(RIP_NODE
, &vtysh_end_all_cmd
);
4199 #endif /* HAVE_RIPD */
4202 install_node(&ripng_node
);
4204 install_element(CONFIG_NODE
, &router_ripng_cmd
);
4205 install_element(RIPNG_NODE
, &vtysh_exit_ripngd_cmd
);
4206 install_element(RIPNG_NODE
, &vtysh_quit_ripngd_cmd
);
4207 install_element(RIPNG_NODE
, &vtysh_end_all_cmd
);
4208 #endif /* HAVE_RIPNGD */
4212 install_node(&ospf_node
);
4213 install_element(CONFIG_NODE
, &router_ospf_cmd
);
4214 install_element(OSPF_NODE
, &vtysh_exit_ospfd_cmd
);
4215 install_element(OSPF_NODE
, &vtysh_quit_ospfd_cmd
);
4216 install_element(OSPF_NODE
, &vtysh_end_all_cmd
);
4217 #endif /* HAVE_OSPFD */
4221 install_node(&ospf6_node
);
4222 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
4223 install_element(OSPF6_NODE
, &vtysh_exit_ospf6d_cmd
);
4224 install_element(OSPF6_NODE
, &vtysh_quit_ospf6d_cmd
);
4225 install_element(OSPF6_NODE
, &vtysh_end_all_cmd
);
4226 #endif /* HAVE_OSPF6D */
4229 #if defined(HAVE_LDPD)
4230 install_node(&ldp_node
);
4231 install_element(CONFIG_NODE
, &ldp_mpls_ldp_cmd
);
4232 install_element(LDP_NODE
, &vtysh_exit_ldpd_cmd
);
4233 install_element(LDP_NODE
, &vtysh_quit_ldpd_cmd
);
4234 install_element(LDP_NODE
, &vtysh_end_all_cmd
);
4236 install_node(&ldp_ipv4_node
);
4237 install_element(LDP_NODE
, &ldp_address_family_ipv4_cmd
);
4238 install_element(LDP_IPV4_NODE
, &vtysh_exit_ldpd_cmd
);
4239 install_element(LDP_IPV4_NODE
, &vtysh_quit_ldpd_cmd
);
4240 install_element(LDP_IPV4_NODE
, &ldp_exit_address_family_cmd
);
4241 install_element(LDP_IPV4_NODE
, &vtysh_end_all_cmd
);
4243 install_node(&ldp_ipv6_node
);
4244 install_element(LDP_NODE
, &ldp_address_family_ipv6_cmd
);
4245 install_element(LDP_IPV6_NODE
, &vtysh_exit_ldpd_cmd
);
4246 install_element(LDP_IPV6_NODE
, &vtysh_quit_ldpd_cmd
);
4247 install_element(LDP_IPV6_NODE
, &ldp_exit_address_family_cmd
);
4248 install_element(LDP_IPV6_NODE
, &vtysh_end_all_cmd
);
4250 install_node(&ldp_ipv4_iface_node
);
4251 install_element(LDP_IPV4_NODE
, &ldp_interface_ifname_cmd
);
4252 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
4253 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
4254 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_end_all_cmd
);
4256 install_node(&ldp_ipv6_iface_node
);
4257 install_element(LDP_IPV6_NODE
, &ldp_interface_ifname_cmd
);
4258 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
4259 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
4260 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_end_all_cmd
);
4262 install_node(&ldp_l2vpn_node
);
4263 install_element(CONFIG_NODE
, &ldp_l2vpn_word_type_vpls_cmd
);
4264 install_element(LDP_L2VPN_NODE
, &vtysh_exit_ldpd_cmd
);
4265 install_element(LDP_L2VPN_NODE
, &vtysh_quit_ldpd_cmd
);
4266 install_element(LDP_L2VPN_NODE
, &vtysh_end_all_cmd
);
4268 install_node(&ldp_pseudowire_node
);
4269 install_element(LDP_L2VPN_NODE
, &ldp_member_pseudowire_ifname_cmd
);
4270 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_exit_ldpd_cmd
);
4271 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_quit_ldpd_cmd
);
4272 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_end_all_cmd
);
4277 install_node(&eigrp_node
);
4278 install_element(CONFIG_NODE
, &router_eigrp_cmd
);
4279 install_element(EIGRP_NODE
, &vtysh_exit_eigrpd_cmd
);
4280 install_element(EIGRP_NODE
, &vtysh_quit_eigrpd_cmd
);
4281 install_element(EIGRP_NODE
, &vtysh_end_all_cmd
);
4282 #endif /* HAVE_EIGRPD */
4286 install_node(&babel_node
);
4287 install_element(CONFIG_NODE
, &router_babel_cmd
);
4288 install_element(BABEL_NODE
, &vtysh_exit_babeld_cmd
);
4289 install_element(BABEL_NODE
, &vtysh_quit_babeld_cmd
);
4290 install_element(BABEL_NODE
, &vtysh_end_all_cmd
);
4291 #endif /* HAVE_BABELD */
4295 install_node(&isis_node
);
4296 install_element(CONFIG_NODE
, &router_isis_cmd
);
4297 install_element(ISIS_NODE
, &vtysh_exit_isisd_cmd
);
4298 install_element(ISIS_NODE
, &vtysh_quit_isisd_cmd
);
4299 install_element(ISIS_NODE
, &vtysh_end_all_cmd
);
4300 #endif /* HAVE_ISISD */
4304 install_node(&openfabric_node
);
4305 install_element(CONFIG_NODE
, &router_openfabric_cmd
);
4306 install_element(OPENFABRIC_NODE
, &vtysh_exit_fabricd_cmd
);
4307 install_element(OPENFABRIC_NODE
, &vtysh_quit_fabricd_cmd
);
4308 install_element(OPENFABRIC_NODE
, &vtysh_end_all_cmd
);
4309 #endif /* HAVE_FABRICD */
4313 install_node(&pbr_map_node
);
4314 install_element(CONFIG_NODE
, &vtysh_pbr_map_cmd
);
4315 install_element(CONFIG_NODE
, &vtysh_no_pbr_map_cmd
);
4316 install_element(PBRMAP_NODE
, &vtysh_exit_pbr_map_cmd
);
4317 install_element(PBRMAP_NODE
, &vtysh_quit_pbr_map_cmd
);
4318 install_element(PBRMAP_NODE
, &vtysh_end_all_cmd
);
4319 #endif /* HAVE_PBRD */
4323 install_node(&bfd_node
);
4324 install_element(CONFIG_NODE
, &bfd_enter_cmd
);
4325 install_element(BFD_NODE
, &vtysh_exit_bfdd_cmd
);
4326 install_element(BFD_NODE
, &vtysh_quit_bfdd_cmd
);
4327 install_element(BFD_NODE
, &vtysh_end_all_cmd
);
4329 install_node(&bfd_peer_node
);
4330 install_element(BFD_NODE
, &bfd_peer_enter_cmd
);
4331 install_element(BFD_PEER_NODE
, &vtysh_exit_bfdd_cmd
);
4332 install_element(BFD_PEER_NODE
, &vtysh_quit_bfdd_cmd
);
4333 install_element(BFD_PEER_NODE
, &vtysh_end_all_cmd
);
4335 install_node(&bfd_profile_node
);
4336 install_element(BFD_NODE
, &bfd_profile_enter_cmd
);
4337 install_element(BFD_PROFILE_NODE
, &vtysh_exit_bfdd_cmd
);
4338 install_element(BFD_PROFILE_NODE
, &vtysh_quit_bfdd_cmd
);
4339 install_element(BFD_PROFILE_NODE
, &vtysh_end_all_cmd
);
4340 #endif /* HAVE_BFDD */
4342 install_node(&segment_routing_node
);
4343 install_element(SEGMENT_ROUTING_NODE
, &vtysh_exit_sr_cmd
);
4344 install_element(SEGMENT_ROUTING_NODE
, &vtysh_quit_sr_cmd
);
4345 install_element(SEGMENT_ROUTING_NODE
, &vtysh_end_all_cmd
);
4347 #if defined(HAVE_PATHD)
4348 install_node(&sr_traffic_eng_node
);
4349 install_node(&srte_segment_list_node
);
4350 install_node(&srte_policy_node
);
4351 install_node(&srte_candidate_dyn_node
);
4353 install_element(SR_TRAFFIC_ENG_NODE
, &vtysh_exit_pathd_cmd
);
4354 install_element(SR_TRAFFIC_ENG_NODE
, &vtysh_quit_pathd_cmd
);
4355 install_element(SR_SEGMENT_LIST_NODE
, &vtysh_exit_pathd_cmd
);
4356 install_element(SR_SEGMENT_LIST_NODE
, &vtysh_quit_pathd_cmd
);
4357 install_element(SR_POLICY_NODE
, &vtysh_exit_pathd_cmd
);
4358 install_element(SR_POLICY_NODE
, &vtysh_quit_pathd_cmd
);
4359 install_element(SR_CANDIDATE_DYN_NODE
, &vtysh_exit_pathd_cmd
);
4360 install_element(SR_CANDIDATE_DYN_NODE
, &vtysh_quit_pathd_cmd
);
4363 install_element(SR_TRAFFIC_ENG_NODE
, &vtysh_end_all_cmd
);
4364 install_element(SR_SEGMENT_LIST_NODE
, &vtysh_end_all_cmd
);
4365 install_element(SR_POLICY_NODE
, &vtysh_end_all_cmd
);
4366 install_element(SR_CANDIDATE_DYN_NODE
, &vtysh_end_all_cmd
);
4368 install_element(CONFIG_NODE
, &segment_routing_cmd
);
4369 install_element(SEGMENT_ROUTING_NODE
, &sr_traffic_eng_cmd
);
4370 install_element(SR_TRAFFIC_ENG_NODE
, &srte_segment_list_cmd
);
4371 install_element(SR_TRAFFIC_ENG_NODE
, &srte_policy_cmd
);
4372 install_element(SR_POLICY_NODE
, &srte_policy_candidate_dyn_path_cmd
);
4374 #if defined(HAVE_PATHD_PCEP)
4375 install_node(&pcep_node
);
4376 install_node(&pcep_pcc_node
);
4377 install_node(&pcep_pce_node
);
4378 install_node(&pcep_pce_config_node
);
4380 install_element(PCEP_NODE
, &vtysh_exit_pathd_cmd
);
4381 install_element(PCEP_NODE
, &vtysh_quit_pathd_cmd
);
4382 install_element(PCEP_PCC_NODE
, &vtysh_exit_pathd_cmd
);
4383 install_element(PCEP_PCC_NODE
, &vtysh_quit_pathd_cmd
);
4384 install_element(PCEP_PCE_NODE
, &vtysh_exit_pathd_cmd
);
4385 install_element(PCEP_PCE_NODE
, &vtysh_quit_pathd_cmd
);
4386 install_element(PCEP_PCE_CONFIG_NODE
, &vtysh_exit_pathd_cmd
);
4387 install_element(PCEP_PCE_CONFIG_NODE
, &vtysh_quit_pathd_cmd
);
4389 install_element(PCEP_NODE
, &vtysh_end_all_cmd
);
4390 install_element(PCEP_PCC_NODE
, &vtysh_end_all_cmd
);
4391 install_element(PCEP_PCE_NODE
, &vtysh_end_all_cmd
);
4392 install_element(PCEP_PCE_CONFIG_NODE
, &vtysh_end_all_cmd
);
4394 install_element(SR_TRAFFIC_ENG_NODE
, &pcep_cmd
);
4395 install_element(PCEP_NODE
, &pcep_cli_pcc_cmd
);
4396 install_element(PCEP_NODE
, &pcep_cli_pcep_pce_config_cmd
);
4397 install_element(PCEP_NODE
, &pcep_cli_pce_cmd
);
4398 #endif /* HAVE_PATHD_PCEP */
4400 #endif /* HAVE_PATHD */
4403 install_node(&keychain_node
);
4404 install_element(CONFIG_NODE
, &key_chain_cmd
);
4405 install_element(KEYCHAIN_NODE
, &key_chain_cmd
);
4406 install_element(KEYCHAIN_NODE
, &vtysh_exit_keys_cmd
);
4407 install_element(KEYCHAIN_NODE
, &vtysh_quit_keys_cmd
);
4408 install_element(KEYCHAIN_NODE
, &vtysh_end_all_cmd
);
4410 install_node(&keychain_key_node
);
4411 install_element(KEYCHAIN_NODE
, &key_cmd
);
4412 install_element(KEYCHAIN_KEY_NODE
, &key_chain_cmd
);
4413 install_element(KEYCHAIN_KEY_NODE
, &vtysh_exit_keys_cmd
);
4414 install_element(KEYCHAIN_KEY_NODE
, &vtysh_quit_keys_cmd
);
4415 install_element(KEYCHAIN_KEY_NODE
, &vtysh_end_all_cmd
);
4418 install_node(&nh_group_node
);
4419 install_element(CONFIG_NODE
, &vtysh_nexthop_group_cmd
);
4420 install_element(CONFIG_NODE
, &vtysh_no_nexthop_group_cmd
);
4421 install_element(NH_GROUP_NODE
, &vtysh_end_all_cmd
);
4422 install_element(NH_GROUP_NODE
, &vtysh_exit_nexthop_group_cmd
);
4423 install_element(NH_GROUP_NODE
, &vtysh_quit_nexthop_group_cmd
);
4426 install_node(&zebra_node
);
4428 install_node(&interface_node
);
4429 install_element(CONFIG_NODE
, &vtysh_interface_cmd
);
4430 install_element(INTERFACE_NODE
, &vtysh_end_all_cmd
);
4431 install_element(INTERFACE_NODE
, &vtysh_exit_interface_cmd
);
4432 install_element(INTERFACE_NODE
, &vtysh_quit_interface_cmd
);
4434 install_node(&link_params_node
);
4435 install_element(INTERFACE_NODE
, &vtysh_link_params_cmd
);
4436 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);
4437 install_element(LINK_PARAMS_NODE
, &vtysh_end_all_cmd
);
4438 install_element(LINK_PARAMS_NODE
, &vtysh_exit_interface_cmd
);
4440 install_node(&pw_node
);
4441 install_element(CONFIG_NODE
, &vtysh_pseudowire_cmd
);
4442 install_element(PW_NODE
, &vtysh_end_all_cmd
);
4443 install_element(PW_NODE
, &vtysh_exit_interface_cmd
);
4444 install_element(PW_NODE
, &vtysh_quit_interface_cmd
);
4446 install_node(&vrf_node
);
4447 install_element(CONFIG_NODE
, &vtysh_vrf_cmd
);
4448 install_element(VRF_NODE
, &vtysh_vrf_netns_cmd
);
4449 install_element(VRF_NODE
, &vtysh_no_vrf_netns_cmd
);
4450 install_element(VRF_NODE
, &exit_vrf_config_cmd
);
4451 install_element(VRF_NODE
, &vtysh_end_all_cmd
);
4452 install_element(VRF_NODE
, &vtysh_exit_vrf_cmd
);
4453 install_element(VRF_NODE
, &vtysh_quit_vrf_cmd
);
4455 install_node(&rmap_node
);
4456 install_element(CONFIG_NODE
, &vtysh_route_map_cmd
);
4457 install_element(RMAP_NODE
, &vtysh_exit_rmap_cmd
);
4458 install_element(RMAP_NODE
, &vtysh_quit_rmap_cmd
);
4459 install_element(RMAP_NODE
, &vtysh_end_all_cmd
);
4461 install_node(&vty_node
);
4462 install_element(CONFIG_NODE
, &vtysh_line_vty_cmd
);
4463 install_element(VTY_NODE
, &vtysh_exit_line_vty_cmd
);
4464 install_element(VTY_NODE
, &vtysh_quit_line_vty_cmd
);
4465 install_element(VTY_NODE
, &vtysh_end_all_cmd
);
4468 struct cmd_node
*node
;
4469 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
4470 node
= vector_slot(cmdvec
, i
);
4471 if (!node
|| node
->node
== VIEW_NODE
)
4473 vtysh_install_default(node
->node
);
4478 install_element(VIEW_NODE
, &vtysh_enable_cmd
);
4479 install_element(ENABLE_NODE
, &vtysh_config_terminal_cmd
);
4480 install_element(ENABLE_NODE
, &vtysh_disable_cmd
);
4482 /* "exit" command. */
4483 install_element(VIEW_NODE
, &vtysh_exit_all_cmd
);
4484 install_element(CONFIG_NODE
, &vtysh_exit_all_cmd
);
4485 install_element(VIEW_NODE
, &vtysh_quit_all_cmd
);
4486 install_element(CONFIG_NODE
, &vtysh_quit_all_cmd
);
4488 /* "end" command. */
4489 install_element(CONFIG_NODE
, &vtysh_end_all_cmd
);
4490 install_element(ENABLE_NODE
, &vtysh_end_all_cmd
);
4492 /* SRv6 Data-plane */
4493 install_node(&srv6_node
);
4494 install_element(SEGMENT_ROUTING_NODE
, &srv6_cmd
);
4495 install_element(SRV6_NODE
, &srv6_locators_cmd
);
4496 install_element(SRV6_NODE
, &exit_srv6_config_cmd
);
4497 install_element(SRV6_NODE
, &vtysh_end_all_cmd
);
4499 install_node(&srv6_locs_node
);
4500 install_element(SRV6_LOCS_NODE
, &srv6_locator_cmd
);
4501 install_element(SRV6_LOCS_NODE
, &exit_srv6_locs_config_cmd
);
4502 install_element(SRV6_LOCS_NODE
, &vtysh_end_all_cmd
);
4504 install_node(&srv6_loc_node
);
4505 install_element(SRV6_LOC_NODE
, &exit_srv6_loc_config_cmd
);
4506 install_element(SRV6_LOC_NODE
, &vtysh_end_all_cmd
);
4508 install_element(ENABLE_NODE
, &vtysh_show_running_config_cmd
);
4509 install_element(ENABLE_NODE
, &vtysh_copy_running_config_cmd
);
4510 install_element(ENABLE_NODE
, &vtysh_copy_to_running_cmd
);
4512 /* "write terminal" command. */
4513 install_element(ENABLE_NODE
, &vtysh_write_terminal_cmd
);
4515 install_element(CONFIG_NODE
, &vtysh_integrated_config_cmd
);
4516 install_element(CONFIG_NODE
, &no_vtysh_integrated_config_cmd
);
4518 /* "write memory" command. */
4519 install_element(ENABLE_NODE
, &vtysh_write_memory_cmd
);
4521 install_element(CONFIG_NODE
, &vtysh_terminal_paginate_cmd
);
4522 install_element(VIEW_NODE
, &vtysh_terminal_paginate_cmd
);
4523 install_element(VIEW_NODE
, &vtysh_terminal_length_cmd
);
4524 install_element(VIEW_NODE
, &vtysh_terminal_no_length_cmd
);
4525 install_element(VIEW_NODE
, &vtysh_show_daemons_cmd
);
4527 install_element(VIEW_NODE
, &vtysh_ping_cmd
);
4528 install_element(VIEW_NODE
, &vtysh_ping_ip_cmd
);
4529 install_element(VIEW_NODE
, &vtysh_traceroute_cmd
);
4530 install_element(VIEW_NODE
, &vtysh_traceroute_ip_cmd
);
4531 install_element(VIEW_NODE
, &vtysh_mtrace_cmd
);
4532 install_element(VIEW_NODE
, &vtysh_ping6_cmd
);
4533 install_element(VIEW_NODE
, &vtysh_traceroute6_cmd
);
4534 #if defined(HAVE_SHELL_ACCESS)
4535 install_element(VIEW_NODE
, &vtysh_telnet_cmd
);
4536 install_element(VIEW_NODE
, &vtysh_telnet_port_cmd
);
4537 install_element(VIEW_NODE
, &vtysh_ssh_cmd
);
4539 #if defined(HAVE_SHELL_ACCESS)
4540 install_element(ENABLE_NODE
, &vtysh_start_shell_cmd
);
4541 install_element(ENABLE_NODE
, &vtysh_start_bash_cmd
);
4542 install_element(ENABLE_NODE
, &vtysh_start_zsh_cmd
);
4546 install_element(VIEW_NODE
, &vtysh_show_error_code_cmd
);
4547 install_element(ENABLE_NODE
, &vtysh_show_debugging_cmd
);
4548 install_element(ENABLE_NODE
, &vtysh_show_debugging_hashtable_cmd
);
4549 install_element(ENABLE_NODE
, &vtysh_debug_all_cmd
);
4550 install_element(CONFIG_NODE
, &vtysh_debug_all_cmd
);
4551 install_element(ENABLE_NODE
, &vtysh_debug_memstats_cmd
);
4552 install_element(CONFIG_NODE
, &vtysh_debug_memstats_cmd
);
4555 install_element(ENABLE_NODE
, &show_config_running_cmd
);
4556 install_element(ENABLE_NODE
, &show_yang_operational_data_cmd
);
4557 install_element(ENABLE_NODE
, &show_yang_module_cmd
);
4558 install_element(ENABLE_NODE
, &show_yang_module_detail_cmd
);
4559 install_element(ENABLE_NODE
, &debug_nb_cmd
);
4560 install_element(CONFIG_NODE
, &debug_nb_cmd
);
4562 /* misc lib show commands */
4563 install_element(VIEW_NODE
, &vtysh_show_history_cmd
);
4564 install_element(VIEW_NODE
, &vtysh_show_memory_cmd
);
4565 install_element(VIEW_NODE
, &vtysh_show_modules_cmd
);
4566 install_element(VIEW_NODE
, &vtysh_show_work_queues_cmd
);
4567 install_element(VIEW_NODE
, &vtysh_show_work_queues_daemon_cmd
);
4568 install_element(VIEW_NODE
, &vtysh_show_thread_cmd
);
4569 install_element(VIEW_NODE
, &vtysh_show_poll_cmd
);
4572 install_element(VIEW_NODE
, &vtysh_show_logging_cmd
);
4574 install_element(CONFIG_NODE
, &vtysh_service_password_encrypt_cmd
);
4575 install_element(CONFIG_NODE
, &no_vtysh_service_password_encrypt_cmd
);
4577 install_element(CONFIG_NODE
, &vtysh_password_cmd
);
4578 install_element(CONFIG_NODE
, &no_vtysh_password_cmd
);
4579 install_element(CONFIG_NODE
, &vtysh_enable_password_cmd
);
4580 install_element(CONFIG_NODE
, &no_vtysh_enable_password_cmd
);