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 && vty
->node
> CONFIG_NODE
) {
497 vty
->node
= node_parent(vty
->node
);
498 ret
= cmd_execute(vty
, line
, &cmd
, 1);
502 vty
->node
= saved_node
;
505 * If command succeeded in any other node than current (tried > 0) we
506 * have to move into node in the vtysh where it succeeded.
508 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
509 || ret
== CMD_WARNING
) {
510 if ((saved_node
== BGP_VPNV4_NODE
511 || saved_node
== BGP_VPNV6_NODE
512 || saved_node
== BGP_IPV4_NODE
513 || saved_node
== BGP_IPV6_NODE
514 || saved_node
== BGP_FLOWSPECV4_NODE
515 || saved_node
== BGP_FLOWSPECV6_NODE
516 || saved_node
== BGP_IPV4M_NODE
517 || saved_node
== BGP_IPV4L_NODE
518 || saved_node
== BGP_IPV6L_NODE
519 || saved_node
== BGP_IPV6M_NODE
520 || saved_node
== BGP_EVPN_NODE
521 || saved_node
== LDP_IPV4_NODE
522 || saved_node
== LDP_IPV6_NODE
)
524 vtysh_execute("exit-address-family");
525 } else if ((saved_node
== BGP_EVPN_VNI_NODE
) && (tried
== 1)) {
526 vtysh_execute("exit-vni");
527 } else if (saved_node
== BGP_VRF_POLICY_NODE
&& (tried
== 1)) {
528 vtysh_execute("exit-vrf-policy");
529 } else if ((saved_node
== BGP_VNC_DEFAULTS_NODE
530 || saved_node
== BGP_VNC_NVE_GROUP_NODE
531 || saved_node
== BGP_VNC_L2_GROUP_NODE
)
533 vtysh_execute("exit-vnc");
534 } else if (saved_node
== VRF_NODE
&& (tried
== 1)) {
535 vtysh_execute("exit-vrf");
536 } else if ((saved_node
== KEYCHAIN_KEY_NODE
537 || saved_node
== LDP_PSEUDOWIRE_NODE
538 || saved_node
== LDP_IPV4_IFACE_NODE
539 || saved_node
== LDP_IPV6_IFACE_NODE
)
541 vtysh_execute("exit");
542 } else if ((saved_node
== SR_SEGMENT_LIST_NODE
543 || saved_node
== SR_POLICY_NODE
544 || saved_node
== SR_CANDIDATE_DYN_NODE
545 || saved_node
== PCEP_NODE
546 || saved_node
== PCEP_PCE_CONFIG_NODE
547 || saved_node
== PCEP_PCE_NODE
548 || saved_node
== PCEP_PCC_NODE
)
550 vtysh_execute("exit");
552 vtysh_execute("end");
553 vtysh_execute("configure");
557 * If command didn't succeed in any node, continue with return value
564 cmd_free_strvec(vline
);
569 case CMD_WARNING_CONFIG_FAILED
:
570 if (vty
->type
== VTY_FILE
)
571 vty_out(vty
, "Warning...\n");
573 case CMD_ERR_AMBIGUOUS
:
574 vty_out(vty
, "%% Ambiguous command: %s\n", line
);
576 case CMD_ERR_NO_MATCH
:
577 vty_out(vty
, "%% Unknown command: %s\n", line
);
579 case CMD_ERR_INCOMPLETE
:
580 vty_out(vty
, "%% Command incomplete: %s\n", line
);
582 case CMD_SUCCESS_DAEMON
: {
584 * FIXME: Don't open pager for exit commands. popen() causes
585 * problems if exited from vtysh at all. This hack shouldn't
586 * cause any problem but is really ugly.
588 if (pager
&& strncmp(line
, "exit", 4))
591 if (!strcmp(cmd
->string
, "configure")) {
592 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
593 cmd_stat
= vtysh_client_execute(
594 &vtysh_client
[i
], line
);
595 if (cmd_stat
== CMD_WARNING
)
601 vline
= cmd_make_strvec(line
);
606 vty_close_pager(vty
);
610 ret
= cmd_execute_command(vline
, vty
, &cmd
, 1);
611 cmd_free_strvec(vline
);
612 if (ret
!= CMD_SUCCESS_DAEMON
)
614 } else if (cmd
->func
) {
615 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
620 cmd_stat
= CMD_SUCCESS
;
621 struct vtysh_client
*vc
;
622 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
623 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
624 if (vtysh_client
[i
].fd
< 0
625 && (cmd
->daemon
== vtysh_client
[i
].flag
)) {
626 for (vc
= &vtysh_client
[i
]; vc
;
628 if (vc
->fd
== VTYSH_WAS_ACTIVE
)
631 if (vtysh_client
[i
].fd
< 0
632 && (cmd
->daemon
== vtysh_client
[i
].flag
)) {
633 bool any_inst
= false;
634 for (vc
= &vtysh_client
[i
]; vc
;
640 "%s is not running\n",
641 vtysh_client
[i
].name
);
645 cmd_stat
= vtysh_client_execute(
646 &vtysh_client
[i
], line
);
647 if (cmd_stat
!= CMD_SUCCESS
)
651 if (cmd_stat
!= CMD_SUCCESS
)
655 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
659 vty_close_pager(vty
);
664 int vtysh_execute_no_pager(const char *line
)
666 return vtysh_execute_func(line
, 0);
669 int vtysh_execute(const char *line
)
671 return vtysh_execute_func(line
, 1);
674 static char *trim(char *s
)
685 while (end
>= s
&& isspace((unsigned char)*end
))
689 while (*s
&& isspace((unsigned char)*s
))
695 int vtysh_mark_file(const char *filename
)
703 const struct cmd_element
*cmd
;
704 int saved_ret
, prev_node
;
706 char *vty_buf_copy
= NULL
;
707 char *vty_buf_trimmed
= NULL
;
709 if (strncmp("-", filename
, 1) == 0)
712 confp
= fopen(filename
, "r");
715 fprintf(stderr
, "%% Can't open config file %s due to '%s'.\n",
716 filename
, safe_strerror(errno
));
717 return CMD_ERR_NO_FILE
;
721 vty
->wfd
= STDOUT_FILENO
;
722 vty
->type
= VTY_TERM
;
723 vty
->node
= CONFIG_NODE
;
725 vtysh_execute_no_pager("enable");
726 vtysh_execute_no_pager("configure");
727 vty_buf_copy
= XCALLOC(MTYPE_VTYSH_CMD
, VTY_BUFSIZ
);
729 while (fgets(vty
->buf
, VTY_BUFSIZ
, confp
)) {
732 strlcpy(vty_buf_copy
, vty
->buf
, VTY_BUFSIZ
);
733 vty_buf_trimmed
= trim(vty_buf_copy
);
736 case LDP_IPV4_IFACE_NODE
:
737 if (strncmp(vty_buf_copy
, " ", 3)) {
738 vty_out(vty
, " exit-ldp-if\n");
739 vty
->node
= LDP_IPV4_NODE
;
742 case LDP_IPV6_IFACE_NODE
:
743 if (strncmp(vty_buf_copy
, " ", 3)) {
744 vty_out(vty
, " exit-ldp-if\n");
745 vty
->node
= LDP_IPV6_NODE
;
748 case LDP_PSEUDOWIRE_NODE
:
749 if (strncmp(vty_buf_copy
, " ", 2)) {
750 vty_out(vty
, " exit\n");
751 vty
->node
= LDP_L2VPN_NODE
;
754 case SR_CANDIDATE_DYN_NODE
:
755 if (strncmp(vty_buf_copy
, " ", 2)) {
756 vty_out(vty
, " exit\n");
757 vty
->node
= SR_POLICY_NODE
;
764 if (vty_buf_trimmed
[0] == '!' || vty_buf_trimmed
[0] == '#') {
765 vty_out(vty
, "%s", vty
->buf
);
769 /* Split readline string up into the vector. */
770 vline
= cmd_make_strvec(vty
->buf
);
773 vty_out(vty
, "%s", vty
->buf
);
778 * Ignore the "end" lines, we will generate these where
781 if (strlen(vty_buf_trimmed
) == 3
782 && strncmp("end", vty_buf_trimmed
, 3) == 0) {
783 cmd_free_strvec(vline
);
787 prev_node
= vty
->node
;
788 saved_ret
= ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
791 * If command doesn't succeeded in current node, try to walk up
792 * in node tree. Changing vty->node is enough to try it just
793 * out without actual walkup in the vtysh.
795 while (ret
!= CMD_SUCCESS
&& ret
!= CMD_SUCCESS_DAEMON
796 && ret
!= CMD_WARNING
&& ret
!= CMD_WARNING_CONFIG_FAILED
797 && vty
->node
> CONFIG_NODE
) {
798 vty
->node
= node_parent(vty
->node
);
799 ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
804 * If command succeeded in any other node than current (tried >
805 * 0) we have to move into node in the vtysh where it
808 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
809 || ret
== CMD_WARNING
) {
810 if ((prev_node
== BGP_VPNV4_NODE
811 || prev_node
== BGP_VPNV6_NODE
812 || prev_node
== BGP_IPV4_NODE
813 || prev_node
== BGP_IPV6_NODE
814 || prev_node
== BGP_FLOWSPECV4_NODE
815 || prev_node
== BGP_FLOWSPECV6_NODE
816 || prev_node
== BGP_IPV4L_NODE
817 || prev_node
== BGP_IPV6L_NODE
818 || prev_node
== BGP_IPV4M_NODE
819 || prev_node
== BGP_IPV6M_NODE
820 || prev_node
== BGP_EVPN_NODE
)
822 vty_out(vty
, "exit-address-family\n");
823 } else if ((prev_node
== BGP_EVPN_VNI_NODE
)
825 vty_out(vty
, "exit-vni\n");
826 } else if ((prev_node
== KEYCHAIN_KEY_NODE
)
828 vty_out(vty
, "exit\n");
829 } else if ((prev_node
== BFD_PEER_NODE
)
831 vty_out(vty
, "exit\n");
832 } else if (((prev_node
== SEGMENT_ROUTING_NODE
)
833 || (prev_node
== SR_TRAFFIC_ENG_NODE
)
834 || (prev_node
== SR_SEGMENT_LIST_NODE
)
835 || (prev_node
== SR_POLICY_NODE
)
836 || (prev_node
== SR_CANDIDATE_DYN_NODE
)
837 || (prev_node
== PCEP_NODE
)
838 || (prev_node
== PCEP_PCE_CONFIG_NODE
)
839 || (prev_node
== PCEP_PCE_NODE
)
840 || (prev_node
== PCEP_PCC_NODE
))
842 ending
= (vty
->node
!= SEGMENT_ROUTING_NODE
)
843 && (vty
->node
!= SR_TRAFFIC_ENG_NODE
)
844 && (vty
->node
!= SR_SEGMENT_LIST_NODE
)
845 && (vty
->node
!= SR_POLICY_NODE
)
846 && (vty
->node
!= SR_CANDIDATE_DYN_NODE
)
847 && (vty
->node
!= PCEP_NODE
)
848 && (vty
->node
!= PCEP_PCE_CONFIG_NODE
)
849 && (vty
->node
!= PCEP_PCE_NODE
)
850 && (vty
->node
!= PCEP_PCC_NODE
);
854 vty_out(vty
, "exit\n");
856 vty_out(vty
, "end\n");
858 vty_out(vty
, "end\n");
862 * If command didn't succeed in any node, continue with return
863 * value from first try.
867 vty
->node
= prev_node
;
870 cmd_free_strvec(vline
);
873 case CMD_WARNING_CONFIG_FAILED
:
874 if (vty
->type
== VTY_FILE
)
875 fprintf(stderr
, "line %d: Warning...: %s\n",
879 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
881 case CMD_ERR_AMBIGUOUS
:
882 fprintf(stderr
, "line %d: %% Ambiguous command: %s\n",
886 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
887 return CMD_ERR_AMBIGUOUS
;
888 case CMD_ERR_NO_MATCH
:
889 fprintf(stderr
, "line %d: %% Unknown command: %s\n",
893 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
894 return CMD_ERR_NO_MATCH
;
895 case CMD_ERR_INCOMPLETE
:
896 fprintf(stderr
, "line %d: %% Command incomplete: %s\n",
900 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
901 return CMD_ERR_INCOMPLETE
;
903 vty_out(vty
, "%s", vty
->buf
);
904 if (strmatch(vty_buf_trimmed
, "exit-vrf"))
905 vty_out(vty
, "end\n");
907 case CMD_SUCCESS_DAEMON
: {
910 vty_out(vty
, "%s", vty
->buf
);
911 if (strmatch(vty_buf_trimmed
, "exit-vrf"))
912 vty_out(vty
, "end\n");
913 cmd_stat
= vtysh_client_execute(&vtysh_client
[0],
915 if (cmd_stat
!= CMD_SUCCESS
)
919 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
923 /* This is the end */
924 vty_out(vty
, "\nend\n");
926 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
934 /* Configration make from file. */
935 int vtysh_config_from_file(struct vty
*vty
, FILE *fp
)
938 const struct cmd_element
*cmd
;
940 /* once we have an error, we remember & return that */
941 int retcode
= CMD_SUCCESS
;
943 while (fgets(vty
->buf
, VTY_BUFSIZ
, fp
)) {
946 ret
= command_config_read_one_line(vty
, &cmd
, lineno
, 1);
950 case CMD_WARNING_CONFIG_FAILED
:
951 if (vty
->type
== VTY_FILE
)
952 fprintf(stderr
, "line %d: Warning[%d]...: %s\n",
953 lineno
, vty
->node
, vty
->buf
);
957 case CMD_ERR_AMBIGUOUS
:
959 "line %d: %% Ambiguous command[%d]: %s\n",
960 lineno
, vty
->node
, vty
->buf
);
961 retcode
= CMD_ERR_AMBIGUOUS
;
963 case CMD_ERR_NO_MATCH
:
964 fprintf(stderr
, "line %d: %% Unknown command[%d]: %s",
965 lineno
, vty
->node
, vty
->buf
);
966 retcode
= CMD_ERR_NO_MATCH
;
968 case CMD_ERR_INCOMPLETE
:
970 "line %d: %% Command incomplete[%d]: %s\n",
971 lineno
, vty
->node
, vty
->buf
);
972 retcode
= CMD_ERR_INCOMPLETE
;
974 case CMD_SUCCESS_DAEMON
: {
976 int cmd_stat
= CMD_SUCCESS
;
978 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
979 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
980 cmd_stat
= vtysh_client_execute(
981 &vtysh_client
[i
], vty
->buf
);
983 * CMD_WARNING - Can mean that the
984 * command was parsed successfully but
985 * it was already entered in a few
986 * spots. As such if we receive a
987 * CMD_WARNING from a daemon we
988 * shouldn't stop talking to the other
989 * daemons for the particular command.
991 if (cmd_stat
!= CMD_SUCCESS
992 && cmd_stat
!= CMD_WARNING
) {
994 "line %d: Failure to communicate[%d] to %s, line: %s\n",
996 vtysh_client
[i
].name
,
1003 if (cmd_stat
!= CMD_SUCCESS
)
1007 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
1016 * Function processes cli commands terminated with '?' character when entered
1017 * through either 'vtysh' or 'vtysh -c' interfaces.
1019 static int vtysh_process_questionmark(const char *input
, int input_len
)
1023 vector vline
, describe
;
1024 struct cmd_token
*token
;
1029 vline
= cmd_make_strvec(input
);
1031 /* In case of '> ?'. */
1032 if (vline
== NULL
) {
1033 vline
= vector_init(1);
1034 vector_set(vline
, NULL
);
1035 } else if (input_len
&& isspace((unsigned char)input
[input_len
- 1]))
1036 vector_set(vline
, NULL
);
1038 describe
= cmd_describe_command(vline
, vty
, &ret
);
1040 /* Ambiguous and no match error. */
1042 case CMD_ERR_AMBIGUOUS
:
1043 cmd_free_strvec(vline
);
1044 vector_free(describe
);
1045 vty_out(vty
, "%% Ambiguous command.\n");
1048 case CMD_ERR_NO_MATCH
:
1049 cmd_free_strvec(vline
);
1051 vector_free(describe
);
1052 vty_out(vty
, "%% There is no matched command.\n");
1057 /* Get width of command string. */
1059 for (i
= 0; i
< vector_active(describe
); i
++)
1060 if ((token
= vector_slot(describe
, i
)) != NULL
) {
1061 if (token
->text
[0] == '\0')
1064 int len
= strlen(token
->text
);
1070 for (i
= 0; i
< vector_active(describe
); i
++)
1071 if ((token
= vector_slot(describe
, i
)) != NULL
) {
1073 vty_out(vty
, " %-s\n", token
->text
);
1075 vty_out(vty
, " %-*s %s\n", width
, token
->text
,
1078 if (IS_VARYING_TOKEN(token
->type
)) {
1079 const char *ref
= vector_slot(
1080 vline
, vector_active(vline
) - 1);
1082 vector varcomps
= vector_init(VECTOR_MIN_SIZE
);
1083 cmd_variable_complete(token
, ref
, varcomps
);
1085 if (vector_active(varcomps
) > 0) {
1087 rl_get_screen_size(&rows
, &cols
);
1089 char *ac
= cmd_variable_comp2str(
1091 vty_out(vty
, "%s\n", ac
);
1092 XFREE(MTYPE_TMP
, ac
);
1095 vector_free(varcomps
);
1099 cmd_free_strvec(vline
);
1100 vector_free(describe
);
1106 * Entry point for user commands terminated with '?' character and typed through
1107 * the usual vtysh's stdin interface. This is the function being registered with
1110 static int vtysh_rl_describe(int a
, int b
)
1116 ret
= vtysh_process_questionmark(rl_line_buffer
, rl_end
);
1123 * Function in charged of processing vtysh instructions terminating with '?'
1124 * character and received through the 'vtysh -c' interface. If user's
1125 * instruction is well-formatted, we will call the same processing routine
1126 * utilized by the traditional vtysh's stdin interface.
1128 int vtysh_execute_command_questionmark(char *input
)
1130 int input_len
, qmark_count
= 0;
1133 if (!(input
&& *input
))
1136 /* Finding out question_mark count and strlen */
1137 for (str
= input
; *str
; ++str
) {
1141 input_len
= str
- input
;
1144 * Verify that user's input terminates in '?' and that patterns such as
1145 * 'cmd ? subcmd ?' are prevented.
1147 if (qmark_count
!= 1 || input
[input_len
- 1] != '?')
1151 * Questionmark-processing function is not expecting to receive '?'
1152 * character in input string.
1154 input
[input_len
- 1] = '\0';
1156 return vtysh_process_questionmark(input
, input_len
- 1);
1159 /* Result of cmd_complete_command() call will be stored here
1160 * and used in new_completion() in order to put the space in
1161 * correct places only. */
1162 int complete_status
;
1164 static char *command_generator(const char *text
, int state
)
1167 static char **matched
= NULL
;
1168 static int index
= 0;
1174 if (vty
->node
== AUTH_NODE
|| vty
->node
== AUTH_ENABLE_NODE
)
1177 vline
= cmd_make_strvec(rl_line_buffer
);
1182 isspace((unsigned char)rl_line_buffer
[rl_end
- 1]))
1183 vector_set(vline
, NULL
);
1185 matched
= cmd_complete_command(vline
, vty
, &complete_status
);
1186 cmd_free_strvec(vline
);
1189 if (matched
&& matched
[index
]) {
1190 XCOUNTFREE(MTYPE_COMPLETION
, matched
[index
]);
1191 return matched
[index
++];
1194 XFREE(MTYPE_TMP
, matched
);
1199 static char **new_completion(const char *text
, int start
, int end
)
1203 matches
= rl_completion_matches(text
, command_generator
);
1207 if (complete_status
!= CMD_COMPLETE_FULL_MATCH
)
1208 /* only append a space on full match */
1209 rl_completion_append_character
= '\0';
1215 /* Vty node structures. */
1217 static struct cmd_node bgp_node
= {
1220 .parent_node
= CONFIG_NODE
,
1221 .prompt
= "%s(config-router)# ",
1223 #endif /* HAVE_BGPD */
1225 static struct cmd_node rip_node
= {
1228 .parent_node
= CONFIG_NODE
,
1229 .prompt
= "%s(config-router)# ",
1233 static struct cmd_node isis_node
= {
1236 .parent_node
= CONFIG_NODE
,
1237 .prompt
= "%s(config-router)# ",
1239 #endif /* HAVE_ISISD */
1242 static struct cmd_node openfabric_node
= {
1243 .name
= "openfabric",
1244 .node
= OPENFABRIC_NODE
,
1245 .parent_node
= CONFIG_NODE
,
1246 .prompt
= "%s(config-router)# ",
1248 #endif /* HAVE_FABRICD */
1250 static struct cmd_node interface_node
= {
1251 .name
= "interface",
1252 .node
= INTERFACE_NODE
,
1253 .parent_node
= CONFIG_NODE
,
1254 .prompt
= "%s(config-if)# ",
1257 static struct cmd_node pw_node
= {
1260 .parent_node
= CONFIG_NODE
,
1261 .prompt
= "%s(config-pw)# ",
1264 #if defined(HAVE_PATHD)
1265 static struct cmd_node segment_routing_node
= {
1266 .name
= "segment-routing",
1267 .node
= SEGMENT_ROUTING_NODE
,
1268 .parent_node
= CONFIG_NODE
,
1269 .prompt
= "%s(config-sr)# ",
1272 static struct cmd_node sr_traffic_eng_node
= {
1273 .name
= "sr traffic-eng",
1274 .node
= SR_TRAFFIC_ENG_NODE
,
1275 .parent_node
= SEGMENT_ROUTING_NODE
,
1276 .prompt
= "%s(config-sr-te)# ",
1279 static struct cmd_node srte_segment_list_node
= {
1280 .name
= "srte segment-list",
1281 .node
= SR_SEGMENT_LIST_NODE
,
1282 .parent_node
= SR_TRAFFIC_ENG_NODE
,
1283 .prompt
= "%s(config-sr-te-segment-list)# ",
1286 static struct cmd_node srte_policy_node
= {
1287 .name
= "srte policy",
1288 .node
= SR_POLICY_NODE
,
1289 .parent_node
= SR_TRAFFIC_ENG_NODE
,
1290 .prompt
= "%s(config-sr-te-policy)# ",
1293 static struct cmd_node srte_candidate_dyn_node
= {
1294 .name
= "srte candidate-dyn",
1295 .node
= SR_CANDIDATE_DYN_NODE
,
1296 .parent_node
= SR_POLICY_NODE
,
1297 .prompt
= "%s(config-sr-te-candidate)# ",
1300 #if defined(HAVE_PATHD_PCEP)
1301 static struct cmd_node pcep_node
= {
1302 .name
= "srte pcep",
1304 .parent_node
= SR_TRAFFIC_ENG_NODE
,
1305 .prompt
= "%s(config-sr-te-pcep)# "
1308 static struct cmd_node pcep_pcc_node
= {
1309 .name
= "srte pcep pcc",
1310 .node
= PCEP_PCC_NODE
,
1311 .parent_node
= PCEP_NODE
,
1312 .prompt
= "%s(config-sr-te-pcep-pcc)# ",
1315 static struct cmd_node pcep_pce_node
= {
1316 .name
= "srte pcep pce-peer",
1317 .node
= PCEP_PCE_NODE
,
1318 .parent_node
= PCEP_NODE
,
1319 .prompt
= "%s(config-sr-te-pcep-pce-peer)# ",
1322 static struct cmd_node pcep_pce_config_node
= {
1323 .name
= "srte pcep pce-config",
1324 .node
= PCEP_PCE_CONFIG_NODE
,
1325 .parent_node
= PCEP_NODE
,
1326 .prompt
= "%s(pcep-sr-te-pcep-pce-config)# ",
1328 #endif /* HAVE_PATHD_PCEP */
1329 #endif /* HAVE_PATHD */
1331 static struct cmd_node vrf_node
= {
1334 .parent_node
= CONFIG_NODE
,
1335 .prompt
= "%s(config-vrf)# ",
1338 static struct cmd_node nh_group_node
= {
1339 .name
= "nexthop-group",
1340 .node
= NH_GROUP_NODE
,
1341 .parent_node
= CONFIG_NODE
,
1342 .prompt
= "%s(config-nh-group)# ",
1345 static struct cmd_node rmap_node
= {
1348 .parent_node
= CONFIG_NODE
,
1349 .prompt
= "%s(config-route-map)# ",
1352 static struct cmd_node srv6_node
= {
1355 .parent_node
= SEGMENT_ROUTING_NODE
,
1356 .prompt
= "%s(config-srv6)# ",
1359 static struct cmd_node srv6_locs_node
= {
1360 .name
= "srv6-locators",
1361 .node
= SRV6_LOCS_NODE
,
1362 .parent_node
= SRV6_NODE
,
1363 .prompt
= "%s(config-srv6-locators)# ",
1366 static struct cmd_node srv6_loc_node
= {
1367 .name
= "srv6-locator",
1368 .node
= SRV6_LOC_NODE
,
1369 .parent_node
= SRV6_LOCS_NODE
,
1370 .prompt
= "%s(config-srv6-locator)# ",
1374 static struct cmd_node pbr_map_node
= {
1376 .node
= PBRMAP_NODE
,
1377 .parent_node
= CONFIG_NODE
,
1378 .prompt
= "%s(config-pbr-map)# ",
1380 #endif /* HAVE_PBRD */
1382 static struct cmd_node zebra_node
= {
1385 .parent_node
= CONFIG_NODE
,
1386 .prompt
= "%s(config-router)# ",
1390 static struct cmd_node bgp_vpnv4_node
= {
1391 .name
= "bgp vpnv4",
1392 .node
= BGP_VPNV4_NODE
,
1393 .parent_node
= BGP_NODE
,
1394 .prompt
= "%s(config-router-af)# ",
1397 static struct cmd_node bgp_vpnv6_node
= {
1398 .name
= "bgp vpnv6",
1399 .node
= BGP_VPNV6_NODE
,
1400 .parent_node
= BGP_NODE
,
1401 .prompt
= "%s(config-router-af)# ",
1404 static struct cmd_node bgp_flowspecv4_node
= {
1405 .name
= "bgp ipv4 flowspec",
1406 .node
= BGP_FLOWSPECV4_NODE
,
1407 .parent_node
= BGP_NODE
,
1408 .prompt
= "%s(config-router-af)# ",
1411 static struct cmd_node bgp_flowspecv6_node
= {
1412 .name
= "bgp ipv6 flowspec",
1413 .node
= BGP_FLOWSPECV6_NODE
,
1414 .parent_node
= BGP_NODE
,
1415 .prompt
= "%s(config-router-af)# ",
1418 static struct cmd_node bgp_ipv4_node
= {
1419 .name
= "bgp ipv4 unicast",
1420 .node
= BGP_IPV4_NODE
,
1421 .parent_node
= BGP_NODE
,
1422 .prompt
= "%s(config-router-af)# ",
1425 static struct cmd_node bgp_ipv4m_node
= {
1426 .name
= "bgp ipv4 multicast",
1427 .node
= BGP_IPV4M_NODE
,
1428 .parent_node
= BGP_NODE
,
1429 .prompt
= "%s(config-router-af)# ",
1432 static struct cmd_node bgp_ipv4l_node
= {
1433 .name
= "bgp ipv4 labeled unicast",
1434 .node
= BGP_IPV4L_NODE
,
1435 .parent_node
= BGP_NODE
,
1436 .prompt
= "%s(config-router-af)# ",
1439 static struct cmd_node bgp_ipv6_node
= {
1441 .node
= BGP_IPV6_NODE
,
1442 .parent_node
= BGP_NODE
,
1443 .prompt
= "%s(config-router-af)# ",
1446 static struct cmd_node bgp_ipv6m_node
= {
1447 .name
= "bgp ipv6 multicast",
1448 .node
= BGP_IPV6M_NODE
,
1449 .parent_node
= BGP_NODE
,
1450 .prompt
= "%s(config-router-af)# ",
1453 static struct cmd_node bgp_evpn_node
= {
1455 .node
= BGP_EVPN_NODE
,
1456 .parent_node
= BGP_NODE
,
1457 .prompt
= "%s(config-router-af)# ",
1460 static struct cmd_node bgp_evpn_vni_node
= {
1461 .name
= "bgp evpn vni",
1462 .node
= BGP_EVPN_VNI_NODE
,
1463 .parent_node
= BGP_EVPN_NODE
,
1464 .prompt
= "%s(config-router-af-vni)# ",
1467 static struct cmd_node bgp_ipv6l_node
= {
1468 .name
= "bgp ipv6 labeled unicast",
1469 .node
= BGP_IPV6L_NODE
,
1470 .parent_node
= BGP_NODE
,
1471 .prompt
= "%s(config-router-af)# ",
1474 #ifdef ENABLE_BGP_VNC
1475 static struct cmd_node bgp_vnc_defaults_node
= {
1476 .name
= "bgp vnc defaults",
1477 .node
= BGP_VNC_DEFAULTS_NODE
,
1478 .parent_node
= BGP_NODE
,
1479 .prompt
= "%s(config-router-vnc-defaults)# ",
1482 static struct cmd_node bgp_vnc_nve_group_node
= {
1483 .name
= "bgp vnc nve",
1484 .node
= BGP_VNC_NVE_GROUP_NODE
,
1485 .parent_node
= BGP_NODE
,
1486 .prompt
= "%s(config-router-vnc-nve-group)# ",
1489 static struct cmd_node bgp_vrf_policy_node
= {
1490 .name
= "bgp vrf policy",
1491 .node
= BGP_VRF_POLICY_NODE
,
1492 .parent_node
= BGP_NODE
,
1493 .prompt
= "%s(config-router-vrf-policy)# ",
1496 static struct cmd_node bgp_vnc_l2_group_node
= {
1497 .name
= "bgp vnc l2",
1498 .node
= BGP_VNC_L2_GROUP_NODE
,
1499 .parent_node
= BGP_NODE
,
1500 .prompt
= "%s(config-router-vnc-l2-group)# ",
1502 #endif /* ENABLE_BGP_VNC */
1504 static struct cmd_node bmp_node
= {
1507 .parent_node
= BGP_NODE
,
1508 .prompt
= "%s(config-bgp-bmp)# "
1511 static struct cmd_node bgp_srv6_node
= {
1513 .node
= BGP_SRV6_NODE
,
1514 .parent_node
= BGP_NODE
,
1515 .prompt
= "%s(config-router-srv6)# ",
1517 #endif /* HAVE_BGPD */
1520 static struct cmd_node ospf_node
= {
1523 .parent_node
= CONFIG_NODE
,
1524 .prompt
= "%s(config-router)# ",
1526 #endif /* HAVE_OSPFD */
1529 static struct cmd_node eigrp_node
= {
1532 .parent_node
= CONFIG_NODE
,
1533 .prompt
= "%s(config-router)# ",
1535 #endif /* HAVE_EIGRPD */
1538 static struct cmd_node babel_node
= {
1541 .parent_node
= CONFIG_NODE
,
1542 .prompt
= "%s(config-router)# ",
1544 #endif /* HAVE_BABELD */
1546 static struct cmd_node ripng_node
= {
1549 .parent_node
= CONFIG_NODE
,
1550 .prompt
= "%s(config-router)# ",
1554 static struct cmd_node ospf6_node
= {
1557 .parent_node
= CONFIG_NODE
,
1558 .prompt
= "%s(config-ospf6)# ",
1560 #endif /* HAVE_OSPF6D */
1563 static struct cmd_node ldp_node
= {
1566 .parent_node
= CONFIG_NODE
,
1567 .prompt
= "%s(config-ldp)# ",
1570 static struct cmd_node ldp_ipv4_node
= {
1572 .node
= LDP_IPV4_NODE
,
1573 .parent_node
= LDP_NODE
,
1574 .prompt
= "%s(config-ldp-af)# ",
1577 static struct cmd_node ldp_ipv6_node
= {
1579 .node
= LDP_IPV6_NODE
,
1580 .parent_node
= LDP_NODE
,
1581 .prompt
= "%s(config-ldp-af)# ",
1584 static struct cmd_node ldp_ipv4_iface_node
= {
1585 .name
= "ldp ipv4 interface",
1586 .node
= LDP_IPV4_IFACE_NODE
,
1587 .parent_node
= LDP_IPV4_NODE
,
1588 .prompt
= "%s(config-ldp-af-if)# ",
1591 static struct cmd_node ldp_ipv6_iface_node
= {
1592 .name
= "ldp ipv6 interface",
1593 .node
= LDP_IPV6_IFACE_NODE
,
1594 .parent_node
= LDP_IPV6_NODE
,
1595 .prompt
= "%s(config-ldp-af-if)# ",
1598 static struct cmd_node ldp_l2vpn_node
= {
1599 .name
= "ldp l2vpn",
1600 .node
= LDP_L2VPN_NODE
,
1601 .parent_node
= CONFIG_NODE
,
1602 .prompt
= "%s(config-l2vpn)# ",
1605 static struct cmd_node ldp_pseudowire_node
= {
1607 .node
= LDP_PSEUDOWIRE_NODE
,
1608 .parent_node
= LDP_L2VPN_NODE
,
1609 .prompt
= "%s(config-l2vpn-pw)# ",
1611 #endif /* HAVE_LDPD */
1613 static struct cmd_node keychain_node
= {
1615 .node
= KEYCHAIN_NODE
,
1616 .parent_node
= CONFIG_NODE
,
1617 .prompt
= "%s(config-keychain)# ",
1620 static struct cmd_node keychain_key_node
= {
1621 .name
= "keychain key",
1622 .node
= KEYCHAIN_KEY_NODE
,
1623 .parent_node
= KEYCHAIN_NODE
,
1624 .prompt
= "%s(config-keychain-key)# ",
1627 struct cmd_node link_params_node
= {
1628 .name
= "link-params",
1629 .node
= LINK_PARAMS_NODE
,
1630 .parent_node
= INTERFACE_NODE
,
1631 .prompt
= "%s(config-link-params)# ",
1635 static struct cmd_node rpki_node
= {
1638 .parent_node
= CONFIG_NODE
,
1639 .prompt
= "%s(config-rpki)# ",
1641 #endif /* HAVE_BGPD */
1644 static struct cmd_node bfd_node
= {
1647 .parent_node
= CONFIG_NODE
,
1648 .prompt
= "%s(config-bfd)# ",
1651 static struct cmd_node bfd_peer_node
= {
1653 .node
= BFD_PEER_NODE
,
1654 .parent_node
= BFD_NODE
,
1655 .prompt
= "%s(config-bfd-peer)# ",
1658 static struct cmd_node bfd_profile_node
= {
1659 .name
= "bfd profile",
1660 .node
= BFD_PROFILE_NODE
,
1661 .parent_node
= BFD_NODE
,
1662 .prompt
= "%s(config-bfd-profile)# ",
1664 #endif /* HAVE_BFDD */
1666 /* Defined in lib/vty.c */
1667 extern struct cmd_node vty_node
;
1669 /* When '^Z' is received from vty, move down to the enable mode. */
1670 static int vtysh_end(void)
1672 switch (vty
->node
) {
1675 /* Nothing to do. */
1678 vty
->node
= ENABLE_NODE
;
1684 DEFUNSH(VTYSH_REALLYALL
, vtysh_end_all
, vtysh_end_all_cmd
, "end",
1685 "End current mode and change to enable mode\n")
1690 DEFUNSH(VTYSH_SR
, srv6
, srv6_cmd
,
1692 "Segment-Routing SRv6 configration\n")
1694 vty
->node
= SRV6_NODE
;
1698 DEFUNSH(VTYSH_SR
, srv6_locators
, srv6_locators_cmd
,
1700 "Segment-Routing SRv6 locators configration\n")
1702 vty
->node
= SRV6_LOCS_NODE
;
1706 DEFUNSH(VTYSH_SR
, srv6_locator
, srv6_locator_cmd
,
1708 "Segment Routing SRv6 locator\n"
1709 "Specify locator-name\n")
1711 vty
->node
= SRV6_LOC_NODE
;
1716 DEFUNSH(VTYSH_BGPD
, router_bgp
, router_bgp_cmd
,
1717 "router bgp [(1-4294967295) [<view|vrf> WORD]]",
1718 ROUTER_STR BGP_STR AS_STR
1719 "BGP view\nBGP VRF\n"
1722 vty
->node
= BGP_NODE
;
1726 #ifdef KEEP_OLD_VPN_COMMANDS
1727 DEFUNSH(VTYSH_BGPD
, address_family_vpnv4
, address_family_vpnv4_cmd
,
1728 "address-family vpnv4 [unicast]",
1729 "Enter Address Family command mode\n"
1731 "Address Family modifier\n")
1733 vty
->node
= BGP_VPNV4_NODE
;
1737 DEFUNSH(VTYSH_BGPD
, address_family_vpnv6
, address_family_vpnv6_cmd
,
1738 "address-family vpnv6 [unicast]",
1739 "Enter Address Family command mode\n"
1741 "Address Family modifier\n")
1743 vty
->node
= BGP_VPNV6_NODE
;
1746 #endif /* KEEP_OLD_VPN_COMMANDS */
1748 DEFUNSH(VTYSH_BGPD
, address_family_ipv4
, address_family_ipv4_cmd
,
1749 "address-family ipv4 [unicast]",
1750 "Enter Address Family command mode\n"
1752 "Address Family Modifier\n")
1754 vty
->node
= BGP_IPV4_NODE
;
1758 DEFUNSH(VTYSH_BGPD
, address_family_flowspecv4
, address_family_flowspecv4_cmd
,
1759 "address-family ipv4 flowspec",
1760 "Enter Address Family command mode\n"
1762 "Address Family Modifier\n")
1764 vty
->node
= BGP_FLOWSPECV4_NODE
;
1768 DEFUNSH(VTYSH_BGPD
, address_family_flowspecv6
, address_family_flowspecv6_cmd
,
1769 "address-family ipv6 flowspec",
1770 "Enter Address Family command mode\n"
1772 "Address Family Modifier\n")
1774 vty
->node
= BGP_FLOWSPECV6_NODE
;
1778 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_multicast
,
1779 address_family_ipv4_multicast_cmd
, "address-family ipv4 multicast",
1780 "Enter Address Family command mode\n"
1782 "Address Family modifier\n")
1784 vty
->node
= BGP_IPV4M_NODE
;
1788 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_vpn
, address_family_ipv4_vpn_cmd
,
1789 "address-family ipv4 vpn",
1790 "Enter Address Family command mode\n"
1792 "Address Family modifier\n")
1794 vty
->node
= BGP_VPNV4_NODE
;
1798 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_labeled_unicast
,
1799 address_family_ipv4_labeled_unicast_cmd
,
1800 "address-family ipv4 labeled-unicast",
1801 "Enter Address Family command mode\n"
1803 "Address Family modifier\n")
1805 vty
->node
= BGP_IPV4L_NODE
;
1809 DEFUNSH(VTYSH_BGPD
, address_family_ipv6
, address_family_ipv6_cmd
,
1810 "address-family ipv6 [unicast]",
1811 "Enter Address Family command mode\n"
1813 "Address Family modifier\n")
1815 vty
->node
= BGP_IPV6_NODE
;
1819 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_multicast
,
1820 address_family_ipv6_multicast_cmd
, "address-family ipv6 multicast",
1821 "Enter Address Family command mode\n"
1823 "Address Family modifier\n")
1825 vty
->node
= BGP_IPV6M_NODE
;
1829 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_vpn
, address_family_ipv6_vpn_cmd
,
1830 "address-family ipv6 vpn",
1831 "Enter Address Family command mode\n"
1833 "Address Family modifier\n")
1835 vty
->node
= BGP_VPNV6_NODE
;
1839 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_labeled_unicast
,
1840 address_family_ipv6_labeled_unicast_cmd
,
1841 "address-family ipv6 labeled-unicast",
1842 "Enter Address Family command mode\n"
1844 "Address Family modifier\n")
1846 vty
->node
= BGP_IPV6L_NODE
;
1854 "Enable rpki and enter rpki configuration mode\n")
1856 vty
->node
= RPKI_NODE
;
1863 "bmp targets BMPTARGETS",
1864 "BGP Monitoring Protocol\n"
1865 "Create BMP target group\n"
1866 "Name of the BMP target group\n")
1868 vty
->node
= BMP_NODE
;
1875 "segment-routing srv6",
1876 "Segment-Routing configuration\n"
1877 "Segment-Routing SRv6 configuration\n")
1879 vty
->node
= BGP_SRV6_NODE
;
1887 "exit Segment-Routing SRv6 configuration\n")
1889 if (vty
->node
== BGP_SRV6_NODE
)
1890 vty
->node
= BGP_NODE
;
1898 "quit Segment-Routing SRv6 configuration\n")
1900 if (vty
->node
== BGP_SRV6_NODE
)
1901 vty
->node
= BGP_NODE
;
1905 DEFUNSH(VTYSH_BGPD
, address_family_evpn
, address_family_evpn_cmd
,
1906 "address-family <l2vpn evpn>",
1907 "Enter Address Family command mode\n"
1909 "Address Family modifier\n")
1911 vty
->node
= BGP_EVPN_NODE
;
1915 #if defined(HAVE_CUMULUS)
1916 #if CONFDATE > 20211115
1917 CPP_NOTICE("Use of `address-family evpn` is deprecated please remove don't forget frr-reload.py")
1919 DEFUNSH_HIDDEN(VTYSH_BGPD
, address_family_evpn2
, address_family_evpn2_cmd
,
1920 "address-family evpn",
1921 "Enter Address Family command mode\n"
1922 "EVPN Address family\n")
1925 "This command is deprecated please convert to `address-family l2vpn evpn`\n");
1926 vty
->node
= BGP_EVPN_NODE
;
1931 DEFUNSH(VTYSH_BGPD
, bgp_evpn_vni
, bgp_evpn_vni_cmd
, "vni " CMD_VNI_RANGE
,
1932 "VXLAN Network Identifier\n"
1935 vty
->node
= BGP_EVPN_VNI_NODE
;
1939 #if defined(ENABLE_BGP_VNC)
1940 DEFUNSH(VTYSH_BGPD
, vnc_defaults
, vnc_defaults_cmd
, "vnc defaults",
1941 "VNC/RFP related configuration\n"
1942 "Configure default NVE group\n")
1944 vty
->node
= BGP_VNC_DEFAULTS_NODE
;
1948 DEFUNSH(VTYSH_BGPD
, vnc_nve_group
, vnc_nve_group_cmd
, "vnc nve-group NAME",
1949 "VNC/RFP related configuration\n"
1950 "Configure a NVE group\n"
1953 vty
->node
= BGP_VNC_NVE_GROUP_NODE
;
1957 DEFUNSH(VTYSH_BGPD
, vnc_vrf_policy
, vnc_vrf_policy_cmd
, "vrf-policy NAME",
1958 "Configure a VRF policy group\n"
1961 vty
->node
= BGP_VRF_POLICY_NODE
;
1965 DEFUNSH(VTYSH_BGPD
, vnc_l2_group
, vnc_l2_group_cmd
, "vnc l2-group NAME",
1966 "VNC/RFP related configuration\n"
1967 "Configure a L2 group\n"
1970 vty
->node
= BGP_VNC_L2_GROUP_NODE
;
1974 DEFUNSH(VTYSH_BGPD
, exit_vnc_config
, exit_vnc_config_cmd
, "exit-vnc",
1975 "Exit from VNC configuration mode\n")
1977 if (vty
->node
== BGP_VNC_DEFAULTS_NODE
1978 || vty
->node
== BGP_VNC_NVE_GROUP_NODE
1979 || vty
->node
== BGP_VNC_L2_GROUP_NODE
)
1980 vty
->node
= BGP_NODE
;
1984 DEFUNSH(VTYSH_BGPD
, exit_vrf_policy
, exit_vrf_policy_cmd
, "exit-vrf-policy",
1985 "Exit from VRF policy configuration mode\n")
1987 if (vty
->node
== BGP_VRF_POLICY_NODE
)
1988 vty
->node
= BGP_NODE
;
1992 #endif /* HAVE_BGPD */
1994 DEFUNSH(VTYSH_KEYS
, key_chain
, key_chain_cmd
, "key chain WORD",
1995 "Authentication key management\n"
1996 "Key-chain management\n"
1999 vty
->node
= KEYCHAIN_NODE
;
2003 DEFUNSH(VTYSH_KEYS
, key
, key_cmd
, "key (0-2147483647)",
2005 "Key identifier number\n")
2007 vty
->node
= KEYCHAIN_KEY_NODE
;
2012 DEFUNSH(VTYSH_RIPD
, router_rip
, router_rip_cmd
, "router rip [vrf NAME]",
2013 ROUTER_STR
"RIP\n" VRF_CMD_HELP_STR
)
2015 vty
->node
= RIP_NODE
;
2018 #endif /* HAVE_RIPD */
2021 DEFUNSH(VTYSH_RIPNGD
, router_ripng
, router_ripng_cmd
, "router ripng [vrf NAME]",
2022 ROUTER_STR
"RIPng\n" VRF_CMD_HELP_STR
)
2024 vty
->node
= RIPNG_NODE
;
2027 #endif /* HAVE_RIPNGD */
2030 DEFUNSH(VTYSH_OSPFD
, router_ospf
, router_ospf_cmd
,
2031 "router ospf [(1-65535)] [vrf NAME]",
2032 "Enable a routing process\n"
2033 "Start OSPF configuration\n"
2037 vty
->node
= OSPF_NODE
;
2040 #endif /* HAVE_OSPFD */
2043 DEFUNSH(VTYSH_EIGRPD
, router_eigrp
, router_eigrp_cmd
, "router eigrp (1-65535) [vrf NAME]",
2044 "Enable a routing process\n"
2045 "Start EIGRP configuration\n"
2046 "AS number to use\n"
2049 vty
->node
= EIGRP_NODE
;
2052 #endif /* HAVE_EIGRPD */
2055 DEFUNSH(VTYSH_BABELD
, router_babel
, router_babel_cmd
, "router babel",
2056 "Enable a routing process\n"
2057 "Make Babel instance command\n")
2059 vty
->node
= BABEL_NODE
;
2062 #endif /* HAVE_BABELD */
2065 DEFUNSH(VTYSH_OSPF6D
, router_ospf6
, router_ospf6_cmd
, "router ospf6 [vrf NAME]",
2066 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR
)
2068 vty
->node
= OSPF6_NODE
;
2073 #if defined(HAVE_LDPD)
2074 DEFUNSH(VTYSH_LDPD
, ldp_mpls_ldp
, ldp_mpls_ldp_cmd
, "mpls ldp",
2075 "Global MPLS configuration subcommands\n"
2076 "Label Distribution Protocol\n")
2078 vty
->node
= LDP_NODE
;
2082 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv4
, ldp_address_family_ipv4_cmd
,
2083 "address-family ipv4",
2084 "Configure Address Family and its parameters\n"
2087 vty
->node
= LDP_IPV4_NODE
;
2091 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv6
, ldp_address_family_ipv6_cmd
,
2092 "address-family ipv6",
2093 "Configure Address Family and its parameters\n"
2096 vty
->node
= LDP_IPV6_NODE
;
2100 DEFUNSH(VTYSH_LDPD
, ldp_exit_address_family
, ldp_exit_address_family_cmd
,
2101 "exit-address-family", "Exit from Address Family configuration mode\n")
2103 if (vty
->node
== LDP_IPV4_NODE
|| vty
->node
== LDP_IPV6_NODE
)
2104 vty
->node
= LDP_NODE
;
2108 DEFUNSH(VTYSH_LDPD
, ldp_interface_ifname
, ldp_interface_ifname_cmd
,
2110 "Enable LDP on an interface and enter interface submode\n"
2111 "Interface's name\n")
2113 switch (vty
->node
) {
2115 vty
->node
= LDP_IPV4_IFACE_NODE
;
2118 vty
->node
= LDP_IPV6_IFACE_NODE
;
2127 DEFUNSH(VTYSH_LDPD
, ldp_l2vpn_word_type_vpls
, ldp_l2vpn_word_type_vpls_cmd
,
2128 "l2vpn WORD type vpls",
2129 "Configure l2vpn commands\n"
2132 "Virtual Private LAN Service\n")
2134 vty
->node
= LDP_L2VPN_NODE
;
2138 DEFUNSH(VTYSH_LDPD
, ldp_member_pseudowire_ifname
,
2139 ldp_member_pseudowire_ifname_cmd
, "member pseudowire IFNAME",
2140 "L2VPN member configuration\n"
2141 "Pseudowire interface\n"
2142 "Interface's name\n")
2144 vty
->node
= LDP_PSEUDOWIRE_NODE
;
2150 DEFUNSH(VTYSH_ISISD
, router_isis
, router_isis_cmd
,
2151 "router isis WORD [vrf NAME]",
2154 "ISO Routing area tag\n" VRF_CMD_HELP_STR
)
2156 vty
->node
= ISIS_NODE
;
2159 #endif /* HAVE_ISISD */
2162 DEFUNSH(VTYSH_FABRICD
, router_openfabric
, router_openfabric_cmd
, "router openfabric WORD",
2164 "OpenFabric routing protocol\n"
2165 "ISO Routing area tag\n")
2167 vty
->node
= OPENFABRIC_NODE
;
2170 #endif /* HAVE_FABRICD */
2172 #if defined(HAVE_PATHD)
2173 DEFUNSH(VTYSH_SR
, segment_routing
, segment_routing_cmd
,
2175 "Configure segment routing\n")
2177 vty
->node
= SEGMENT_ROUTING_NODE
;
2181 DEFUNSH(VTYSH_PATHD
, sr_traffic_eng
, sr_traffic_eng_cmd
,
2183 "Configure SR traffic engineering\n")
2185 vty
->node
= SR_TRAFFIC_ENG_NODE
;
2189 DEFUNSH(VTYSH_PATHD
, srte_segment_list
, srte_segment_list_cmd
,
2190 "segment-list WORD$name",
2192 "Segment List Name\n")
2194 vty
->node
= SR_SEGMENT_LIST_NODE
;
2198 DEFUNSH(VTYSH_PATHD
, srte_policy
, srte_policy_cmd
,
2199 "policy color (0-4294967295) endpoint <A.B.C.D|X:X::X:X>",
2200 "Segment Routing Policy\n"
2202 "SR Policy color value\n"
2203 "SR Policy endpoint\n"
2204 "SR Policy endpoint IPv4 address\n"
2205 "SR Policy endpoint IPv6 address\n")
2207 vty
->node
= SR_POLICY_NODE
;
2211 DEFUNSH(VTYSH_PATHD
, srte_policy_candidate_dyn_path
,
2212 srte_policy_candidate_dyn_path_cmd
,
2213 "candidate-path preference (0-4294967295) name WORD dynamic",
2214 "Segment Routing Policy Candidate Path\n"
2215 "Segment Routing Policy Candidate Path Preference\n"
2216 "Administrative Preference\n"
2217 "Segment Routing Policy Candidate Path Name\n"
2221 vty
->node
= SR_CANDIDATE_DYN_NODE
;
2225 #if defined(HAVE_PATHD_PCEP)
2227 DEFUNSH(VTYSH_PATHD
, pcep
, pcep_cmd
,
2229 "Configure SR pcep\n")
2231 vty
->node
= PCEP_NODE
;
2235 DEFUNSH(VTYSH_PATHD
, pcep_cli_pcc
, pcep_cli_pcc_cmd
,
2238 "PCC configuration\n")
2240 vty
->node
= PCEP_PCC_NODE
;
2244 DEFUNSH(VTYSH_PATHD
, pcep_cli_pce
, pcep_cli_pce_cmd
,
2247 "PCE configuration\n"
2250 vty
->node
= PCEP_PCE_NODE
;
2254 DEFUNSH(VTYSH_PATHD
, pcep_cli_pcep_pce_config
, pcep_cli_pcep_pce_config_cmd
,
2255 "[no] pce-config WORD",
2257 "PCEP peer Configuration Group\n"
2258 "PCEP peer Configuration Group name\n")
2260 vty
->node
= PCEP_PCE_CONFIG_NODE
;
2264 #endif /* HAVE_PATHD_PCEP */
2266 #endif /* HAVE_PATHD */
2268 DEFUNSH(VTYSH_RMAP
, vtysh_route_map
, vtysh_route_map_cmd
,
2269 "route-map WORD <deny|permit> (1-65535)",
2270 "Create route-map or enter route-map command mode\n"
2272 "Route map denies set operations\n"
2273 "Route map permits set operations\n"
2274 "Sequence to insert to/delete from existing route-map entry\n")
2276 vty
->node
= RMAP_NODE
;
2281 DEFUNSH(VTYSH_PBRD
, vtysh_pbr_map
, vtysh_pbr_map_cmd
,
2282 "pbr-map PBRMAP seq (1-700)",
2283 "Create pbr-map or enter pbr-map command mode\n"
2284 "The name of the PBR MAP\n"
2285 "Sequence to insert to/delete from existing pbr-map entry\n"
2286 "Sequence number\n")
2288 vty
->node
= PBRMAP_NODE
;
2292 DEFSH(VTYSH_PBRD
, vtysh_no_pbr_map_cmd
, "no pbr-map PBRMAP [seq (1-700)]",
2295 "The name of the PBR MAP\n"
2296 "Sequence to delete from existing pbr-map entry\n"
2297 "Sequence number\n")
2298 #endif /* HAVE_PBRD */
2301 DEFUNSH(VTYSH_BFDD
, bfd_enter
, bfd_enter_cmd
, "bfd", "Configure BFD peers\n")
2303 vty
->node
= BFD_NODE
;
2307 DEFUNSH(VTYSH_BFDD
, bfd_peer_enter
, bfd_peer_enter_cmd
,
2308 "peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
2310 "IPv4 peer address\n"
2311 "IPv6 peer address\n"
2312 "Configure multihop\n"
2313 "Configure local address\n"
2314 "IPv4 local address\n"
2315 "IPv6 local address\n"
2317 "Configure interface name to use\n"
2319 "Configure VRF name\n")
2321 vty
->node
= BFD_PEER_NODE
;
2325 DEFUNSH(VTYSH_BFDD
, bfd_profile_enter
, bfd_profile_enter_cmd
,
2328 BFD_PROFILE_NAME_STR
)
2330 vty
->node
= BFD_PROFILE_NODE
;
2333 #endif /* HAVE_BFDD */
2335 DEFUNSH(VTYSH_ALL
, vtysh_line_vty
, vtysh_line_vty_cmd
, "line vty",
2336 "Configure a terminal line\n"
2337 "Virtual terminal\n")
2339 vty
->node
= VTY_NODE
;
2343 DEFUNSH(VTYSH_REALLYALL
, vtysh_enable
, vtysh_enable_cmd
, "enable",
2344 "Turn on privileged mode command\n")
2346 vty
->node
= ENABLE_NODE
;
2350 DEFUNSH(VTYSH_REALLYALL
, vtysh_disable
, vtysh_disable_cmd
, "disable",
2351 "Turn off privileged mode command\n")
2353 if (vty
->node
== ENABLE_NODE
)
2354 vty
->node
= VIEW_NODE
;
2358 DEFUNSH(VTYSH_REALLYALL
, vtysh_config_terminal
, vtysh_config_terminal_cmd
,
2359 "configure [terminal]",
2360 "Configuration from vty interface\n"
2361 "Configuration terminal\n")
2363 vty
->node
= CONFIG_NODE
;
2367 static int vtysh_exit(struct vty
*vty
)
2369 struct cmd_node
*cnode
= vector_lookup(cmdvec
, vty
->node
);
2371 if (vty
->node
== VIEW_NODE
|| vty
->node
== ENABLE_NODE
)
2373 if (cnode
->node_exit
)
2374 cnode
->node_exit(vty
);
2375 if (cnode
->parent_node
)
2376 vty
->node
= cnode
->parent_node
;
2378 if (vty
->node
== CONFIG_NODE
) {
2379 /* resync in case one of the daemons is somewhere else */
2380 vtysh_execute("end");
2381 vtysh_execute("configure");
2386 DEFUNSH(VTYSH_REALLYALL
, vtysh_exit_all
, vtysh_exit_all_cmd
, "exit",
2387 "Exit current mode and down to previous mode\n")
2389 return vtysh_exit(vty
);
2392 DEFUNSH(VTYSH_REALLYALL
, vtysh_quit_all
, vtysh_quit_all_cmd
, "quit",
2393 "Exit current mode and down to previous mode\n")
2395 return vtysh_exit_all(self
, vty
, argc
, argv
);
2399 DEFUNSH(VTYSH_BGPD
, exit_address_family
, exit_address_family_cmd
,
2400 "exit-address-family", "Exit from Address Family configuration mode\n")
2402 if (vty
->node
== BGP_IPV4_NODE
|| vty
->node
== BGP_IPV4M_NODE
2403 || vty
->node
== BGP_IPV4L_NODE
|| vty
->node
== BGP_VPNV4_NODE
2404 || vty
->node
== BGP_VPNV6_NODE
|| vty
->node
== BGP_IPV6_NODE
2405 || vty
->node
== BGP_IPV6L_NODE
|| vty
->node
== BGP_IPV6M_NODE
2406 || vty
->node
== BGP_EVPN_NODE
2407 || vty
->node
== BGP_FLOWSPECV4_NODE
2408 || vty
->node
== BGP_FLOWSPECV6_NODE
)
2409 vty
->node
= BGP_NODE
;
2413 DEFUNSH(VTYSH_BGPD
, exit_vni
, exit_vni_cmd
, "exit-vni", "Exit from VNI mode\n")
2415 if (vty
->node
== BGP_EVPN_VNI_NODE
)
2416 vty
->node
= BGP_EVPN_NODE
;
2420 DEFUNSH(VTYSH_BGPD
, rpki_exit
, rpki_exit_cmd
, "exit",
2421 "Exit current mode and down to previous mode\n")
2427 DEFUNSH(VTYSH_BGPD
, rpki_quit
, rpki_quit_cmd
, "quit",
2428 "Exit current mode and down to previous mode\n")
2430 return rpki_exit(self
, vty
, argc
, argv
);
2433 DEFUNSH(VTYSH_BGPD
, bmp_exit
, bmp_exit_cmd
, "exit",
2434 "Exit current mode and down to previous mode\n")
2440 DEFUNSH(VTYSH_BGPD
, bmp_quit
, bmp_quit_cmd
, "quit",
2441 "Exit current mode and down to previous mode\n")
2443 return bmp_exit(self
, vty
, argc
, argv
);
2445 #endif /* HAVE_BGPD */
2447 DEFUNSH(VTYSH_VRF
, exit_vrf_config
, exit_vrf_config_cmd
, "exit-vrf",
2448 "Exit from VRF configuration mode\n")
2450 if (vty
->node
== VRF_NODE
)
2451 vty
->node
= CONFIG_NODE
;
2455 DEFUNSH(VTYSH_SR
, exit_srv6_config
, exit_srv6_config_cmd
, "exit",
2456 "Exit from SRv6 configuration mode\n")
2458 if (vty
->node
== SRV6_NODE
)
2459 vty
->node
= SEGMENT_ROUTING_NODE
;
2463 DEFUNSH(VTYSH_SR
, exit_srv6_locs_config
, exit_srv6_locs_config_cmd
, "exit",
2464 "Exit from SRv6-locator configuration mode\n")
2466 if (vty
->node
== SRV6_LOCS_NODE
)
2467 vty
->node
= SRV6_NODE
;
2471 DEFUNSH(VTYSH_SR
, exit_srv6_loc_config
, exit_srv6_loc_config_cmd
, "exit",
2472 "Exit from SRv6-locators configuration mode\n")
2474 if (vty
->node
== SRV6_LOC_NODE
)
2475 vty
->node
= SRV6_LOCS_NODE
;
2480 DEFUNSH(VTYSH_RIPD
, vtysh_exit_ripd
, vtysh_exit_ripd_cmd
, "exit",
2481 "Exit current mode and down to previous mode\n")
2483 return vtysh_exit(vty
);
2486 DEFUNSH(VTYSH_RIPD
, vtysh_quit_ripd
, vtysh_quit_ripd_cmd
, "quit",
2487 "Exit current mode and down to previous mode\n")
2489 return vtysh_exit_ripd(self
, vty
, argc
, argv
);
2491 #endif /* HAVE_RIPD */
2494 DEFUNSH(VTYSH_RIPNGD
, vtysh_exit_ripngd
, vtysh_exit_ripngd_cmd
, "exit",
2495 "Exit current mode and down to previous mode\n")
2497 return vtysh_exit(vty
);
2500 DEFUNSH(VTYSH_RIPNGD
, vtysh_quit_ripngd
, vtysh_quit_ripngd_cmd
, "quit",
2501 "Exit current mode and down to previous mode\n")
2503 return vtysh_exit_ripngd(self
, vty
, argc
, argv
);
2505 #endif /* HAVE_RIPNGD */
2507 DEFUNSH(VTYSH_RMAP
, vtysh_exit_rmap
, vtysh_exit_rmap_cmd
, "exit",
2508 "Exit current mode and down to previous mode\n")
2510 return vtysh_exit(vty
);
2513 DEFUNSH(VTYSH_RMAP
, vtysh_quit_rmap
, vtysh_quit_rmap_cmd
, "quit",
2514 "Exit current mode and down to previous mode\n")
2516 return vtysh_exit_rmap(self
, vty
, argc
, argv
);
2520 DEFUNSH(VTYSH_PBRD
, vtysh_exit_pbr_map
, vtysh_exit_pbr_map_cmd
, "exit",
2521 "Exit current mode and down to previous mode\n")
2523 return vtysh_exit(vty
);
2526 DEFUNSH(VTYSH_PBRD
, vtysh_quit_pbr_map
, vtysh_quit_pbr_map_cmd
, "quit",
2527 "Exit current mode and down to previous mode\n")
2529 return vtysh_exit_rmap(self
, vty
, argc
, argv
);
2531 #endif /* HAVE_PBRD */
2534 DEFUNSH(VTYSH_BGPD
, vtysh_exit_bgpd
, vtysh_exit_bgpd_cmd
, "exit",
2535 "Exit current mode and down to previous mode\n")
2537 return vtysh_exit(vty
);
2540 DEFUNSH(VTYSH_BGPD
, vtysh_quit_bgpd
, vtysh_quit_bgpd_cmd
, "quit",
2541 "Exit current mode and down to previous mode\n")
2543 return vtysh_exit_bgpd(self
, vty
, argc
, argv
);
2545 #endif /* HAVE_BGPD */
2548 DEFUNSH(VTYSH_OSPFD
, vtysh_exit_ospfd
, vtysh_exit_ospfd_cmd
, "exit",
2549 "Exit current mode and down to previous mode\n")
2551 return vtysh_exit(vty
);
2554 DEFUNSH(VTYSH_OSPFD
, vtysh_quit_ospfd
, vtysh_quit_ospfd_cmd
, "quit",
2555 "Exit current mode and down to previous mode\n")
2557 return vtysh_exit_ospfd(self
, vty
, argc
, argv
);
2559 #endif /* HAVE_OSPFD */
2562 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_eigrpd
, vtysh_exit_eigrpd_cmd
, "exit",
2563 "Exit current mode and down to previous mode\n")
2565 return vtysh_exit(vty
);
2568 DEFUNSH(VTYSH_EIGRPD
, vtysh_quit_eigrpd
, vtysh_quit_eigrpd_cmd
, "quit",
2569 "Exit current mode and down to previous mode\n")
2571 return vtysh_exit(vty
);
2573 #endif /* HAVE_EIGRPD */
2576 DEFUNSH(VTYSH_BABELD
, vtysh_exit_babeld
, vtysh_exit_babeld_cmd
, "exit",
2577 "Exit current mode and down to previous mode\n")
2579 return vtysh_exit(vty
);
2582 DEFUNSH(VTYSH_BABELD
, vtysh_quit_babeld
, vtysh_quit_babeld_cmd
, "quit",
2583 "Exit current mode and down to previous mode\n")
2585 return vtysh_exit(vty
);
2587 #endif /* HAVE_BABELD */
2590 DEFUNSH(VTYSH_OSPF6D
, vtysh_exit_ospf6d
, vtysh_exit_ospf6d_cmd
, "exit",
2591 "Exit current mode and down to previous mode\n")
2593 return vtysh_exit(vty
);
2596 DEFUNSH(VTYSH_OSPF6D
, vtysh_quit_ospf6d
, vtysh_quit_ospf6d_cmd
, "quit",
2597 "Exit current mode and down to previous mode\n")
2599 return vtysh_exit_ospf6d(self
, vty
, argc
, argv
);
2601 #endif /* HAVE_OSPF6D */
2603 #if defined(HAVE_LDPD)
2604 DEFUNSH(VTYSH_LDPD
, vtysh_exit_ldpd
, vtysh_exit_ldpd_cmd
, "exit",
2605 "Exit current mode and down to previous mode\n")
2607 return vtysh_exit(vty
);
2610 ALIAS(vtysh_exit_ldpd
, vtysh_quit_ldpd_cmd
, "quit",
2611 "Exit current mode and down to previous mode\n")
2615 DEFUNSH(VTYSH_ISISD
, vtysh_exit_isisd
, vtysh_exit_isisd_cmd
, "exit",
2616 "Exit current mode and down to previous mode\n")
2618 return vtysh_exit(vty
);
2621 DEFUNSH(VTYSH_ISISD
, vtysh_quit_isisd
, vtysh_quit_isisd_cmd
, "quit",
2622 "Exit current mode and down to previous mode\n")
2624 return vtysh_exit_isisd(self
, vty
, argc
, argv
);
2626 #endif /* HAVE_ISISD */
2629 DEFUNSH(VTYSH_BFDD
, vtysh_exit_bfdd
, vtysh_exit_bfdd_cmd
, "exit",
2630 "Exit current mode and down to previous mode\n")
2632 return vtysh_exit(vty
);
2635 ALIAS(vtysh_exit_bfdd
, vtysh_quit_bfdd_cmd
, "quit",
2636 "Exit current mode and down to previous mode\n")
2640 DEFUNSH(VTYSH_FABRICD
, vtysh_exit_fabricd
, vtysh_exit_fabricd_cmd
, "exit",
2641 "Exit current mode and down to previous mode\n")
2643 return vtysh_exit(vty
);
2646 DEFUNSH(VTYSH_FABRICD
, vtysh_quit_fabricd
, vtysh_quit_fabricd_cmd
, "quit",
2647 "Exit current mode and down to previous mode\n")
2649 return vtysh_exit_fabricd(self
, vty
, argc
, argv
);
2651 #endif /* HAVE_FABRICD */
2653 DEFUNSH(VTYSH_KEYS
, vtysh_exit_keys
, vtysh_exit_keys_cmd
, "exit",
2654 "Exit current mode and down to previous mode\n")
2656 return vtysh_exit(vty
);
2659 DEFUNSH(VTYSH_KEYS
, vtysh_quit_keys
, vtysh_quit_keys_cmd
, "quit",
2660 "Exit current mode and down to previous mode\n")
2662 return vtysh_exit_keys(self
, vty
, argc
, argv
);
2665 #if defined(HAVE_PATHD)
2666 DEFUNSH(VTYSH_PATHD
, vtysh_exit_pathd
, vtysh_exit_pathd_cmd
, "exit",
2667 "Exit current mode and down to previous mode\n")
2669 return vtysh_exit(vty
);
2672 DEFUNSH(VTYSH_PATHD
, vtysh_quit_pathd
, vtysh_quit_pathd_cmd
, "quit",
2673 "Exit current mode and down to previous mode\n")
2675 return vtysh_exit_pathd(self
, vty
, argc
, argv
);
2677 #endif /* HAVE_PATHD */
2679 DEFUNSH(VTYSH_ALL
, vtysh_exit_line_vty
, vtysh_exit_line_vty_cmd
, "exit",
2680 "Exit current mode and down to previous mode\n")
2682 return vtysh_exit(vty
);
2685 DEFUNSH(VTYSH_ALL
, vtysh_quit_line_vty
, vtysh_quit_line_vty_cmd
, "quit",
2686 "Exit current mode and down to previous mode\n")
2688 return vtysh_exit_line_vty(self
, vty
, argc
, argv
);
2691 DEFUNSH(VTYSH_INTERFACE
, vtysh_interface
, vtysh_interface_cmd
,
2692 "interface IFNAME [vrf NAME]",
2693 "Select an interface to configure\n"
2694 "Interface's name\n" VRF_CMD_HELP_STR
)
2696 vty
->node
= INTERFACE_NODE
;
2700 DEFUNSH(VTYSH_ZEBRA
, vtysh_pseudowire
, vtysh_pseudowire_cmd
,
2701 "pseudowire IFNAME",
2702 "Static pseudowire configuration\n"
2703 "Pseudowire name\n")
2705 vty
->node
= PW_NODE
;
2709 DEFUNSH(VTYSH_NH_GROUP
,
2710 vtysh_nexthop_group
, vtysh_nexthop_group_cmd
,
2711 "nexthop-group NHGNAME",
2712 "Nexthop Group configuration\n"
2713 "Name of the Nexthop Group\n")
2715 vty
->node
= NH_GROUP_NODE
;
2719 DEFSH(VTYSH_NH_GROUP
, vtysh_no_nexthop_group_cmd
,
2720 "no nexthop-group NHGNAME",
2722 "Nexthop Group Configuration\n"
2723 "Name of the Nexthop Group\n")
2725 DEFUNSH(VTYSH_VRF
, vtysh_vrf
, vtysh_vrf_cmd
, "vrf NAME",
2726 "Select a VRF to configure\n"
2729 vty
->node
= VRF_NODE
;
2733 DEFSH(VTYSH_ZEBRA
, vtysh_vrf_netns_cmd
,
2735 "Attach VRF to a Namespace\n"
2736 "The file name in " NS_RUN_DIR
", or a full pathname\n")
2738 DEFSH(VTYSH_ZEBRA
, vtysh_no_vrf_netns_cmd
,
2741 "Detach VRF from a Namespace\n"
2742 "The file name in " NS_RUN_DIR
", or a full pathname\n")
2744 DEFUNSH(VTYSH_VRF
, vtysh_exit_vrf
, vtysh_exit_vrf_cmd
, "exit",
2745 "Exit current mode and down to previous mode\n")
2747 return vtysh_exit(vty
);
2750 DEFUNSH(VTYSH_VRF
, vtysh_quit_vrf
, vtysh_quit_vrf_cmd
, "quit",
2751 "Exit current mode and down to previous mode\n")
2753 return vtysh_exit_vrf(self
, vty
, argc
, argv
);
2756 DEFUNSH(VTYSH_NH_GROUP
,
2757 vtysh_exit_nexthop_group
, vtysh_exit_nexthop_group_cmd
,
2758 "exit", "Exit current mode and down to previous mode\n")
2760 return vtysh_exit(vty
);
2763 DEFUNSH(VTYSH_NH_GROUP
,
2764 vtysh_quit_nexthop_group
, vtysh_quit_nexthop_group_cmd
,
2765 "quit", "Exit current mode and down to previous mode\n")
2767 return vtysh_exit_nexthop_group(self
, vty
, argc
, argv
);
2770 DEFUNSH(VTYSH_INTERFACE
, vtysh_exit_interface
, vtysh_exit_interface_cmd
, "exit",
2771 "Exit current mode and down to previous mode\n")
2773 return vtysh_exit(vty
);
2776 DEFUNSH(VTYSH_INTERFACE
, vtysh_quit_interface
, vtysh_quit_interface_cmd
, "quit",
2777 "Exit current mode and down to previous mode\n")
2779 return vtysh_exit_interface(self
, vty
, argc
, argv
);
2782 static char *do_prepend(struct vty
*vty
, struct cmd_token
**argv
, int argc
)
2784 const char *argstr
[argc
+ 1];
2787 if (vty
->node
!= VIEW_NODE
) {
2792 for (i
= 0; i
< argc
; i
++)
2793 argstr
[i
+ off
] = argv
[i
]->arg
;
2795 return frrstr_join(argstr
, argc
+ off
, " ");
2798 static int show_per_daemon(struct vty
*vty
, struct cmd_token
**argv
, int argc
,
2799 const char *headline
)
2802 int ret
= CMD_SUCCESS
;
2803 char *line
= do_prepend(vty
, argv
, argc
);
2805 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2806 if (vtysh_client
[i
].fd
>= 0 || vtysh_client
[i
].next
) {
2807 vty_out(vty
, headline
, vtysh_client
[i
].name
);
2808 ret
= vtysh_client_execute(&vtysh_client
[i
], line
);
2812 XFREE(MTYPE_TMP
, line
);
2817 static int show_one_daemon(struct vty
*vty
, struct cmd_token
**argv
, int argc
,
2821 char *line
= do_prepend(vty
, argv
, argc
);
2823 ret
= vtysh_client_execute_name(name
, line
);
2825 XFREE(MTYPE_TMP
, line
);
2830 DEFUN (vtysh_show_poll
,
2831 vtysh_show_poll_cmd
,
2834 "Thread information\n"
2835 "Thread Poll Information\n")
2837 return show_per_daemon(vty
, argv
, argc
, "Thread statistics for %s:\n");
2840 #ifndef EXCLUDE_CPU_TIME
2841 DEFUN (vtysh_show_thread
,
2842 vtysh_show_thread_cmd
,
2843 "show thread cpu [FILTER]",
2845 "Thread information\n"
2846 "Thread CPU usage\n"
2847 "Display filter (rwtexb)\n")
2849 return show_per_daemon(vty
, argv
, argc
, "Thread statistics for %s:\n");
2853 DEFUN (vtysh_show_work_queues
,
2854 vtysh_show_work_queues_cmd
,
2857 "Work Queue information\n")
2859 return show_per_daemon(vty
, argv
, argc
,
2860 "Work queue statistics for %s:\n");
2863 DEFUN (vtysh_show_work_queues_daemon
,
2864 vtysh_show_work_queues_daemon_cmd
,
2865 "show work-queues " DAEMONS_LIST
,
2867 "Work Queue information\n"
2870 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
2873 DEFUNSH(VTYSH_ZEBRA
, vtysh_link_params
, vtysh_link_params_cmd
, "link-params",
2876 vty
->node
= LINK_PARAMS_NODE
;
2880 DEFUNSH(VTYSH_ZEBRA
, exit_link_params
, exit_link_params_cmd
, "exit-link-params",
2881 "Exit from Link Params configuration node\n")
2883 if (vty
->node
== LINK_PARAMS_NODE
)
2884 vty
->node
= INTERFACE_NODE
;
2888 DEFUNSH_HIDDEN (0x00,
2890 vtysh_debug_all_cmd
,
2894 "Toggle all debugs on or off\n")
2899 DEFUN (vtysh_show_debugging
,
2900 vtysh_show_debugging_cmd
,
2905 return show_per_daemon(vty
, argv
, argc
, "");
2908 DEFUN (vtysh_show_debugging_hashtable
,
2909 vtysh_show_debugging_hashtable_cmd
,
2910 "show debugging hashtable [statistics]",
2913 "Statistics about hash tables\n"
2914 "Statistics about hash tables\n")
2916 bool stats
= strmatch(argv
[argc
- 1]->text
, "statistics");
2920 "Load factor (LF) - average number of elements across all buckets\n");
2922 "Full load factor (FLF) - average number of elements across full buckets\n\n");
2924 "Standard deviation (SD) is calculated for both the LF and FLF\n");
2926 "and indicates the typical deviation of bucket chain length\n");
2927 vty_out(vty
, "from the value in the corresponding load factor.\n\n");
2929 return show_per_daemon(vty
, argv
, stats
? argc
- 1 : argc
,
2930 "Hashtable statistics for %s:\n");
2933 DEFUN (vtysh_show_error_code
,
2934 vtysh_show_error_code_cmd
,
2935 "show error <(1-4294967296)|all> [json]",
2937 "Information on errors\n"
2938 "Error code to get info about\n"
2939 "Information on all errors\n"
2944 if (!strmatch(argv
[2]->text
, "all"))
2945 arg
= strtoul(argv
[2]->arg
, NULL
, 10);
2947 /* If it's not a shared code, send it to all the daemons */
2948 if (arg
< LIB_FERR_START
|| arg
> LIB_FERR_END
) {
2949 show_per_daemon(vty
, argv
, argc
, "");
2950 /* Otherwise, print it ourselves to avoid duplication */
2952 bool json
= strmatch(argv
[argc
- 1]->text
, "json");
2954 if (!strmatch(argv
[2]->text
, "all"))
2955 arg
= strtoul(argv
[2]->arg
, NULL
, 10);
2957 log_ref_display(vty
, arg
, json
);
2964 DEFUN_HIDDEN (show_config_running
,
2965 show_config_running_cmd
,
2966 "show configuration running\
2967 [<json|xml> [translate WORD]]\
2968 [with-defaults]" DAEMONS_LIST
,
2970 "Configuration information\n"
2971 "Running configuration\n"
2972 "Change output format to JSON\n"
2973 "Change output format to XML\n"
2974 "Translate output\n"
2975 "YANG module translator\n"
2976 "Show default values\n"
2979 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
2982 DEFUN (show_yang_operational_data
,
2983 show_yang_operational_data_cmd
,
2984 "show yang operational-data XPATH\
2990 "YANG information\n"
2991 "Show YANG operational data\n"
2992 "XPath expression specifying the YANG data path\n"
2993 "Set the output format\n"
2994 "JavaScript Object Notation\n"
2995 "Extensible Markup Language\n"
2996 "Translate operational data\n"
2997 "YANG module translator\n"
3000 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
3003 DEFUN(show_yang_module
, show_yang_module_cmd
,
3004 "show yang module [module-translator WORD] " DAEMONS_LIST
,
3006 "YANG information\n"
3007 "Show loaded modules\n"
3008 "YANG module translator\n"
3009 "YANG module translator\n" DAEMONS_STR
)
3011 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
3014 DEFUN(show_yang_module_detail
, show_yang_module_detail_cmd
,
3016 [module-translator WORD]\
3017 WORD <compiled|summary|tree|yang|yin> " DAEMONS_LIST
,
3019 "YANG information\n"
3020 "Show loaded modules\n"
3021 "YANG module translator\n"
3022 "YANG module translator\n"
3024 "Display compiled module in YANG format\n"
3025 "Display summary information about the module\n"
3026 "Display module in the tree (RFC 8340) format\n"
3027 "Display module in the YANG format\n"
3028 "Display module in the YIN format\n" DAEMONS_STR
)
3030 return show_one_daemon(vty
, argv
, argc
- 1, argv
[argc
- 1]->text
);
3034 DEFUNSH(VTYSH_ALL
, debug_nb
,
3036 "[no] debug northbound\
3038 callbacks [{configuration|state|rpc}]\
3045 "Northbound debugging\n"
3052 "libyang debugging\n")
3057 DEFUN (vtysh_show_history
,
3058 vtysh_show_history_cmd
,
3061 "The list of commands stored in history\n")
3063 HIST_ENTRY
**hlist
= history_list();
3067 vty_out(vty
, "%s\n", hlist
[i
]->line
);
3074 DEFUN (vtysh_show_memory
,
3075 vtysh_show_memory_cmd
,
3076 "show memory [" DAEMONS_LIST
"]",
3078 "Memory statistics\n"
3082 return show_one_daemon(vty
, argv
, argc
- 1,
3083 argv
[argc
- 1]->text
);
3085 return show_per_daemon(vty
, argv
, argc
, "Memory statistics for %s:\n");
3088 DEFUN (vtysh_show_modules
,
3089 vtysh_show_modules_cmd
,
3094 return show_per_daemon(vty
, argv
, argc
, "Module information for %s:\n");
3097 /* Logging commands. */
3098 DEFUN (vtysh_show_logging
,
3099 vtysh_show_logging_cmd
,
3102 "Show current logging configuration\n")
3104 return show_per_daemon(vty
, argv
, argc
,
3105 "Logging configuration for %s:\n");
3108 DEFUNSH(VTYSH_ALL
, vtysh_debug_memstats
,
3109 vtysh_debug_memstats_cmd
, "[no] debug memstats-at-exit",
3112 "Print memory statistics at exit\n")
3117 DEFUNSH(VTYSH_ALL
, vtysh_service_password_encrypt
,
3118 vtysh_service_password_encrypt_cmd
, "service password-encryption",
3119 "Set up miscellaneous service\n"
3120 "Enable encrypted passwords\n")
3125 DEFUNSH(VTYSH_ALL
, no_vtysh_service_password_encrypt
,
3126 no_vtysh_service_password_encrypt_cmd
, "no service password-encryption",
3128 "Set up miscellaneous service\n"
3129 "Enable encrypted passwords\n")
3134 DEFUNSH(VTYSH_ALL
, vtysh_config_password
, vtysh_password_cmd
,
3135 "password [(8-8)] LINE",
3136 "Modify the terminal connection password\n"
3137 "Specifies a HIDDEN password will follow\n"
3138 "The password string\n")
3143 DEFUNSH(VTYSH_ALL
, no_vtysh_config_password
, no_vtysh_password_cmd
,
3144 "no password", NO_STR
3145 "Modify the terminal connection password\n")
3147 vty_out(vty
, NO_PASSWD_CMD_WARNING
);
3152 DEFUNSH(VTYSH_ALL
, vtysh_config_enable_password
, vtysh_enable_password_cmd
,
3153 "enable password [(8-8)] LINE",
3154 "Modify enable password parameters\n"
3155 "Assign the privileged level password\n"
3156 "Specifies a HIDDEN password will follow\n"
3157 "The 'enable' password string\n")
3162 DEFUNSH(VTYSH_ALL
, no_vtysh_config_enable_password
,
3163 no_vtysh_enable_password_cmd
, "no enable password", NO_STR
3164 "Modify enable password parameters\n"
3165 "Assign the privileged level password\n")
3167 vty_out(vty
, NO_PASSWD_CMD_WARNING
);
3172 DEFUN (vtysh_write_terminal
,
3173 vtysh_write_terminal_cmd
,
3174 "write terminal ["DAEMONS_LIST
"] [no-header]",
3175 "Write running configuration to memory, network, or terminal\n"
3176 "Write to terminal\n"
3178 "Skip \"Building configuration...\" header\n")
3181 char line
[] = "do write terminal\n";
3183 if (!strcmp(argv
[argc
- 1]->arg
, "no-header"))
3186 vty_out(vty
, "Building configuration...\n");
3187 vty_out(vty
, "\nCurrent configuration:\n");
3188 vty_out(vty
, "!\n");
3191 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3193 || (strmatch(vtysh_client
[i
].name
, argv
[2]->text
)))
3194 vtysh_client_config(&vtysh_client
[i
], line
);
3196 /* Integrate vtysh specific configuration. */
3197 vty_open_pager(vty
);
3198 vtysh_config_write();
3199 vtysh_config_dump();
3200 vty_close_pager(vty
);
3201 vty_out(vty
, "end\n");
3206 DEFUN (vtysh_show_running_config
,
3207 vtysh_show_running_config_cmd
,
3208 "show running-config ["DAEMONS_LIST
"] [no-header]",
3210 "Current operating configuration\n"
3212 "Skip \"Building configuration...\" header\n")
3214 return vtysh_write_terminal(self
, vty
, argc
, argv
);
3217 DEFUN (vtysh_integrated_config
,
3218 vtysh_integrated_config_cmd
,
3219 "service integrated-vtysh-config",
3220 "Set up miscellaneous service\n"
3221 "Write configuration into integrated file\n")
3223 vtysh_write_integrated
= WRITE_INTEGRATED_YES
;
3227 DEFUN (no_vtysh_integrated_config
,
3228 no_vtysh_integrated_config_cmd
,
3229 "no service integrated-vtysh-config",
3231 "Set up miscellaneous service\n"
3232 "Write configuration into integrated file\n")
3234 vtysh_write_integrated
= WRITE_INTEGRATED_NO
;
3238 static void backup_config_file(const char *fbackup
)
3240 char *integrate_sav
= NULL
;
3242 size_t integrate_sav_sz
= strlen(fbackup
) + strlen(CONF_BACKUP_EXT
) + 1;
3243 integrate_sav
= malloc(integrate_sav_sz
);
3244 strlcpy(integrate_sav
, fbackup
, integrate_sav_sz
);
3245 strlcat(integrate_sav
, CONF_BACKUP_EXT
, integrate_sav_sz
);
3247 /* Move current configuration file to backup config file. */
3248 if (unlink(integrate_sav
) != 0 && errno
!= ENOENT
)
3249 vty_out(vty
, "Unlink failed for %s: %s\n", integrate_sav
,
3251 if (rename(fbackup
, integrate_sav
) != 0 && errno
!= ENOENT
)
3252 vty_out(vty
, "Error renaming %s to %s: %s\n", fbackup
,
3253 integrate_sav
, strerror(errno
));
3254 free(integrate_sav
);
3257 int vtysh_write_config_integrated(void)
3260 char line
[] = "do write terminal\n";
3264 struct passwd
*pwentry
;
3267 struct group
*grentry
;
3274 vty_out(vty
, "Building Configuration...\n");
3276 backup_config_file(frr_config
);
3277 fp
= fopen(frr_config
, "w");
3280 "%% Error: failed to open configuration file %s: %s\n",
3281 frr_config
, safe_strerror(errno
));
3282 return CMD_WARNING_CONFIG_FAILED
;
3286 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3287 vtysh_client_config(&vtysh_client
[i
], line
);
3289 vtysh_config_write();
3290 vty
->of_saved
= vty
->of
;
3292 vtysh_config_dump();
3293 vty
->of
= vty
->of_saved
;
3295 if (fchmod(fd
, CONFIGFILE_MASK
) != 0) {
3296 printf("%% Warning: can't chmod configuration file %s: %s\n",
3297 frr_config
, safe_strerror(errno
));
3302 pwentry
= getpwnam(FRR_USER
);
3304 uid
= pwentry
->pw_uid
;
3306 printf("%% Warning: could not look up user \"%s\"\n", FRR_USER
);
3311 grentry
= getgrnam(FRR_GROUP
);
3313 gid
= grentry
->gr_gid
;
3315 printf("%% Warning: could not look up group \"%s\"\n",
3321 if (!fstat(fd
, &st
)) {
3322 if (st
.st_uid
== uid
)
3324 if (st
.st_gid
== gid
)
3326 if ((uid
!= (uid_t
)-1 || gid
!= (gid_t
)-1)
3327 && fchown(fd
, uid
, gid
)) {
3328 printf("%% Warning: can't chown configuration file %s: %s\n",
3329 frr_config
, safe_strerror(errno
));
3333 printf("%% Warning: stat() failed on %s: %s\n", frr_config
,
3334 safe_strerror(errno
));
3340 printf("Integrated configuration saved to %s\n", frr_config
);
3348 static bool want_config_integrated(void)
3352 switch (vtysh_write_integrated
) {
3353 case WRITE_INTEGRATED_UNSPECIFIED
:
3354 if (stat(frr_config
, &s
) && errno
== ENOENT
)
3357 case WRITE_INTEGRATED_NO
:
3359 case WRITE_INTEGRATED_YES
:
3365 DEFUN (vtysh_write_memory
,
3366 vtysh_write_memory_cmd
,
3367 "write [<memory|file>]",
3368 "Write running configuration to memory, network, or terminal\n"
3369 "Write configuration to the file (same as write file)\n"
3370 "Write configuration to the file (same as write memory)\n")
3372 int ret
= CMD_SUCCESS
;
3373 char line
[] = "do write memory\n";
3376 vty_out(vty
, "Note: this version of vtysh never writes vtysh.conf\n");
3378 /* If integrated frr.conf explicitely set. */
3379 if (want_config_integrated()) {
3380 ret
= CMD_WARNING_CONFIG_FAILED
;
3382 /* first attempt to use watchfrr if it's available */
3383 bool used_watchfrr
= false;
3385 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3386 if (vtysh_client
[i
].flag
== VTYSH_WATCHFRR
)
3388 if (i
< array_size(vtysh_client
) && vtysh_client
[i
].fd
!= -1) {
3389 used_watchfrr
= true;
3390 ret
= vtysh_client_execute(&vtysh_client
[i
],
3391 "do write integrated");
3395 * If we didn't use watchfrr, fallback to writing the config
3398 if (!used_watchfrr
) {
3399 printf("\nWarning: attempting direct configuration write without watchfrr.\nFile permissions and ownership may be incorrect, or write may fail.\n\n");
3400 ret
= vtysh_write_config_integrated();
3405 vty_out(vty
, "Building Configuration...\n");
3407 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3408 ret
= vtysh_client_execute(&vtysh_client
[i
], line
);
3413 DEFUN (vtysh_copy_running_config
,
3414 vtysh_copy_running_config_cmd
,
3415 "copy running-config startup-config",
3416 "Copy from one file to another\n"
3417 "Copy from current system configuration\n"
3418 "Copy to startup configuration\n")
3420 return vtysh_write_memory(self
, vty
, argc
, argv
);
3423 DEFUN (vtysh_copy_to_running
,
3424 vtysh_copy_to_running_cmd
,
3425 "copy FILENAME running-config",
3426 "Apply a configuration file\n"
3427 "Configuration file to read\n"
3428 "Apply to current configuration\n")
3431 const char *fname
= argv
[1]->arg
;
3433 ret
= vtysh_read_config(fname
, true);
3435 /* Return to enable mode - the 'read_config' api leaves us up a level */
3436 vtysh_execute_no_pager("enable");
3441 DEFUN (vtysh_terminal_paginate
,
3442 vtysh_terminal_paginate_cmd
,
3443 "[no] terminal paginate",
3445 "Set terminal line parameters\n"
3446 "Use pager for output scrolling\n")
3448 free(vtysh_pager_name
);
3449 vtysh_pager_name
= NULL
;
3451 if (strcmp(argv
[0]->text
, "no"))
3452 vtysh_pager_envdef(true);
3456 DEFUN (vtysh_terminal_length
,
3457 vtysh_terminal_length_cmd
,
3458 "[no] terminal length (0-4294967295)",
3460 "Set terminal line parameters\n"
3461 "Set number of lines on a screen\n"
3462 "Number of lines on screen (0 for no pausing, nonzero to use pager)\n")
3465 unsigned long lines
;
3467 free(vtysh_pager_name
);
3468 vtysh_pager_name
= NULL
;
3470 if (!strcmp(argv
[0]->text
, "no") || !strcmp(argv
[1]->text
, "no")) {
3471 /* "terminal no length" = use VTYSH_PAGER */
3472 vtysh_pager_envdef(true);
3476 lines
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
3479 "%% The \"terminal length\" command is deprecated and its value is ignored.\n"
3480 "%% Please use \"terminal paginate\" instead with OS TTY length handling.\n");
3481 vtysh_pager_envdef(true);
3487 ALIAS_DEPRECATED(vtysh_terminal_length
,
3488 vtysh_terminal_no_length_cmd
,
3489 "terminal no length",
3490 "Set terminal line parameters\n"
3492 "Set number of lines on a screen\n")
3494 DEFUN (vtysh_show_daemons
,
3495 vtysh_show_daemons_cmd
,
3498 "Show list of running daemons\n")
3502 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3503 if (vtysh_client
[i
].fd
>= 0)
3504 vty_out(vty
, " %s", vtysh_client
[i
].name
);
3510 /* Execute command in child process. */
3511 static void execute_command(const char *command
, int argc
, const char *arg1
,
3521 /* Failure of fork(). */
3522 fprintf(stderr
, "Can't fork: %s\n", safe_strerror(errno
));
3524 } else if (pid
== 0) {
3525 /* This is child process. */
3528 execlp(command
, command
, (const char *)NULL
);
3531 execlp(command
, command
, arg1
, (const char *)NULL
);
3534 execlp(command
, command
, arg1
, arg2
,
3535 (const char *)NULL
);
3539 /* When execlp suceed, this part is not executed. */
3540 fprintf(stderr
, "Can't execute %s: %s\n", command
,
3541 safe_strerror(errno
));
3544 /* This is parent. */
3546 wait4(pid
, &status
, 0, NULL
);
3554 "Send echo messages\n"
3555 "Ping destination address or hostname\n")
3559 argv_find(argv
, argc
, "WORD", &idx
);
3560 execute_command("ping", 1, argv
[idx
]->arg
, NULL
);
3564 ALIAS(vtysh_ping
, vtysh_ping_ip_cmd
, "ping ip WORD",
3565 "Send echo messages\n"
3567 "Ping destination address or hostname\n")
3569 DEFUN (vtysh_traceroute
,
3570 vtysh_traceroute_cmd
,
3572 "Trace route to destination\n"
3573 "Trace route to destination address or hostname\n")
3577 argv_find(argv
, argc
, "WORD", &idx
);
3578 execute_command("traceroute", 1, argv
[idx
]->arg
, NULL
);
3582 ALIAS(vtysh_traceroute
, vtysh_traceroute_ip_cmd
, "traceroute ip WORD",
3583 "Trace route to destination\n"
3585 "Trace route to destination address or hostname\n")
3587 DEFUN (vtysh_mtrace
,
3589 "mtrace WORD [WORD]",
3590 "Multicast trace route to multicast source\n"
3591 "Multicast trace route to multicast source address\n"
3592 "Multicast trace route for multicast group address\n")
3595 execute_command("mtracebis", 1, argv
[1]->arg
, NULL
);
3597 execute_command("mtracebis", 2, argv
[1]->arg
, argv
[2]->arg
);
3604 "Send echo messages\n"
3606 "Ping destination address or hostname\n")
3608 execute_command("ping6", 1, argv
[2]->arg
, NULL
);
3612 DEFUN (vtysh_traceroute6
,
3613 vtysh_traceroute6_cmd
,
3614 "traceroute ipv6 WORD",
3615 "Trace route to destination\n"
3617 "Trace route to destination address or hostname\n")
3619 execute_command("traceroute6", 1, argv
[2]->arg
, NULL
);
3623 #if defined(HAVE_SHELL_ACCESS)
3624 DEFUN (vtysh_telnet
,
3627 "Open a telnet connection\n"
3628 "IP address or hostname of a remote system\n")
3630 execute_command("telnet", 1, argv
[1]->arg
, NULL
);
3634 DEFUN (vtysh_telnet_port
,
3635 vtysh_telnet_port_cmd
,
3637 "Open a telnet connection\n"
3638 "IP address or hostname of a remote system\n"
3639 "TCP Port number\n")
3641 execute_command("telnet", 2, argv
[1]->arg
, argv
[2]->arg
);
3648 "Open an ssh connection\n"
3651 execute_command("ssh", 1, argv
[1]->arg
, NULL
);
3655 DEFUN (vtysh_start_shell
,
3656 vtysh_start_shell_cmd
,
3658 "Start UNIX shell\n")
3660 execute_command("sh", 0, NULL
, NULL
);
3664 DEFUN (vtysh_start_bash
,
3665 vtysh_start_bash_cmd
,
3667 "Start UNIX shell\n"
3670 execute_command("bash", 0, NULL
, NULL
);
3674 DEFUN (vtysh_start_zsh
,
3675 vtysh_start_zsh_cmd
,
3677 "Start UNIX shell\n"
3680 execute_command("zsh", 0, NULL
, NULL
);
3687 "list [permutations]",
3688 "Print command list\n"
3689 "Print all possible command permutations\n")
3691 return cmd_list_cmds(vty
, argc
== 2);
3694 DEFUN (vtysh_output_file
,
3695 vtysh_output_file_cmd
,
3697 "Direct vtysh output to file\n"
3698 "Direct vtysh output to file\n"
3699 "Path to dump output to\n")
3701 const char *path
= argv
[argc
- 1]->arg
;
3702 vty
->of
= fopen(path
, "a");
3704 vty_out(vty
, "Failed to open file '%s': %s\n", path
,
3705 safe_strerror(errno
));
3711 DEFUN (no_vtysh_output_file
,
3712 no_vtysh_output_file_cmd
,
3713 "no output file [FILE]",
3715 "Direct vtysh output to file\n"
3716 "Direct vtysh output to file\n"
3717 "Path to dump output to\n")
3719 if (vty
->of
!= stdout
) {
3729 "Find CLI command matching a regular expression\n"
3730 "Search pattern (POSIX regex)\n")
3732 const struct cmd_node
*node
;
3733 const struct cmd_element
*cli
;
3736 char *pattern
= argv_concat(argv
, argc
, 1);
3737 int cr
= regcomp(&exp
, pattern
, REG_NOSUB
| REG_EXTENDED
);
3739 XFREE(MTYPE_TMP
, pattern
);
3744 vty_out(vty
, "%% Invalid \\{...\\} expression\n");
3747 vty_out(vty
, "%% Bad repetition operator\n");
3750 vty_out(vty
, "%% Regex syntax error\n");
3753 vty_out(vty
, "%% Invalid collating element\n");
3756 vty_out(vty
, "%% Invalid character class name\n");
3760 "%% Regex ended with escape character (\\)\n");
3764 "%% Invalid number in \\digit construction\n");
3767 vty_out(vty
, "%% Unbalanced square brackets\n");
3770 vty_out(vty
, "%% Unbalanced parentheses\n");
3773 vty_out(vty
, "%% Unbalanced braces\n");
3777 "%% Invalid endpoint in range expression\n");
3780 vty_out(vty
, "%% Failed to compile (out of memory)\n");
3788 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
3789 node
= vector_slot(cmdvec
, i
);
3792 clis
= node
->cmd_vector
;
3793 for (unsigned int j
= 0; j
< vector_active(clis
); j
++) {
3794 cli
= vector_slot(clis
, j
);
3796 if (regexec(&exp
, cli
->string
, 0, NULL
, 0) == 0)
3797 vty_out(vty
, " (%s) %s\n",
3798 node
->name
, cli
->string
);
3807 DEFUN_HIDDEN(show_cli_graph_vtysh
,
3808 show_cli_graph_vtysh_cmd
,
3812 "Dump current command space as DOT graph\n")
3814 struct cmd_node
*cn
= vector_slot(cmdvec
, vty
->node
);
3815 char *dot
= cmd_graph_dump_dot(cn
->cmdgraph
);
3817 vty_out(vty
, "%s\n", dot
);
3818 XFREE(MTYPE_TMP
, dot
);
3822 static void vtysh_install_default(enum node_type node
)
3824 _install_element(node
, &config_list_cmd
);
3825 _install_element(node
, &find_cmd
);
3826 _install_element(node
, &show_cli_graph_vtysh_cmd
);
3827 _install_element(node
, &vtysh_output_file_cmd
);
3828 _install_element(node
, &no_vtysh_output_file_cmd
);
3831 /* Making connection to protocol daemon. */
3832 static int vtysh_connect(struct vtysh_client
*vclient
)
3836 struct sockaddr_un addr
;
3840 if (!vclient
->path
[0])
3841 snprintf(vclient
->path
, sizeof(vclient
->path
), "%s/%s.vty",
3842 vtydir
, vclient
->name
);
3843 path
= vclient
->path
;
3845 /* Stat socket to see if we have permission to access it. */
3846 ret
= stat(path
, &s_stat
);
3847 if (ret
< 0 && errno
!= ENOENT
) {
3848 fprintf(stderr
, "vtysh_connect(%s): stat = %s\n", path
,
3849 safe_strerror(errno
));
3854 if (!S_ISSOCK(s_stat
.st_mode
)) {
3855 fprintf(stderr
, "vtysh_connect(%s): Not a socket\n",
3861 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
3864 fprintf(stderr
, "vtysh_connect(%s): socket = %s\n", path
,
3865 safe_strerror(errno
));
3870 memset(&addr
, 0, sizeof(struct sockaddr_un
));
3871 addr
.sun_family
= AF_UNIX
;
3872 strlcpy(addr
.sun_path
, path
, sizeof(addr
.sun_path
));
3873 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
3874 len
= addr
.sun_len
= SUN_LEN(&addr
);
3876 len
= sizeof(addr
.sun_family
) + strlen(addr
.sun_path
);
3877 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
3879 ret
= connect(sock
, (struct sockaddr
*)&addr
, len
);
3882 fprintf(stderr
, "vtysh_connect(%s): connect = %s\n", path
,
3883 safe_strerror(errno
));
3893 static int vtysh_reconnect(struct vtysh_client
*vclient
)
3897 fprintf(stderr
, "Warning: connecting to %s...", vclient
->name
);
3898 ret
= vtysh_connect(vclient
);
3900 fprintf(stderr
, "failed!\n");
3903 fprintf(stderr
, "success!\n");
3904 if (vtysh_client_execute(vclient
, "enable") < 0)
3906 return vtysh_execute_no_pager("end");
3909 /* Return true if str ends with suffix, else return false */
3910 static int ends_with(const char *str
, const char *suffix
)
3912 if (!str
|| !suffix
)
3914 size_t lenstr
= strlen(str
);
3915 size_t lensuffix
= strlen(suffix
);
3916 if (lensuffix
> lenstr
)
3918 return strncmp(str
+ lenstr
- lensuffix
, suffix
, lensuffix
) == 0;
3921 static void vtysh_client_sorted_insert(struct vtysh_client
*head_client
,
3922 struct vtysh_client
*client
)
3924 struct vtysh_client
*prev_node
, *current_node
;
3926 prev_node
= head_client
;
3927 current_node
= head_client
->next
;
3928 while (current_node
) {
3929 if (strcmp(current_node
->path
, client
->path
) > 0)
3932 prev_node
= current_node
;
3933 current_node
= current_node
->next
;
3935 client
->next
= current_node
;
3936 prev_node
->next
= client
;
3939 #define MAXIMUM_INSTANCES 10
3941 static void vtysh_update_all_instances(struct vtysh_client
*head_client
)
3943 struct vtysh_client
*client
;
3945 struct dirent
*file
;
3948 if (head_client
->flag
!= VTYSH_OSPFD
)
3951 /* ls vty_sock_dir and look for all files ending in .vty */
3952 dir
= opendir(vtydir
);
3954 while ((file
= readdir(dir
)) != NULL
) {
3955 if (frrstr_startswith(file
->d_name
, "ospfd-")
3956 && ends_with(file
->d_name
, ".vty")) {
3957 if (n
== MAXIMUM_INSTANCES
) {
3959 "Parsing %s, client limit(%d) reached!\n",
3963 client
= (struct vtysh_client
*)malloc(
3964 sizeof(struct vtysh_client
));
3966 client
->name
= "ospfd";
3967 client
->flag
= VTYSH_OSPFD
;
3968 snprintf(client
->path
, sizeof(client
->path
),
3969 "%s/%s", vtydir
, file
->d_name
);
3970 client
->next
= NULL
;
3971 vtysh_client_sorted_insert(head_client
, client
);
3979 static int vtysh_connect_all_instances(struct vtysh_client
*head_client
)
3981 struct vtysh_client
*client
;
3984 vtysh_update_all_instances(head_client
);
3986 client
= head_client
->next
;
3988 if (vtysh_connect(client
) == 0)
3990 client
= client
->next
;
3996 int vtysh_connect_all(const char *daemon_name
)
4002 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
4004 || !strcmp(daemon_name
, vtysh_client
[i
].name
)) {
4006 if (vtysh_connect(&vtysh_client
[i
]) == 0)
4009 rc
+= vtysh_connect_all_instances(&vtysh_client
[i
]);
4013 fprintf(stderr
, "Error: no daemons match name %s!\n",
4018 /* To disable readline's filename completion. */
4019 static char *vtysh_completion_entry_function(const char *ignore
,
4025 void vtysh_readline_init(void)
4027 /* readline related settings. */
4028 char *disable_bracketed_paste
=
4029 XSTRDUP(MTYPE_TMP
, "set enable-bracketed-paste off");
4032 rl_parse_and_bind(disable_bracketed_paste
);
4033 rl_bind_key('?', (rl_command_func_t
*)vtysh_rl_describe
);
4034 rl_completion_entry_function
= vtysh_completion_entry_function
;
4035 rl_attempted_completion_function
= new_completion
;
4037 XFREE(MTYPE_TMP
, disable_bracketed_paste
);
4040 char *vtysh_prompt(void)
4042 static char buf
[512];
4044 snprintf(buf
, sizeof(buf
), cmd_prompt(vty
->node
), cmd_hostname_get());
4048 static void vtysh_ac_line(void *arg
, const char *line
)
4052 for (i
= 0; i
< vector_active(comps
); i
++)
4053 if (!strcmp(line
, (char *)vector_slot(comps
, i
)))
4055 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, line
));
4058 static void vtysh_autocomplete(vector comps
, struct cmd_token
*token
)
4063 snprintf(accmd
, sizeof(accmd
), "autocomplete %d %s %s", token
->type
,
4064 token
->text
, token
->varname
? token
->varname
: "-");
4066 vty
->of_saved
= vty
->of
;
4068 for (i
= 0; i
< array_size(vtysh_client
); i
++)
4069 vtysh_client_run_all(&vtysh_client
[i
], accmd
, 1, vtysh_ac_line
,
4071 vty
->of
= vty
->of_saved
;
4074 static const struct cmd_variable_handler vtysh_var_handler
[] = {
4078 .completions
= vtysh_autocomplete
},
4079 {.completions
= NULL
}};
4081 void vtysh_uninit(void)
4083 if (vty
->of
!= stdout
)
4087 void vtysh_init_vty(void)
4089 /* Make vty structure. */
4091 vty
->type
= VTY_SHELL
;
4092 vty
->node
= VIEW_NODE
;
4094 /* set default output */
4096 vtysh_pager_envdef(false);
4098 /* Initialize commands. */
4100 cmd_variable_handler_register(vtysh_var_handler
);
4104 install_node(&bgp_node
);
4105 install_element(CONFIG_NODE
, &router_bgp_cmd
);
4106 install_element(BGP_NODE
, &vtysh_exit_bgpd_cmd
);
4107 install_element(BGP_NODE
, &vtysh_quit_bgpd_cmd
);
4108 install_element(BGP_NODE
, &vtysh_end_all_cmd
);
4110 install_node(&bgp_vpnv4_node
);
4111 install_element(BGP_NODE
, &address_family_ipv4_vpn_cmd
);
4112 #ifdef KEEP_OLD_VPN_COMMANDS
4113 install_element(BGP_NODE
, &address_family_vpnv4_cmd
);
4114 #endif /* KEEP_OLD_VPN_COMMANDS */
4115 install_element(BGP_VPNV4_NODE
, &vtysh_exit_bgpd_cmd
);
4116 install_element(BGP_VPNV4_NODE
, &vtysh_quit_bgpd_cmd
);
4117 install_element(BGP_VPNV4_NODE
, &vtysh_end_all_cmd
);
4118 install_element(BGP_VPNV4_NODE
, &exit_address_family_cmd
);
4120 install_node(&bgp_vpnv6_node
);
4121 install_element(BGP_NODE
, &address_family_ipv6_vpn_cmd
);
4122 #ifdef KEEP_OLD_VPN_COMMANDS
4123 install_element(BGP_NODE
, &address_family_vpnv6_cmd
);
4124 #endif /* KEEP_OLD_VPN_COMMANDS */
4125 install_element(BGP_VPNV6_NODE
, &vtysh_exit_bgpd_cmd
);
4126 install_element(BGP_VPNV6_NODE
, &vtysh_quit_bgpd_cmd
);
4127 install_element(BGP_VPNV6_NODE
, &vtysh_end_all_cmd
);
4128 install_element(BGP_VPNV6_NODE
, &exit_address_family_cmd
);
4130 install_node(&bgp_flowspecv4_node
);
4131 install_element(BGP_NODE
, &address_family_flowspecv4_cmd
);
4132 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_exit_bgpd_cmd
);
4133 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_quit_bgpd_cmd
);
4134 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_end_all_cmd
);
4135 install_element(BGP_FLOWSPECV4_NODE
, &exit_address_family_cmd
);
4137 install_node(&bgp_flowspecv6_node
);
4138 install_element(BGP_NODE
, &address_family_flowspecv6_cmd
);
4139 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_exit_bgpd_cmd
);
4140 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_quit_bgpd_cmd
);
4141 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_end_all_cmd
);
4142 install_element(BGP_FLOWSPECV6_NODE
, &exit_address_family_cmd
);
4144 install_node(&bgp_ipv4_node
);
4145 install_element(BGP_NODE
, &address_family_ipv4_cmd
);
4146 install_element(BGP_IPV4_NODE
, &vtysh_exit_bgpd_cmd
);
4147 install_element(BGP_IPV4_NODE
, &vtysh_quit_bgpd_cmd
);
4148 install_element(BGP_IPV4_NODE
, &vtysh_end_all_cmd
);
4149 install_element(BGP_IPV4_NODE
, &exit_address_family_cmd
);
4151 install_node(&bgp_ipv4m_node
);
4152 install_element(BGP_NODE
, &address_family_ipv4_multicast_cmd
);
4153 install_element(BGP_IPV4M_NODE
, &vtysh_exit_bgpd_cmd
);
4154 install_element(BGP_IPV4M_NODE
, &vtysh_quit_bgpd_cmd
);
4155 install_element(BGP_IPV4M_NODE
, &vtysh_end_all_cmd
);
4156 install_element(BGP_IPV4M_NODE
, &exit_address_family_cmd
);
4158 install_node(&bgp_ipv4l_node
);
4159 install_element(BGP_NODE
, &address_family_ipv4_labeled_unicast_cmd
);
4160 install_element(BGP_IPV4L_NODE
, &vtysh_exit_bgpd_cmd
);
4161 install_element(BGP_IPV4L_NODE
, &vtysh_quit_bgpd_cmd
);
4162 install_element(BGP_IPV4L_NODE
, &vtysh_end_all_cmd
);
4163 install_element(BGP_IPV4L_NODE
, &exit_address_family_cmd
);
4165 install_node(&bgp_ipv6_node
);
4166 install_element(BGP_NODE
, &address_family_ipv6_cmd
);
4167 install_element(BGP_IPV6_NODE
, &vtysh_exit_bgpd_cmd
);
4168 install_element(BGP_IPV6_NODE
, &vtysh_quit_bgpd_cmd
);
4169 install_element(BGP_IPV6_NODE
, &vtysh_end_all_cmd
);
4170 install_element(BGP_IPV6_NODE
, &exit_address_family_cmd
);
4172 install_node(&bgp_ipv6m_node
);
4173 install_element(BGP_NODE
, &address_family_ipv6_multicast_cmd
);
4174 install_element(BGP_IPV6M_NODE
, &vtysh_exit_bgpd_cmd
);
4175 install_element(BGP_IPV6M_NODE
, &vtysh_quit_bgpd_cmd
);
4176 install_element(BGP_IPV6M_NODE
, &vtysh_end_all_cmd
);
4177 install_element(BGP_IPV6M_NODE
, &exit_address_family_cmd
);
4179 install_node(&bgp_ipv6l_node
);
4180 install_element(BGP_NODE
, &address_family_ipv6_labeled_unicast_cmd
);
4181 install_element(BGP_IPV6L_NODE
, &vtysh_exit_bgpd_cmd
);
4182 install_element(BGP_IPV6L_NODE
, &vtysh_quit_bgpd_cmd
);
4183 install_element(BGP_IPV6L_NODE
, &vtysh_end_all_cmd
);
4184 install_element(BGP_IPV6L_NODE
, &exit_address_family_cmd
);
4186 #if defined(ENABLE_BGP_VNC)
4187 install_node(&bgp_vrf_policy_node
);
4188 install_element(BGP_NODE
, &vnc_vrf_policy_cmd
);
4189 install_element(BGP_VRF_POLICY_NODE
, &vtysh_exit_bgpd_cmd
);
4190 install_element(BGP_VRF_POLICY_NODE
, &vtysh_quit_bgpd_cmd
);
4191 install_element(BGP_VRF_POLICY_NODE
, &vtysh_end_all_cmd
);
4192 install_element(BGP_VRF_POLICY_NODE
, &exit_vrf_policy_cmd
);
4194 install_node(&bgp_vnc_defaults_node
);
4195 install_element(BGP_NODE
, &vnc_defaults_cmd
);
4196 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_exit_bgpd_cmd
);
4197 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_quit_bgpd_cmd
);
4198 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_end_all_cmd
);
4199 install_element(BGP_VNC_DEFAULTS_NODE
, &exit_vnc_config_cmd
);
4201 install_node(&bgp_vnc_nve_group_node
);
4202 install_element(BGP_NODE
, &vnc_nve_group_cmd
);
4203 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
4204 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
4205 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_end_all_cmd
);
4206 install_element(BGP_VNC_NVE_GROUP_NODE
, &exit_vnc_config_cmd
);
4208 install_node(&bgp_vnc_l2_group_node
);
4209 install_element(BGP_NODE
, &vnc_l2_group_cmd
);
4210 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
4211 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
4212 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_end_all_cmd
);
4213 install_element(BGP_VNC_L2_GROUP_NODE
, &exit_vnc_config_cmd
);
4216 install_node(&bgp_evpn_node
);
4217 install_element(BGP_NODE
, &address_family_evpn_cmd
);
4218 #if defined(HAVE_CUMULUS)
4219 install_element(BGP_NODE
, &address_family_evpn2_cmd
);
4221 install_element(BGP_EVPN_NODE
, &vtysh_quit_bgpd_cmd
);
4222 install_element(BGP_EVPN_NODE
, &vtysh_exit_bgpd_cmd
);
4223 install_element(BGP_EVPN_NODE
, &vtysh_end_all_cmd
);
4224 install_element(BGP_EVPN_NODE
, &exit_address_family_cmd
);
4226 install_node(&bgp_evpn_vni_node
);
4227 install_element(BGP_EVPN_NODE
, &bgp_evpn_vni_cmd
);
4228 install_element(BGP_EVPN_VNI_NODE
, &vtysh_exit_bgpd_cmd
);
4229 install_element(BGP_EVPN_VNI_NODE
, &vtysh_quit_bgpd_cmd
);
4230 install_element(BGP_EVPN_VNI_NODE
, &vtysh_end_all_cmd
);
4231 install_element(BGP_EVPN_VNI_NODE
, &exit_vni_cmd
);
4233 install_node(&rpki_node
);
4234 install_element(CONFIG_NODE
, &rpki_cmd
);
4235 install_element(RPKI_NODE
, &rpki_exit_cmd
);
4236 install_element(RPKI_NODE
, &rpki_quit_cmd
);
4237 install_element(RPKI_NODE
, &vtysh_end_all_cmd
);
4239 install_node(&bmp_node
);
4240 install_element(BGP_NODE
, &bmp_targets_cmd
);
4241 install_element(BMP_NODE
, &bmp_exit_cmd
);
4242 install_element(BMP_NODE
, &bmp_quit_cmd
);
4243 install_element(BMP_NODE
, &vtysh_end_all_cmd
);
4245 install_node(&bgp_srv6_node
);
4246 install_element(BGP_NODE
, &bgp_srv6_cmd
);
4247 install_element(BGP_SRV6_NODE
, &exit_bgp_srv6_cmd
);
4248 install_element(BGP_SRV6_NODE
, &quit_bgp_srv6_cmd
);
4249 install_element(BGP_SRV6_NODE
, &vtysh_end_all_cmd
);
4250 #endif /* HAVE_BGPD */
4253 install_node(&rip_node
);
4255 install_element(CONFIG_NODE
, &router_rip_cmd
);
4256 install_element(RIP_NODE
, &vtysh_exit_ripd_cmd
);
4257 install_element(RIP_NODE
, &vtysh_quit_ripd_cmd
);
4258 install_element(RIP_NODE
, &vtysh_end_all_cmd
);
4259 #endif /* HAVE_RIPD */
4262 install_node(&ripng_node
);
4264 install_element(CONFIG_NODE
, &router_ripng_cmd
);
4265 install_element(RIPNG_NODE
, &vtysh_exit_ripngd_cmd
);
4266 install_element(RIPNG_NODE
, &vtysh_quit_ripngd_cmd
);
4267 install_element(RIPNG_NODE
, &vtysh_end_all_cmd
);
4268 #endif /* HAVE_RIPNGD */
4272 install_node(&ospf_node
);
4273 install_element(CONFIG_NODE
, &router_ospf_cmd
);
4274 install_element(OSPF_NODE
, &vtysh_exit_ospfd_cmd
);
4275 install_element(OSPF_NODE
, &vtysh_quit_ospfd_cmd
);
4276 install_element(OSPF_NODE
, &vtysh_end_all_cmd
);
4277 #endif /* HAVE_OSPFD */
4281 install_node(&ospf6_node
);
4282 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
4283 install_element(OSPF6_NODE
, &vtysh_exit_ospf6d_cmd
);
4284 install_element(OSPF6_NODE
, &vtysh_quit_ospf6d_cmd
);
4285 install_element(OSPF6_NODE
, &vtysh_end_all_cmd
);
4286 #endif /* HAVE_OSPF6D */
4289 #if defined(HAVE_LDPD)
4290 install_node(&ldp_node
);
4291 install_element(CONFIG_NODE
, &ldp_mpls_ldp_cmd
);
4292 install_element(LDP_NODE
, &vtysh_exit_ldpd_cmd
);
4293 install_element(LDP_NODE
, &vtysh_quit_ldpd_cmd
);
4294 install_element(LDP_NODE
, &vtysh_end_all_cmd
);
4296 install_node(&ldp_ipv4_node
);
4297 install_element(LDP_NODE
, &ldp_address_family_ipv4_cmd
);
4298 install_element(LDP_IPV4_NODE
, &vtysh_exit_ldpd_cmd
);
4299 install_element(LDP_IPV4_NODE
, &vtysh_quit_ldpd_cmd
);
4300 install_element(LDP_IPV4_NODE
, &ldp_exit_address_family_cmd
);
4301 install_element(LDP_IPV4_NODE
, &vtysh_end_all_cmd
);
4303 install_node(&ldp_ipv6_node
);
4304 install_element(LDP_NODE
, &ldp_address_family_ipv6_cmd
);
4305 install_element(LDP_IPV6_NODE
, &vtysh_exit_ldpd_cmd
);
4306 install_element(LDP_IPV6_NODE
, &vtysh_quit_ldpd_cmd
);
4307 install_element(LDP_IPV6_NODE
, &ldp_exit_address_family_cmd
);
4308 install_element(LDP_IPV6_NODE
, &vtysh_end_all_cmd
);
4310 install_node(&ldp_ipv4_iface_node
);
4311 install_element(LDP_IPV4_NODE
, &ldp_interface_ifname_cmd
);
4312 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
4313 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
4314 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_end_all_cmd
);
4316 install_node(&ldp_ipv6_iface_node
);
4317 install_element(LDP_IPV6_NODE
, &ldp_interface_ifname_cmd
);
4318 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
4319 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
4320 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_end_all_cmd
);
4322 install_node(&ldp_l2vpn_node
);
4323 install_element(CONFIG_NODE
, &ldp_l2vpn_word_type_vpls_cmd
);
4324 install_element(LDP_L2VPN_NODE
, &vtysh_exit_ldpd_cmd
);
4325 install_element(LDP_L2VPN_NODE
, &vtysh_quit_ldpd_cmd
);
4326 install_element(LDP_L2VPN_NODE
, &vtysh_end_all_cmd
);
4328 install_node(&ldp_pseudowire_node
);
4329 install_element(LDP_L2VPN_NODE
, &ldp_member_pseudowire_ifname_cmd
);
4330 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_exit_ldpd_cmd
);
4331 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_quit_ldpd_cmd
);
4332 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_end_all_cmd
);
4337 install_node(&eigrp_node
);
4338 install_element(CONFIG_NODE
, &router_eigrp_cmd
);
4339 install_element(EIGRP_NODE
, &vtysh_exit_eigrpd_cmd
);
4340 install_element(EIGRP_NODE
, &vtysh_quit_eigrpd_cmd
);
4341 install_element(EIGRP_NODE
, &vtysh_end_all_cmd
);
4342 #endif /* HAVE_EIGRPD */
4346 install_node(&babel_node
);
4347 install_element(CONFIG_NODE
, &router_babel_cmd
);
4348 install_element(BABEL_NODE
, &vtysh_exit_babeld_cmd
);
4349 install_element(BABEL_NODE
, &vtysh_quit_babeld_cmd
);
4350 install_element(BABEL_NODE
, &vtysh_end_all_cmd
);
4351 #endif /* HAVE_BABELD */
4355 install_node(&isis_node
);
4356 install_element(CONFIG_NODE
, &router_isis_cmd
);
4357 install_element(ISIS_NODE
, &vtysh_exit_isisd_cmd
);
4358 install_element(ISIS_NODE
, &vtysh_quit_isisd_cmd
);
4359 install_element(ISIS_NODE
, &vtysh_end_all_cmd
);
4360 #endif /* HAVE_ISISD */
4364 install_node(&openfabric_node
);
4365 install_element(CONFIG_NODE
, &router_openfabric_cmd
);
4366 install_element(OPENFABRIC_NODE
, &vtysh_exit_fabricd_cmd
);
4367 install_element(OPENFABRIC_NODE
, &vtysh_quit_fabricd_cmd
);
4368 install_element(OPENFABRIC_NODE
, &vtysh_end_all_cmd
);
4369 #endif /* HAVE_FABRICD */
4373 install_node(&pbr_map_node
);
4374 install_element(CONFIG_NODE
, &vtysh_pbr_map_cmd
);
4375 install_element(CONFIG_NODE
, &vtysh_no_pbr_map_cmd
);
4376 install_element(PBRMAP_NODE
, &vtysh_exit_pbr_map_cmd
);
4377 install_element(PBRMAP_NODE
, &vtysh_quit_pbr_map_cmd
);
4378 install_element(PBRMAP_NODE
, &vtysh_end_all_cmd
);
4379 #endif /* HAVE_PBRD */
4383 install_node(&bfd_node
);
4384 install_element(CONFIG_NODE
, &bfd_enter_cmd
);
4385 install_element(BFD_NODE
, &vtysh_exit_bfdd_cmd
);
4386 install_element(BFD_NODE
, &vtysh_quit_bfdd_cmd
);
4387 install_element(BFD_NODE
, &vtysh_end_all_cmd
);
4389 install_node(&bfd_peer_node
);
4390 install_element(BFD_NODE
, &bfd_peer_enter_cmd
);
4391 install_element(BFD_PEER_NODE
, &vtysh_exit_bfdd_cmd
);
4392 install_element(BFD_PEER_NODE
, &vtysh_quit_bfdd_cmd
);
4393 install_element(BFD_PEER_NODE
, &vtysh_end_all_cmd
);
4395 install_node(&bfd_profile_node
);
4396 install_element(BFD_NODE
, &bfd_profile_enter_cmd
);
4397 install_element(BFD_PROFILE_NODE
, &vtysh_exit_bfdd_cmd
);
4398 install_element(BFD_PROFILE_NODE
, &vtysh_quit_bfdd_cmd
);
4399 install_element(BFD_PROFILE_NODE
, &vtysh_end_all_cmd
);
4400 #endif /* HAVE_BFDD */
4402 #if defined(HAVE_PATHD)
4403 install_node(&segment_routing_node
);
4404 install_node(&sr_traffic_eng_node
);
4405 install_node(&srte_segment_list_node
);
4406 install_node(&srte_policy_node
);
4407 install_node(&srte_candidate_dyn_node
);
4409 install_element(SEGMENT_ROUTING_NODE
, &vtysh_exit_pathd_cmd
);
4410 install_element(SEGMENT_ROUTING_NODE
, &vtysh_quit_pathd_cmd
);
4411 install_element(SR_TRAFFIC_ENG_NODE
, &vtysh_exit_pathd_cmd
);
4412 install_element(SR_TRAFFIC_ENG_NODE
, &vtysh_quit_pathd_cmd
);
4413 install_element(SR_SEGMENT_LIST_NODE
, &vtysh_exit_pathd_cmd
);
4414 install_element(SR_SEGMENT_LIST_NODE
, &vtysh_quit_pathd_cmd
);
4415 install_element(SR_POLICY_NODE
, &vtysh_exit_pathd_cmd
);
4416 install_element(SR_POLICY_NODE
, &vtysh_quit_pathd_cmd
);
4417 install_element(SR_CANDIDATE_DYN_NODE
, &vtysh_exit_pathd_cmd
);
4418 install_element(SR_CANDIDATE_DYN_NODE
, &vtysh_quit_pathd_cmd
);
4420 install_element(SEGMENT_ROUTING_NODE
, &vtysh_end_all_cmd
);
4421 install_element(SR_TRAFFIC_ENG_NODE
, &vtysh_end_all_cmd
);
4422 install_element(SR_SEGMENT_LIST_NODE
, &vtysh_end_all_cmd
);
4423 install_element(SR_POLICY_NODE
, &vtysh_end_all_cmd
);
4424 install_element(SR_CANDIDATE_DYN_NODE
, &vtysh_end_all_cmd
);
4426 install_element(CONFIG_NODE
, &segment_routing_cmd
);
4427 install_element(SEGMENT_ROUTING_NODE
, &sr_traffic_eng_cmd
);
4428 install_element(SR_TRAFFIC_ENG_NODE
, &srte_segment_list_cmd
);
4429 install_element(SR_TRAFFIC_ENG_NODE
, &srte_policy_cmd
);
4430 install_element(SR_POLICY_NODE
, &srte_policy_candidate_dyn_path_cmd
);
4432 #if defined(HAVE_PATHD_PCEP)
4433 install_node(&pcep_node
);
4434 install_node(&pcep_pcc_node
);
4435 install_node(&pcep_pce_node
);
4436 install_node(&pcep_pce_config_node
);
4438 install_element(PCEP_NODE
, &vtysh_exit_pathd_cmd
);
4439 install_element(PCEP_NODE
, &vtysh_quit_pathd_cmd
);
4440 install_element(PCEP_PCC_NODE
, &vtysh_exit_pathd_cmd
);
4441 install_element(PCEP_PCC_NODE
, &vtysh_quit_pathd_cmd
);
4442 install_element(PCEP_PCE_NODE
, &vtysh_exit_pathd_cmd
);
4443 install_element(PCEP_PCE_NODE
, &vtysh_quit_pathd_cmd
);
4444 install_element(PCEP_PCE_CONFIG_NODE
, &vtysh_exit_pathd_cmd
);
4445 install_element(PCEP_PCE_CONFIG_NODE
, &vtysh_quit_pathd_cmd
);
4447 install_element(PCEP_NODE
, &vtysh_end_all_cmd
);
4448 install_element(PCEP_PCC_NODE
, &vtysh_end_all_cmd
);
4449 install_element(PCEP_PCE_NODE
, &vtysh_end_all_cmd
);
4450 install_element(PCEP_PCE_CONFIG_NODE
, &vtysh_end_all_cmd
);
4452 install_element(SR_TRAFFIC_ENG_NODE
, &pcep_cmd
);
4453 install_element(PCEP_NODE
, &pcep_cli_pcc_cmd
);
4454 install_element(PCEP_NODE
, &pcep_cli_pcep_pce_config_cmd
);
4455 install_element(PCEP_NODE
, &pcep_cli_pce_cmd
);
4456 #endif /* HAVE_PATHD_PCEP */
4458 #endif /* HAVE_PATHD */
4461 install_node(&keychain_node
);
4462 install_element(CONFIG_NODE
, &key_chain_cmd
);
4463 install_element(KEYCHAIN_NODE
, &key_chain_cmd
);
4464 install_element(KEYCHAIN_NODE
, &vtysh_exit_keys_cmd
);
4465 install_element(KEYCHAIN_NODE
, &vtysh_quit_keys_cmd
);
4466 install_element(KEYCHAIN_NODE
, &vtysh_end_all_cmd
);
4468 install_node(&keychain_key_node
);
4469 install_element(KEYCHAIN_NODE
, &key_cmd
);
4470 install_element(KEYCHAIN_KEY_NODE
, &key_chain_cmd
);
4471 install_element(KEYCHAIN_KEY_NODE
, &vtysh_exit_keys_cmd
);
4472 install_element(KEYCHAIN_KEY_NODE
, &vtysh_quit_keys_cmd
);
4473 install_element(KEYCHAIN_KEY_NODE
, &vtysh_end_all_cmd
);
4476 install_node(&nh_group_node
);
4477 install_element(CONFIG_NODE
, &vtysh_nexthop_group_cmd
);
4478 install_element(CONFIG_NODE
, &vtysh_no_nexthop_group_cmd
);
4479 install_element(NH_GROUP_NODE
, &vtysh_end_all_cmd
);
4480 install_element(NH_GROUP_NODE
, &vtysh_exit_nexthop_group_cmd
);
4481 install_element(NH_GROUP_NODE
, &vtysh_quit_nexthop_group_cmd
);
4484 install_node(&zebra_node
);
4486 install_node(&interface_node
);
4487 install_element(CONFIG_NODE
, &vtysh_interface_cmd
);
4488 install_element(INTERFACE_NODE
, &vtysh_end_all_cmd
);
4489 install_element(INTERFACE_NODE
, &vtysh_exit_interface_cmd
);
4490 install_element(INTERFACE_NODE
, &vtysh_quit_interface_cmd
);
4492 install_node(&link_params_node
);
4493 install_element(INTERFACE_NODE
, &vtysh_link_params_cmd
);
4494 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);
4495 install_element(LINK_PARAMS_NODE
, &vtysh_end_all_cmd
);
4496 install_element(LINK_PARAMS_NODE
, &vtysh_exit_interface_cmd
);
4498 install_node(&pw_node
);
4499 install_element(CONFIG_NODE
, &vtysh_pseudowire_cmd
);
4500 install_element(PW_NODE
, &vtysh_end_all_cmd
);
4501 install_element(PW_NODE
, &vtysh_exit_interface_cmd
);
4502 install_element(PW_NODE
, &vtysh_quit_interface_cmd
);
4504 install_node(&vrf_node
);
4505 install_element(CONFIG_NODE
, &vtysh_vrf_cmd
);
4506 install_element(VRF_NODE
, &vtysh_vrf_netns_cmd
);
4507 install_element(VRF_NODE
, &vtysh_no_vrf_netns_cmd
);
4508 install_element(VRF_NODE
, &exit_vrf_config_cmd
);
4509 install_element(VRF_NODE
, &vtysh_end_all_cmd
);
4510 install_element(VRF_NODE
, &vtysh_exit_vrf_cmd
);
4511 install_element(VRF_NODE
, &vtysh_quit_vrf_cmd
);
4513 install_node(&rmap_node
);
4514 install_element(CONFIG_NODE
, &vtysh_route_map_cmd
);
4515 install_element(RMAP_NODE
, &vtysh_exit_rmap_cmd
);
4516 install_element(RMAP_NODE
, &vtysh_quit_rmap_cmd
);
4517 install_element(RMAP_NODE
, &vtysh_end_all_cmd
);
4519 install_node(&vty_node
);
4520 install_element(CONFIG_NODE
, &vtysh_line_vty_cmd
);
4521 install_element(VTY_NODE
, &vtysh_exit_line_vty_cmd
);
4522 install_element(VTY_NODE
, &vtysh_quit_line_vty_cmd
);
4523 install_element(VTY_NODE
, &vtysh_end_all_cmd
);
4526 struct cmd_node
*node
;
4527 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
4528 node
= vector_slot(cmdvec
, i
);
4529 if (!node
|| node
->node
== VIEW_NODE
)
4531 vtysh_install_default(node
->node
);
4536 install_element(VIEW_NODE
, &vtysh_enable_cmd
);
4537 install_element(ENABLE_NODE
, &vtysh_config_terminal_cmd
);
4538 install_element(ENABLE_NODE
, &vtysh_disable_cmd
);
4540 /* "exit" command. */
4541 install_element(VIEW_NODE
, &vtysh_exit_all_cmd
);
4542 install_element(CONFIG_NODE
, &vtysh_exit_all_cmd
);
4543 install_element(VIEW_NODE
, &vtysh_quit_all_cmd
);
4544 install_element(CONFIG_NODE
, &vtysh_quit_all_cmd
);
4546 /* "end" command. */
4547 install_element(CONFIG_NODE
, &vtysh_end_all_cmd
);
4548 install_element(ENABLE_NODE
, &vtysh_end_all_cmd
);
4550 /* SRv6 Data-plane */
4551 install_node(&srv6_node
);
4552 install_element(SEGMENT_ROUTING_NODE
, &srv6_cmd
);
4553 install_element(SRV6_NODE
, &srv6_locators_cmd
);
4554 install_element(SRV6_NODE
, &exit_srv6_config_cmd
);
4555 install_element(SRV6_NODE
, &vtysh_end_all_cmd
);
4557 install_node(&srv6_locs_node
);
4558 install_element(SRV6_LOCS_NODE
, &srv6_locator_cmd
);
4559 install_element(SRV6_LOCS_NODE
, &exit_srv6_locs_config_cmd
);
4560 install_element(SRV6_LOCS_NODE
, &vtysh_end_all_cmd
);
4562 install_node(&srv6_loc_node
);
4563 install_element(SRV6_LOC_NODE
, &exit_srv6_loc_config_cmd
);
4564 install_element(SRV6_LOC_NODE
, &vtysh_end_all_cmd
);
4566 install_element(ENABLE_NODE
, &vtysh_show_running_config_cmd
);
4567 install_element(ENABLE_NODE
, &vtysh_copy_running_config_cmd
);
4568 install_element(ENABLE_NODE
, &vtysh_copy_to_running_cmd
);
4570 /* "write terminal" command. */
4571 install_element(ENABLE_NODE
, &vtysh_write_terminal_cmd
);
4573 install_element(CONFIG_NODE
, &vtysh_integrated_config_cmd
);
4574 install_element(CONFIG_NODE
, &no_vtysh_integrated_config_cmd
);
4576 /* "write memory" command. */
4577 install_element(ENABLE_NODE
, &vtysh_write_memory_cmd
);
4579 install_element(CONFIG_NODE
, &vtysh_terminal_paginate_cmd
);
4580 install_element(VIEW_NODE
, &vtysh_terminal_paginate_cmd
);
4581 install_element(VIEW_NODE
, &vtysh_terminal_length_cmd
);
4582 install_element(VIEW_NODE
, &vtysh_terminal_no_length_cmd
);
4583 install_element(VIEW_NODE
, &vtysh_show_daemons_cmd
);
4585 install_element(VIEW_NODE
, &vtysh_ping_cmd
);
4586 install_element(VIEW_NODE
, &vtysh_ping_ip_cmd
);
4587 install_element(VIEW_NODE
, &vtysh_traceroute_cmd
);
4588 install_element(VIEW_NODE
, &vtysh_traceroute_ip_cmd
);
4589 install_element(VIEW_NODE
, &vtysh_mtrace_cmd
);
4590 install_element(VIEW_NODE
, &vtysh_ping6_cmd
);
4591 install_element(VIEW_NODE
, &vtysh_traceroute6_cmd
);
4592 #if defined(HAVE_SHELL_ACCESS)
4593 install_element(VIEW_NODE
, &vtysh_telnet_cmd
);
4594 install_element(VIEW_NODE
, &vtysh_telnet_port_cmd
);
4595 install_element(VIEW_NODE
, &vtysh_ssh_cmd
);
4597 #if defined(HAVE_SHELL_ACCESS)
4598 install_element(ENABLE_NODE
, &vtysh_start_shell_cmd
);
4599 install_element(ENABLE_NODE
, &vtysh_start_bash_cmd
);
4600 install_element(ENABLE_NODE
, &vtysh_start_zsh_cmd
);
4604 install_element(VIEW_NODE
, &vtysh_show_error_code_cmd
);
4605 install_element(ENABLE_NODE
, &vtysh_show_debugging_cmd
);
4606 install_element(ENABLE_NODE
, &vtysh_show_debugging_hashtable_cmd
);
4607 install_element(ENABLE_NODE
, &vtysh_debug_all_cmd
);
4608 install_element(CONFIG_NODE
, &vtysh_debug_all_cmd
);
4609 install_element(ENABLE_NODE
, &vtysh_debug_memstats_cmd
);
4610 install_element(CONFIG_NODE
, &vtysh_debug_memstats_cmd
);
4613 install_element(ENABLE_NODE
, &show_config_running_cmd
);
4614 install_element(ENABLE_NODE
, &show_yang_operational_data_cmd
);
4615 install_element(ENABLE_NODE
, &show_yang_module_cmd
);
4616 install_element(ENABLE_NODE
, &show_yang_module_detail_cmd
);
4617 install_element(ENABLE_NODE
, &debug_nb_cmd
);
4618 install_element(CONFIG_NODE
, &debug_nb_cmd
);
4620 /* misc lib show commands */
4621 install_element(VIEW_NODE
, &vtysh_show_history_cmd
);
4622 install_element(VIEW_NODE
, &vtysh_show_memory_cmd
);
4623 install_element(VIEW_NODE
, &vtysh_show_modules_cmd
);
4624 install_element(VIEW_NODE
, &vtysh_show_work_queues_cmd
);
4625 install_element(VIEW_NODE
, &vtysh_show_work_queues_daemon_cmd
);
4626 #ifndef EXCLUDE_CPU_TIME
4627 install_element(VIEW_NODE
, &vtysh_show_thread_cmd
);
4629 install_element(VIEW_NODE
, &vtysh_show_poll_cmd
);
4632 install_element(VIEW_NODE
, &vtysh_show_logging_cmd
);
4634 install_element(CONFIG_NODE
, &vtysh_service_password_encrypt_cmd
);
4635 install_element(CONFIG_NODE
, &no_vtysh_service_password_encrypt_cmd
);
4637 install_element(CONFIG_NODE
, &vtysh_password_cmd
);
4638 install_element(CONFIG_NODE
, &no_vtysh_password_cmd
);
4639 install_element(CONFIG_NODE
, &vtysh_enable_password_cmd
);
4640 install_element(CONFIG_NODE
, &no_vtysh_enable_password_cmd
);