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"
42 #include "bgpd/bgp_vty.h"
47 DEFINE_MTYPE_STATIC(MVTYSH
, VTYSH_CMD
, "Vtysh cmd copy")
49 /* Destination for vtysh output */
55 /* VTY shell pager name. */
56 char *vtysh_pager_name
= NULL
;
58 /* VTY shell client structure. */
63 char path
[MAXPATHLEN
];
64 struct vtysh_client
*next
;
67 struct vtysh_client vtysh_client
[] = {
68 {.fd
= -1, .name
= "zebra", .flag
= VTYSH_ZEBRA
, .next
= NULL
},
69 {.fd
= -1, .name
= "ripd", .flag
= VTYSH_RIPD
, .next
= NULL
},
70 {.fd
= -1, .name
= "ripngd", .flag
= VTYSH_RIPNGD
, .next
= NULL
},
71 {.fd
= -1, .name
= "ospfd", .flag
= VTYSH_OSPFD
, .next
= NULL
},
72 {.fd
= -1, .name
= "ospf6d", .flag
= VTYSH_OSPF6D
, .next
= NULL
},
73 {.fd
= -1, .name
= "ldpd", .flag
= VTYSH_LDPD
, .next
= NULL
},
74 {.fd
= -1, .name
= "bgpd", .flag
= VTYSH_BGPD
, .next
= NULL
},
75 {.fd
= -1, .name
= "isisd", .flag
= VTYSH_ISISD
, .next
= NULL
},
76 {.fd
= -1, .name
= "pimd", .flag
= VTYSH_PIMD
, .next
= NULL
},
77 {.fd
= -1, .name
= "nhrpd", .flag
= VTYSH_NHRPD
, .next
= NULL
},
78 {.fd
= -1, .name
= "eigrpd", .flag
= VTYSH_EIGRPD
, .next
= NULL
},
79 {.fd
= -1, .name
= "babeld", .flag
= VTYSH_BABELD
, .next
= NULL
},
80 {.fd
= -1, .name
= "sharpd", .flag
= VTYSH_SHARPD
, .next
= NULL
},
81 {.fd
= -1, .name
= "watchfrr", .flag
= VTYSH_WATCHFRR
, .next
= NULL
},
84 enum vtysh_write_integrated vtysh_write_integrated
=
85 WRITE_INTEGRATED_UNSPECIFIED
;
87 static void vclient_close(struct vtysh_client
*vclient
)
89 if (vclient
->fd
>= 0) {
91 "Warning: closing connection to %s because of an I/O error!\n",
98 /* Return true if str begins with prefix, else return false */
99 static int begins_with(const char *str
, const char *prefix
)
103 size_t lenstr
= strlen(str
);
104 size_t lenprefix
= strlen(prefix
);
105 if (lenprefix
> lenstr
)
107 return strncmp(str
, prefix
, lenprefix
) == 0;
110 static int vtysh_client_run(struct vtysh_client
*vclient
, const char *line
,
111 FILE *fp
, void (*callback
)(void *, const char *),
116 char *buf
= stackbuf
;
117 size_t bufsz
= sizeof(stackbuf
);
118 char *bufvalid
, *end
= NULL
;
119 char terminator
[3] = {0, 0, 0};
124 ret
= write(vclient
->fd
, line
, strlen(line
) + 1);
131 read(vclient
->fd
, bufvalid
, buf
+ bufsz
- bufvalid
);
133 if (nread
< 0 && (errno
== EINTR
|| errno
== EAGAIN
))
137 fprintf(stderr
, "vtysh: error reading from %s: %s (%d)",
138 vclient
->name
, safe_strerror(errno
), errno
);
144 if (bufvalid
- buf
>= 4)
145 end
= memmem(bufvalid
- 4, 4, terminator
,
148 if (end
&& end
+ sizeof(terminator
) + 1 > bufvalid
)
149 /* found \0\0\0 but return code hasn't been read yet */
152 ret
= end
[sizeof(terminator
)];
155 * calculate # bytes we have, up to & not including the
156 * terminator if present
158 size_t textlen
= (end
? end
: bufvalid
) - buf
;
160 /* feed line processing callback if present */
161 while (callback
&& bufvalid
> buf
&& (end
> buf
|| !end
)) {
162 textlen
= (end
? end
: bufvalid
) - buf
;
163 char *eol
= memchr(buf
, '\n', textlen
);
168 /* no line break, end of input, no text left
170 * => don't insert an empty line at the end */
173 /* no line break, end of input, but some text
177 /* continue reading */
180 /* eol is at line end now, either \n => \0 or \0\0\0 */
181 assert(eol
&& eol
<= bufvalid
);
188 callback(cbarg
, buf
);
194 memmove(buf
, eol
, bufvalid
- eol
);
195 bufvalid
-= eol
- buf
;
200 /* else if no callback, dump raw */
203 fwrite(buf
, 1, textlen
, fp
);
204 memmove(buf
, buf
+ textlen
, bufvalid
- buf
- textlen
);
208 if (bufvalid
== buf
+ bufsz
) {
211 if (buf
== stackbuf
) {
212 new = XMALLOC(MTYPE_TMP
, bufsz
);
213 memcpy(new, stackbuf
, sizeof(stackbuf
));
215 new = XREALLOC(MTYPE_TMP
, buf
, bufsz
);
217 bufvalid
= bufvalid
- buf
+ new;
219 /* if end != NULL, we won't be reading more data... */
226 vclient_close(vclient
);
230 XFREE(MTYPE_TMP
, buf
);
234 static int vtysh_client_run_all(struct vtysh_client
*head_client
,
235 const char *line
, int continue_on_err
, FILE *fp
,
236 void (*callback
)(void *, const char *),
239 struct vtysh_client
*client
;
240 int rc
, rc_all
= CMD_SUCCESS
;
241 int correct_instance
= 0, wrong_instance
= 0;
243 for (client
= head_client
; client
; client
= client
->next
) {
244 rc
= vtysh_client_run(client
, line
, fp
, callback
, cbarg
);
245 if (rc
== CMD_NOT_MY_INSTANCE
) {
251 if (rc
!= CMD_SUCCESS
) {
252 if (!continue_on_err
)
257 if (wrong_instance
&& !correct_instance
&& fp
) {
259 "%% [%s]: command ignored as it targets an instance that is not running\n",
261 rc_all
= CMD_WARNING_CONFIG_FAILED
;
266 static int vtysh_client_execute(struct vtysh_client
*head_client
,
267 const char *line
, FILE *fp
)
269 return vtysh_client_run_all(head_client
, line
, 0, fp
, NULL
, NULL
);
272 static void vtysh_client_config(struct vtysh_client
*head_client
, char *line
)
274 /* watchfrr currently doesn't load any config, and has some hardcoded
275 * settings that show up in "show run". skip it here (for now at
276 * least) so we don't get that mangled up in config-write.
278 if (head_client
->flag
== VTYSH_WATCHFRR
)
281 vtysh_client_run_all(head_client
, line
, 1, NULL
,
282 vtysh_config_parse_line
, NULL
);
285 void vtysh_pager_init(void)
289 pager_defined
= getenv("VTYSH_PAGER");
292 vtysh_pager_name
= strdup(pager_defined
);
294 vtysh_pager_name
= strdup(VTYSH_PAGER
);
297 /* Command execution over the vty interface. */
298 static int vtysh_execute_func(const char *line
, int pager
)
303 const struct cmd_element
*cmd
;
307 int saved_ret
, saved_node
;
309 /* Split readline string up into the vector. */
310 vline
= cmd_make_strvec(line
);
315 saved_ret
= ret
= cmd_execute_command(vline
, vty
, &cmd
, 1);
316 saved_node
= vty
->node
;
318 /* If command doesn't succeeded in current node, try to walk up in node
320 * Changing vty->node is enough to try it just out without actual walkup
323 while (ret
!= CMD_SUCCESS
&& ret
!= CMD_SUCCESS_DAEMON
324 && ret
!= CMD_WARNING
&& ret
!= CMD_WARNING_CONFIG_FAILED
325 && vty
->node
> CONFIG_NODE
) {
326 vty
->node
= node_parent(vty
->node
);
327 ret
= cmd_execute_command(vline
, vty
, &cmd
, 1);
331 vty
->node
= saved_node
;
333 /* If command succeeded in any other node than current (tried > 0) we
335 * to move into node in the vtysh where it succeeded. */
336 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
337 || ret
== CMD_WARNING
) {
338 if ((saved_node
== BGP_VPNV4_NODE
339 || saved_node
== BGP_VPNV6_NODE
340 || saved_node
== BGP_IPV4_NODE
341 || saved_node
== BGP_IPV6_NODE
342 || saved_node
== BGP_FLOWSPECV4_NODE
343 || saved_node
== BGP_FLOWSPECV6_NODE
344 || saved_node
== BGP_IPV4M_NODE
345 || saved_node
== BGP_IPV4L_NODE
346 || saved_node
== BGP_IPV6L_NODE
347 || saved_node
== BGP_IPV6M_NODE
348 || saved_node
== BGP_EVPN_NODE
349 || saved_node
== LDP_IPV4_NODE
350 || saved_node
== LDP_IPV6_NODE
)
352 vtysh_execute("exit-address-family");
353 } else if ((saved_node
== BGP_EVPN_VNI_NODE
) && (tried
== 1)) {
354 vtysh_execute("exit-vni");
355 } else if (saved_node
== BGP_VRF_POLICY_NODE
&& (tried
== 1)) {
356 vtysh_execute("exit-vrf-policy");
357 } else if ((saved_node
== BGP_VNC_DEFAULTS_NODE
358 || saved_node
== BGP_VNC_NVE_GROUP_NODE
359 || saved_node
== BGP_VNC_L2_GROUP_NODE
)
361 vtysh_execute("exit-vnc");
362 } else if ((saved_node
== KEYCHAIN_KEY_NODE
363 || saved_node
== LDP_PSEUDOWIRE_NODE
364 || saved_node
== LDP_IPV4_IFACE_NODE
365 || saved_node
== LDP_IPV6_IFACE_NODE
)
367 vtysh_execute("exit");
369 vtysh_execute("end");
370 vtysh_execute("configure terminal");
373 /* If command didn't succeed in any node, continue with return value
380 cmd_free_strvec(vline
);
385 case CMD_WARNING_CONFIG_FAILED
:
386 if (vty
->type
== VTY_FILE
)
387 fprintf(stdout
, "Warning...\n");
389 case CMD_ERR_AMBIGUOUS
:
390 fprintf(stdout
, "%% Ambiguous command.\n");
392 case CMD_ERR_NO_MATCH
:
393 fprintf(stdout
, "%% Unknown command.\n");
395 case CMD_ERR_INCOMPLETE
:
396 fprintf(stdout
, "%% Command incomplete.\n");
398 case CMD_SUCCESS_DAEMON
: {
400 * FIXME: Don't open pager for exit commands. popen() causes
401 * problems if exited from vtysh at all. This hack shouldn't
402 * cause any problem but is really ugly.
405 if (pager
&& vtysh_pager_name
&& outputfile
== stdout
406 && (strncmp(line
, "exit", 4) != 0)) {
407 fp
= popen(vtysh_pager_name
, "w");
409 perror("popen failed for pager");
415 if (!strcmp(cmd
->string
, "configure terminal")) {
416 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
417 cmd_stat
= vtysh_client_execute(
418 &vtysh_client
[i
], line
, fp
);
419 if (cmd_stat
== CMD_WARNING
)
425 vline
= cmd_make_strvec(line
);
428 if (pager
&& vtysh_pager_name
&& fp
429 && fp
!= outputfile
&& closepager
) {
430 if (pclose(fp
) == -1) {
431 perror("pclose failed for pager");
438 ret
= cmd_execute_command(vline
, vty
, &cmd
, 1);
439 cmd_free_strvec(vline
);
440 if (ret
!= CMD_SUCCESS_DAEMON
)
442 } else if (cmd
->func
) {
443 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
448 cmd_stat
= CMD_SUCCESS
;
449 struct vtysh_client
*vc
;
450 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
451 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
452 if (vtysh_client
[i
].fd
< 0
453 && (cmd
->daemon
== vtysh_client
[i
].flag
)) {
454 bool any_inst
= false;
455 for (vc
= &vtysh_client
[i
]; vc
;
461 "%s is not running\n",
462 vtysh_client
[i
].name
);
466 cmd_stat
= vtysh_client_execute(
467 &vtysh_client
[i
], line
, fp
);
468 if (cmd_stat
!= CMD_SUCCESS
)
472 if (cmd_stat
!= CMD_SUCCESS
)
476 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
479 if (pager
&& vtysh_pager_name
&& fp
&& closepager
&& fp
!= outputfile
) {
480 if (pclose(fp
) == -1) {
481 perror("pclose failed for pager");
488 int vtysh_execute_no_pager(const char *line
)
490 return vtysh_execute_func(line
, 0);
493 int vtysh_execute(const char *line
)
495 return vtysh_execute_func(line
, 1);
498 static char *trim(char *s
)
509 while (end
>= s
&& isspace((int)*end
))
513 while (*s
&& isspace((int)*s
))
519 int vtysh_mark_file(const char *filename
)
526 const struct cmd_element
*cmd
;
527 int saved_ret
, prev_node
;
529 char *vty_buf_copy
= NULL
;
530 char *vty_buf_trimmed
= NULL
;
532 if (strncmp("-", filename
, 1) == 0)
535 confp
= fopen(filename
, "r");
538 fprintf(stderr
, "%% Can't open config file %s due to '%s'.\n",
539 filename
, safe_strerror(errno
));
540 return (CMD_ERR_NO_FILE
);
544 vty
->wfd
= STDERR_FILENO
;
545 vty
->type
= VTY_TERM
;
546 vty
->node
= CONFIG_NODE
;
548 vtysh_execute_no_pager("enable");
549 vtysh_execute_no_pager("configure terminal");
550 vty_buf_copy
= XCALLOC(MTYPE_VTYSH_CMD
, VTY_BUFSIZ
);
552 while (fgets(vty
->buf
, VTY_BUFSIZ
, confp
)) {
555 strcpy(vty_buf_copy
, vty
->buf
);
556 vty_buf_trimmed
= trim(vty_buf_copy
);
559 case LDP_IPV4_IFACE_NODE
:
560 if (strncmp(vty_buf_copy
, " ", 3)) {
561 fprintf(outputfile
, " end\n");
562 vty
->node
= LDP_IPV4_NODE
;
565 case LDP_IPV6_IFACE_NODE
:
566 if (strncmp(vty_buf_copy
, " ", 3)) {
567 fprintf(outputfile
, " end\n");
568 vty
->node
= LDP_IPV6_NODE
;
571 case LDP_PSEUDOWIRE_NODE
:
572 if (strncmp(vty_buf_copy
, " ", 2)) {
573 fprintf(outputfile
, " end\n");
574 vty
->node
= LDP_L2VPN_NODE
;
581 if (vty_buf_trimmed
[0] == '!' || vty_buf_trimmed
[0] == '#') {
582 fprintf(outputfile
, "%s", vty
->buf
);
586 /* Split readline string up into the vector. */
587 vline
= cmd_make_strvec(vty
->buf
);
590 fprintf(outputfile
, "%s", vty
->buf
);
594 /* Ignore the "end" lines, we will generate these where
596 if (strlen(vty_buf_trimmed
) == 3
597 && strncmp("end", vty_buf_trimmed
, 3) == 0) {
598 cmd_free_strvec(vline
);
602 prev_node
= vty
->node
;
603 saved_ret
= ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
605 /* If command doesn't succeeded in current node, try to walk up
607 * Changing vty->node is enough to try it just out without
610 while (ret
!= CMD_SUCCESS
&& ret
!= CMD_SUCCESS_DAEMON
611 && ret
!= CMD_WARNING
&& ret
!= CMD_WARNING_CONFIG_FAILED
612 && vty
->node
> CONFIG_NODE
) {
613 vty
->node
= node_parent(vty
->node
);
614 ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
618 /* If command succeeded in any other node than current (tried >
620 * to move into node in the vtysh where it succeeded. */
621 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
622 || ret
== CMD_WARNING
) {
623 if ((prev_node
== BGP_VPNV4_NODE
624 || prev_node
== BGP_VPNV6_NODE
625 || prev_node
== BGP_IPV4_NODE
626 || prev_node
== BGP_IPV6_NODE
627 || prev_node
== BGP_FLOWSPECV4_NODE
628 || prev_node
== BGP_FLOWSPECV6_NODE
629 || prev_node
== BGP_IPV4L_NODE
630 || prev_node
== BGP_IPV6L_NODE
631 || prev_node
== BGP_IPV4M_NODE
632 || prev_node
== BGP_IPV6M_NODE
633 || prev_node
== BGP_EVPN_NODE
)
635 fprintf(outputfile
, "exit-address-family\n");
636 } else if ((prev_node
== BGP_EVPN_VNI_NODE
)
638 fprintf(outputfile
, "exit-vni\n");
639 } else if ((prev_node
== KEYCHAIN_KEY_NODE
)
641 fprintf(outputfile
, "exit\n");
643 fprintf(outputfile
, "end\n");
646 /* If command didn't succeed in any node, continue with return
651 vty
->node
= prev_node
;
654 cmd_free_strvec(vline
);
657 case CMD_WARNING_CONFIG_FAILED
:
658 if (vty
->type
== VTY_FILE
)
659 fprintf(stderr
, "line %d: Warning...: %s\n",
663 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
665 case CMD_ERR_AMBIGUOUS
:
666 fprintf(stderr
, "line %d: %% Ambiguous command: %s\n",
670 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
671 return CMD_ERR_AMBIGUOUS
;
672 case CMD_ERR_NO_MATCH
:
673 fprintf(stderr
, "line %d: %% Unknown command: %s\n",
677 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
678 return CMD_ERR_NO_MATCH
;
679 case CMD_ERR_INCOMPLETE
:
680 fprintf(stderr
, "line %d: %% Command incomplete: %s\n",
684 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
685 return CMD_ERR_INCOMPLETE
;
687 fprintf(stdout
, "%s", vty
->buf
);
689 case CMD_SUCCESS_DAEMON
: {
691 int cmd_stat
= CMD_SUCCESS
;
693 fprintf(outputfile
, "%s", vty
->buf
);
694 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
695 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
696 cmd_stat
= vtysh_client_execute(
697 &vtysh_client
[i
], vty
->buf
,
699 if (cmd_stat
!= CMD_SUCCESS
)
703 if (cmd_stat
!= CMD_SUCCESS
)
707 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
711 /* This is the end */
712 fprintf(outputfile
, "\nend\n");
714 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
722 /* Configration make from file. */
723 int vtysh_config_from_file(struct vty
*vty
, FILE *fp
)
726 const struct cmd_element
*cmd
;
728 int retcode
= CMD_SUCCESS
;
730 while (fgets(vty
->buf
, VTY_BUFSIZ
, fp
)) {
733 ret
= command_config_read_one_line(vty
, &cmd
, 1);
737 case CMD_WARNING_CONFIG_FAILED
:
738 if (vty
->type
== VTY_FILE
)
739 fprintf(stderr
, "line %d: Warning[%d]...: %s\n",
740 lineno
, vty
->node
, vty
->buf
);
741 retcode
= ret
; /* once we have an error, we remember &
744 case CMD_ERR_AMBIGUOUS
:
746 "line %d: %% Ambiguous command[%d]: %s\n",
747 lineno
, vty
->node
, vty
->buf
);
748 retcode
= CMD_ERR_AMBIGUOUS
; /* once we have an error,
752 case CMD_ERR_NO_MATCH
:
753 fprintf(stderr
, "line %d: %% Unknown command[%d]: %s",
754 lineno
, vty
->node
, vty
->buf
);
755 retcode
= CMD_ERR_NO_MATCH
; /* once we have an error, we
756 remember & return that */
758 case CMD_ERR_INCOMPLETE
:
760 "line %d: %% Command incomplete[%d]: %s\n",
761 lineno
, vty
->node
, vty
->buf
);
762 retcode
= CMD_ERR_INCOMPLETE
; /* once we have an error,
766 case CMD_SUCCESS_DAEMON
: {
768 int cmd_stat
= CMD_SUCCESS
;
770 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
771 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
772 cmd_stat
= vtysh_client_execute(
773 &vtysh_client
[i
], vty
->buf
,
776 * CMD_WARNING - Can mean that the
778 * parsed successfully but it was
780 * in a few spots. As such if we
782 * CMD_WARNING from a daemon we
784 * talking to the other daemons for the
788 if (cmd_stat
!= CMD_SUCCESS
789 && cmd_stat
!= CMD_WARNING
) {
791 "line %d: Failure to communicate[%d] to %s, line: %s\n",
793 vtysh_client
[i
].name
,
800 if (cmd_stat
!= CMD_SUCCESS
)
804 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
812 /* We don't care about the point of the cursor when '?' is typed. */
813 static int vtysh_rl_describe(void)
820 struct cmd_token
*token
;
822 vline
= cmd_make_strvec(rl_line_buffer
);
824 /* In case of '> ?'. */
826 vline
= vector_init(1);
827 vector_set(vline
, NULL
);
828 } else if (rl_end
&& isspace((int)rl_line_buffer
[rl_end
- 1]))
829 vector_set(vline
, NULL
);
831 fprintf(stdout
, "\n");
833 describe
= cmd_describe_command(vline
, vty
, &ret
);
835 /* Ambiguous and no match error. */
837 case CMD_ERR_AMBIGUOUS
:
838 cmd_free_strvec(vline
);
839 vector_free(describe
);
840 fprintf(stdout
, "%% Ambiguous command.\n");
844 case CMD_ERR_NO_MATCH
:
845 cmd_free_strvec(vline
);
847 vector_free(describe
);
848 fprintf(stdout
, "%% There is no matched command.\n");
854 /* Get width of command string. */
856 for (i
= 0; i
< vector_active(describe
); i
++)
857 if ((token
= vector_slot(describe
, i
)) != NULL
) {
858 if (token
->text
[0] == '\0')
861 int len
= strlen(token
->text
);
867 for (i
= 0; i
< vector_active(describe
); i
++)
868 if ((token
= vector_slot(describe
, i
)) != NULL
) {
870 fprintf(stdout
, " %-s\n", token
->text
);
872 fprintf(stdout
, " %-*s %s\n", width
,
873 token
->text
, token
->desc
);
875 if (IS_VARYING_TOKEN(token
->type
)) {
876 const char *ref
= vector_slot(
877 vline
, vector_active(vline
) - 1);
879 vector varcomps
= vector_init(VECTOR_MIN_SIZE
);
880 cmd_variable_complete(token
, ref
, varcomps
);
882 if (vector_active(varcomps
) > 0) {
884 rl_get_screen_size(&rows
, &cols
);
886 char *ac
= cmd_variable_comp2str(
888 fprintf(stdout
, "%s\n", ac
);
889 XFREE(MTYPE_TMP
, ac
);
892 vector_free(varcomps
);
896 cmd_free_strvec(vline
);
897 vector_free(describe
);
904 /* Result of cmd_complete_command() call will be stored here
905 * and used in new_completion() in order to put the space in
906 * correct places only. */
909 static char *command_generator(const char *text
, int state
)
912 static char **matched
= NULL
;
913 static int index
= 0;
919 if (vty
->node
== AUTH_NODE
|| vty
->node
== AUTH_ENABLE_NODE
)
922 vline
= cmd_make_strvec(rl_line_buffer
);
926 if (rl_end
&& isspace((int)rl_line_buffer
[rl_end
- 1]))
927 vector_set(vline
, NULL
);
929 matched
= cmd_complete_command(vline
, vty
, &complete_status
);
930 cmd_free_strvec(vline
);
933 if (matched
&& matched
[index
])
934 /* this is free()'d by readline, but we leak 1 count of
935 * MTYPE_COMPLETION */
936 return matched
[index
++];
938 XFREE(MTYPE_TMP
, matched
);
944 static char **new_completion(char *text
, int start
, int end
)
948 matches
= rl_completion_matches(text
, command_generator
);
952 if (complete_status
!= CMD_COMPLETE_FULL_MATCH
)
953 /* only append a space on full match */
954 rl_completion_append_character
= '\0';
960 /* Vty node structures. */
961 static struct cmd_node bgp_node
= {
962 BGP_NODE
, "%s(config-router)# ",
965 static struct cmd_node rip_node
= {
966 RIP_NODE
, "%s(config-router)# ",
969 static struct cmd_node isis_node
= {
970 ISIS_NODE
, "%s(config-router)# ",
973 static struct cmd_node interface_node
= {
974 INTERFACE_NODE
, "%s(config-if)# ",
977 static struct cmd_node pw_node
= {
978 PW_NODE
, "%s(config-pw)# ",
981 static struct cmd_node logicalrouter_node
= {
982 LOGICALROUTER_NODE
, "%s(config-logical-router)# ",
985 static struct cmd_node vrf_node
= {
986 VRF_NODE
, "%s(config-vrf)# ",
989 static struct cmd_node rmap_node
= {RMAP_NODE
, "%s(config-route-map)# "};
991 static struct cmd_node zebra_node
= {ZEBRA_NODE
, "%s(config-router)# "};
993 static struct cmd_node bgp_vpnv4_node
= {BGP_VPNV4_NODE
,
994 "%s(config-router-af)# "};
996 static struct cmd_node bgp_vpnv6_node
= {BGP_VPNV6_NODE
,
997 "%s(config-router-af)# "};
999 static struct cmd_node bgp_flowspecv4_node
= {BGP_FLOWSPECV4_NODE
,
1000 "%s(config-router-af)# "};
1002 static struct cmd_node bgp_flowspecv6_node
= {BGP_FLOWSPECV6_NODE
,
1003 "%s(config-router-af)# "};
1005 static struct cmd_node bgp_ipv4_node
= {BGP_IPV4_NODE
,
1006 "%s(config-router-af)# "};
1008 static struct cmd_node bgp_ipv4m_node
= {BGP_IPV4M_NODE
,
1009 "%s(config-router-af)# "};
1011 static struct cmd_node bgp_ipv4l_node
= {BGP_IPV4L_NODE
,
1012 "%s(config-router-af)# "};
1014 static struct cmd_node bgp_ipv6_node
= {BGP_IPV6_NODE
,
1015 "%s(config-router-af)# "};
1017 static struct cmd_node bgp_ipv6m_node
= {BGP_IPV6M_NODE
,
1018 "%s(config-router-af)# "};
1020 static struct cmd_node bgp_evpn_node
= {BGP_EVPN_NODE
,
1021 "%s(config-router-af)# "};
1023 static struct cmd_node bgp_evpn_vni_node
= {BGP_EVPN_VNI_NODE
,
1024 "%s(config-router-af-vni)# "};
1026 static struct cmd_node bgp_ipv6l_node
= {BGP_IPV6L_NODE
,
1027 "%s(config-router-af)# "};
1029 static struct cmd_node bgp_vnc_defaults_node
= {
1030 BGP_VNC_DEFAULTS_NODE
, "%s(config-router-vnc-defaults)# "};
1032 static struct cmd_node bgp_vnc_nve_group_node
= {
1033 BGP_VNC_NVE_GROUP_NODE
, "%s(config-router-vnc-nve-group)# "};
1035 static struct cmd_node bgp_vrf_policy_node
= {BGP_VRF_POLICY_NODE
,
1036 "%s(config-router-vrf-policy)# "};
1038 static struct cmd_node bgp_vnc_l2_group_node
= {
1039 BGP_VNC_L2_GROUP_NODE
, "%s(config-router-vnc-l2-group)# "};
1041 static struct cmd_node ospf_node
= {OSPF_NODE
, "%s(config-router)# "};
1043 static struct cmd_node eigrp_node
= {EIGRP_NODE
, "%s(config-router)# "};
1045 static struct cmd_node babel_node
= {BABEL_NODE
, "%s(config-router)# "};
1047 static struct cmd_node ripng_node
= {RIPNG_NODE
, "%s(config-router)# "};
1049 static struct cmd_node ospf6_node
= {OSPF6_NODE
, "%s(config-ospf6)# "};
1051 static struct cmd_node ldp_node
= {LDP_NODE
, "%s(config-ldp)# "};
1053 static struct cmd_node ldp_ipv4_node
= {LDP_IPV4_NODE
, "%s(config-ldp-af)# "};
1055 static struct cmd_node ldp_ipv6_node
= {LDP_IPV6_NODE
, "%s(config-ldp-af)# "};
1057 static struct cmd_node ldp_ipv4_iface_node
= {LDP_IPV4_IFACE_NODE
,
1058 "%s(config-ldp-af-if)# "};
1060 static struct cmd_node ldp_ipv6_iface_node
= {LDP_IPV6_IFACE_NODE
,
1061 "%s(config-ldp-af-if)# "};
1063 static struct cmd_node ldp_l2vpn_node
= {LDP_L2VPN_NODE
, "%s(config-l2vpn)# "};
1065 static struct cmd_node ldp_pseudowire_node
= {LDP_PSEUDOWIRE_NODE
,
1066 "%s(config-l2vpn-pw)# "};
1068 static struct cmd_node keychain_node
= {KEYCHAIN_NODE
, "%s(config-keychain)# "};
1070 static struct cmd_node keychain_key_node
= {KEYCHAIN_KEY_NODE
,
1071 "%s(config-keychain-key)# "};
1073 struct cmd_node link_params_node
= {
1074 LINK_PARAMS_NODE
, "%s(config-link-params)# ",
1077 #if defined(HAVE_RPKI)
1078 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
1081 /* Defined in lib/vty.c */
1082 extern struct cmd_node vty_node
;
1084 /* When '^Z' is received from vty, move down to the enable mode. */
1085 static int vtysh_end(void)
1087 switch (vty
->node
) {
1090 /* Nothing to do. */
1093 vty
->node
= ENABLE_NODE
;
1099 DEFUNSH(VTYSH_REALLYALL
, vtysh_end_all
, vtysh_end_all_cmd
, "end",
1100 "End current mode and change to enable mode\n")
1105 DEFUNSH(VTYSH_BGPD
, router_bgp
, router_bgp_cmd
,
1106 "router bgp [(1-4294967295) [<view|vrf> WORD]]",
1107 ROUTER_STR BGP_STR AS_STR
1108 "BGP view\nBGP VRF\n"
1111 vty
->node
= BGP_NODE
;
1115 DEFUNSH(VTYSH_BGPD
, address_family_vpnv4
, address_family_vpnv4_cmd
,
1116 "address-family vpnv4 [unicast]",
1117 "Enter Address Family command mode\n"
1119 "Address Family modifier\n")
1121 vty
->node
= BGP_VPNV4_NODE
;
1125 DEFUNSH(VTYSH_BGPD
, address_family_vpnv6
, address_family_vpnv6_cmd
,
1126 "address-family vpnv6 [unicast]",
1127 "Enter Address Family command mode\n"
1129 "Address Family modifier\n")
1131 vty
->node
= BGP_VPNV6_NODE
;
1135 DEFUNSH(VTYSH_BGPD
, address_family_ipv4
, address_family_ipv4_cmd
,
1136 "address-family ipv4 [unicast]",
1137 "Enter Address Family command mode\n"
1139 "Address Family Modifier\n")
1141 vty
->node
= BGP_IPV4_NODE
;
1145 DEFUNSH(VTYSH_BGPD
, address_family_flowspecv4
, address_family_flowspecv4_cmd
,
1146 "address-family ipv4 flowspec",
1147 "Enter Address Family command mode\n"
1149 "Address Family Modifier\n")
1151 vty
->node
= BGP_FLOWSPECV4_NODE
;
1155 DEFUNSH(VTYSH_BGPD
, address_family_flowspecv6
, address_family_flowspecv6_cmd
,
1156 "address-family ipv6 flowspec",
1157 "Enter Address Family command mode\n"
1159 "Address Family Modifier\n")
1161 vty
->node
= BGP_FLOWSPECV6_NODE
;
1165 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_multicast
,
1166 address_family_ipv4_multicast_cmd
, "address-family ipv4 multicast",
1167 "Enter Address Family command mode\n"
1169 "Address Family modifier\n")
1171 vty
->node
= BGP_IPV4M_NODE
;
1175 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_vpn
, address_family_ipv4_vpn_cmd
,
1176 "address-family ipv4 vpn",
1177 "Enter Address Family command mode\n"
1179 "Address Family modifier\n")
1181 vty
->node
= BGP_VPNV4_NODE
;
1185 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_labeled_unicast
,
1186 address_family_ipv4_labeled_unicast_cmd
,
1187 "address-family ipv4 labeled-unicast",
1188 "Enter Address Family command mode\n"
1190 "Address Family modifier\n")
1192 vty
->node
= BGP_IPV4L_NODE
;
1196 DEFUNSH(VTYSH_BGPD
, address_family_ipv6
, address_family_ipv6_cmd
,
1197 "address-family ipv6 [unicast]",
1198 "Enter Address Family command mode\n"
1200 "Address Family modifier\n")
1202 vty
->node
= BGP_IPV6_NODE
;
1206 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_multicast
,
1207 address_family_ipv6_multicast_cmd
, "address-family ipv6 multicast",
1208 "Enter Address Family command mode\n"
1210 "Address Family modifier\n")
1212 vty
->node
= BGP_IPV6M_NODE
;
1216 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_vpn
, address_family_ipv6_vpn_cmd
,
1217 "address-family ipv6 vpn",
1218 "Enter Address Family command mode\n"
1220 "Address Family modifier\n")
1222 vty
->node
= BGP_VPNV6_NODE
;
1226 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_labeled_unicast
,
1227 address_family_ipv6_labeled_unicast_cmd
,
1228 "address-family ipv6 labeled-unicast",
1229 "Enter Address Family command mode\n"
1231 "Address Family modifier\n")
1233 vty
->node
= BGP_IPV6L_NODE
;
1237 #if defined(HAVE_RPKI)
1242 "Enable rpki and enter rpki configuration mode\n")
1244 vty
->node
= RPKI_NODE
;
1252 "Exit current mode and down to previous mode\n")
1254 vty
->node
= CONFIG_NODE
;
1262 "Exit current mode and down to previous mode\n")
1264 return rpki_exit(self
, vty
, argc
, argv
);
1268 DEFUNSH(VTYSH_BGPD
, address_family_evpn
, address_family_evpn_cmd
,
1269 "address-family <l2vpn evpn>",
1270 "Enter Address Family command mode\n"
1272 "Address Family modifier\n")
1274 vty
->node
= BGP_EVPN_NODE
;
1278 #if defined(HAVE_CUMULUS)
1279 DEFUNSH_HIDDEN(VTYSH_BGPD
, address_family_evpn2
, address_family_evpn2_cmd
,
1280 "address-family evpn",
1281 "Enter Address Family command mode\n"
1282 "EVPN Address family\n")
1284 vty
->node
= BGP_EVPN_NODE
;
1289 DEFUNSH(VTYSH_BGPD
, bgp_evpn_vni
, bgp_evpn_vni_cmd
, "vni (1-16777215)",
1290 "VXLAN Network Identifier\n"
1293 vty
->node
= BGP_EVPN_VNI_NODE
;
1297 #if defined(ENABLE_BGP_VNC)
1298 DEFUNSH(VTYSH_BGPD
, vnc_defaults
, vnc_defaults_cmd
, "vnc defaults",
1299 "VNC/RFP related configuration\n"
1300 "Configure default NVE group\n")
1302 vty
->node
= BGP_VNC_DEFAULTS_NODE
;
1306 DEFUNSH(VTYSH_BGPD
, vnc_nve_group
, vnc_nve_group_cmd
, "vnc nve-group NAME",
1307 "VNC/RFP related configuration\n"
1308 "Configure a NVE group\n"
1311 vty
->node
= BGP_VNC_NVE_GROUP_NODE
;
1315 DEFUNSH(VTYSH_BGPD
, vnc_vrf_policy
, vnc_vrf_policy_cmd
, "vrf-policy NAME",
1316 "Configure a VRF policy group\n"
1319 vty
->node
= BGP_VRF_POLICY_NODE
;
1323 DEFUNSH(VTYSH_BGPD
, vnc_l2_group
, vnc_l2_group_cmd
, "vnc l2-group NAME",
1324 "VNC/RFP related configuration\n"
1325 "Configure a L2 group\n"
1328 vty
->node
= BGP_VNC_L2_GROUP_NODE
;
1333 DEFUNSH(VTYSH_RIPD
, key_chain
, key_chain_cmd
, "key chain WORD",
1334 "Authentication key management\n"
1335 "Key-chain management\n"
1338 vty
->node
= KEYCHAIN_NODE
;
1342 DEFUNSH(VTYSH_RIPD
, key
, key_cmd
, "key (0-2147483647)",
1344 "Key identifier number\n")
1346 vty
->node
= KEYCHAIN_KEY_NODE
;
1350 DEFUNSH(VTYSH_RIPD
, router_rip
, router_rip_cmd
, "router rip",
1353 vty
->node
= RIP_NODE
;
1357 DEFUNSH(VTYSH_RIPNGD
, router_ripng
, router_ripng_cmd
, "router ripng",
1358 ROUTER_STR
"RIPng\n")
1360 vty
->node
= RIPNG_NODE
;
1364 DEFUNSH(VTYSH_OSPFD
, router_ospf
, router_ospf_cmd
,
1365 "router ospf [(1-65535)] [vrf NAME]",
1366 "Enable a routing process\n"
1367 "Start OSPF configuration\n"
1371 vty
->node
= OSPF_NODE
;
1375 DEFUNSH(VTYSH_EIGRPD
, router_eigrp
, router_eigrp_cmd
, "router eigrp (1-65535)",
1376 "Enable a routing process\n"
1377 "Start EIGRP configuration\n"
1378 "AS number to use\n")
1380 vty
->node
= EIGRP_NODE
;
1384 DEFUNSH(VTYSH_BABELD
, router_babel
, router_babel_cmd
, "router babel",
1385 "Enable a routing process\n"
1386 "Make Babel instance command\n")
1388 vty
->node
= BABEL_NODE
;
1392 DEFUNSH(VTYSH_OSPF6D
, router_ospf6
, router_ospf6_cmd
, "router ospf6",
1393 ROUTER_STR OSPF6_STR
)
1395 vty
->node
= OSPF6_NODE
;
1399 #if defined(HAVE_LDPD)
1400 DEFUNSH(VTYSH_LDPD
, ldp_mpls_ldp
, ldp_mpls_ldp_cmd
, "mpls ldp",
1401 "Global MPLS configuration subcommands\n"
1402 "Label Distribution Protocol\n")
1404 vty
->node
= LDP_NODE
;
1408 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv4
, ldp_address_family_ipv4_cmd
,
1409 "address-family ipv4",
1410 "Configure Address Family and its parameters\n"
1413 vty
->node
= LDP_IPV4_NODE
;
1417 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv6
, ldp_address_family_ipv6_cmd
,
1418 "address-family ipv6",
1419 "Configure Address Family and its parameters\n"
1422 vty
->node
= LDP_IPV6_NODE
;
1426 DEFUNSH(VTYSH_LDPD
, ldp_exit_address_family
, ldp_exit_address_family_cmd
,
1427 "exit-address-family", "Exit from Address Family configuration mode\n")
1429 if (vty
->node
== LDP_IPV4_NODE
|| vty
->node
== LDP_IPV6_NODE
)
1430 vty
->node
= LDP_NODE
;
1434 DEFUNSH(VTYSH_LDPD
, ldp_interface_ifname
, ldp_interface_ifname_cmd
,
1436 "Enable LDP on an interface and enter interface submode\n"
1437 "Interface's name\n")
1439 switch (vty
->node
) {
1441 vty
->node
= LDP_IPV4_IFACE_NODE
;
1444 vty
->node
= LDP_IPV6_IFACE_NODE
;
1453 DEFUNSH(VTYSH_LDPD
, ldp_l2vpn_word_type_vpls
, ldp_l2vpn_word_type_vpls_cmd
,
1454 "l2vpn WORD type vpls",
1455 "Configure l2vpn commands\n"
1458 "Virtual Private LAN Service\n")
1460 vty
->node
= LDP_L2VPN_NODE
;
1464 DEFUNSH(VTYSH_LDPD
, ldp_member_pseudowire_ifname
,
1465 ldp_member_pseudowire_ifname_cmd
, "member pseudowire IFNAME",
1466 "L2VPN member configuration\n"
1467 "Pseudowire interface\n"
1468 "Interface's name\n")
1470 vty
->node
= LDP_PSEUDOWIRE_NODE
;
1475 DEFUNSH(VTYSH_ISISD
, router_isis
, router_isis_cmd
, "router isis WORD",
1478 "ISO Routing area tag\n")
1480 vty
->node
= ISIS_NODE
;
1484 DEFUNSH(VTYSH_RMAP
, vtysh_route_map
, vtysh_route_map_cmd
,
1485 "route-map WORD <deny|permit> (1-65535)",
1486 "Create route-map or enter route-map command mode\n"
1488 "Route map denies set operations\n"
1489 "Route map permits set operations\n"
1490 "Sequence to insert to/delete from existing route-map entry\n")
1492 vty
->node
= RMAP_NODE
;
1496 DEFUNSH(VTYSH_ALL
, vtysh_line_vty
, vtysh_line_vty_cmd
, "line vty",
1497 "Configure a terminal line\n"
1498 "Virtual terminal\n")
1500 vty
->node
= VTY_NODE
;
1504 DEFUNSH(VTYSH_REALLYALL
, vtysh_enable
, vtysh_enable_cmd
, "enable",
1505 "Turn on privileged mode command\n")
1507 vty
->node
= ENABLE_NODE
;
1511 DEFUNSH(VTYSH_REALLYALL
, vtysh_disable
, vtysh_disable_cmd
, "disable",
1512 "Turn off privileged mode command\n")
1514 if (vty
->node
== ENABLE_NODE
)
1515 vty
->node
= VIEW_NODE
;
1519 DEFUNSH(VTYSH_REALLYALL
, vtysh_config_terminal
, vtysh_config_terminal_cmd
,
1520 "configure terminal",
1521 "Configuration from vty interface\n"
1522 "Configuration terminal\n")
1524 vty
->node
= CONFIG_NODE
;
1528 static int vtysh_exit(struct vty
*vty
)
1530 switch (vty
->node
) {
1536 vty
->node
= ENABLE_NODE
;
1538 case INTERFACE_NODE
:
1540 case LOGICALROUTER_NODE
:
1552 case LDP_L2VPN_NODE
:
1557 vtysh_execute("end");
1558 vtysh_execute("configure terminal");
1559 vty
->node
= CONFIG_NODE
;
1561 case BGP_VPNV4_NODE
:
1562 case BGP_VPNV6_NODE
:
1564 case BGP_IPV4M_NODE
:
1565 case BGP_IPV4L_NODE
:
1567 case BGP_IPV6M_NODE
:
1568 case BGP_IPV6L_NODE
:
1569 case BGP_FLOWSPECV4_NODE
:
1570 case BGP_FLOWSPECV6_NODE
:
1571 case BGP_VRF_POLICY_NODE
:
1573 case BGP_VNC_DEFAULTS_NODE
:
1574 case BGP_VNC_NVE_GROUP_NODE
:
1575 case BGP_VNC_L2_GROUP_NODE
:
1576 vty
->node
= BGP_NODE
;
1578 case BGP_EVPN_VNI_NODE
:
1579 vty
->node
= BGP_EVPN_NODE
;
1583 vty
->node
= LDP_NODE
;
1585 case LDP_IPV4_IFACE_NODE
:
1586 vty
->node
= LDP_IPV4_NODE
;
1588 case LDP_IPV6_IFACE_NODE
:
1589 vty
->node
= LDP_IPV6_NODE
;
1591 case LDP_PSEUDOWIRE_NODE
:
1592 vty
->node
= LDP_L2VPN_NODE
;
1594 case KEYCHAIN_KEY_NODE
:
1595 vty
->node
= KEYCHAIN_NODE
;
1597 case LINK_PARAMS_NODE
:
1598 vty
->node
= INTERFACE_NODE
;
1606 DEFUNSH(VTYSH_REALLYALL
, vtysh_exit_all
, vtysh_exit_all_cmd
, "exit",
1607 "Exit current mode and down to previous mode\n")
1609 return vtysh_exit(vty
);
1612 DEFUNSH(VTYSH_ALL
, vtysh_quit_all
, vtysh_quit_all_cmd
, "quit",
1613 "Exit current mode and down to previous mode\n")
1615 return vtysh_exit_all(self
, vty
, argc
, argv
);
1618 DEFUNSH(VTYSH_BGPD
, exit_address_family
, exit_address_family_cmd
,
1619 "exit-address-family", "Exit from Address Family configuration mode\n")
1621 if (vty
->node
== BGP_IPV4_NODE
|| vty
->node
== BGP_IPV4M_NODE
1622 || vty
->node
== BGP_IPV4L_NODE
|| vty
->node
== BGP_VPNV4_NODE
1623 || vty
->node
== BGP_VPNV6_NODE
|| vty
->node
== BGP_IPV6_NODE
1624 || vty
->node
== BGP_IPV6L_NODE
|| vty
->node
== BGP_IPV6M_NODE
1625 || vty
->node
== BGP_EVPN_NODE
1626 || vty
->node
== BGP_FLOWSPECV4_NODE
1627 || vty
->node
== BGP_FLOWSPECV6_NODE
)
1628 vty
->node
= BGP_NODE
;
1632 DEFUNSH(VTYSH_BGPD
, exit_vni
, exit_vni_cmd
, "exit-vni", "Exit from VNI mode\n")
1634 if (vty
->node
== BGP_EVPN_VNI_NODE
)
1635 vty
->node
= BGP_EVPN_NODE
;
1639 DEFUNSH(VTYSH_BGPD
, exit_vnc_config
, exit_vnc_config_cmd
, "exit-vnc",
1640 "Exit from VNC configuration mode\n")
1642 if (vty
->node
== BGP_VNC_DEFAULTS_NODE
1643 || vty
->node
== BGP_VNC_NVE_GROUP_NODE
1644 || vty
->node
== BGP_VNC_L2_GROUP_NODE
)
1645 vty
->node
= BGP_NODE
;
1649 DEFUNSH(VTYSH_BGPD
, exit_vrf_policy
, exit_vrf_policy_cmd
, "exit-vrf-policy",
1650 "Exit from VRF configuration mode\n")
1652 if (vty
->node
== BGP_VRF_POLICY_NODE
)
1653 vty
->node
= BGP_NODE
;
1657 DEFUNSH(VTYSH_RIPD
, vtysh_exit_ripd
, vtysh_exit_ripd_cmd
, "exit",
1658 "Exit current mode and down to previous mode\n")
1660 return vtysh_exit(vty
);
1663 DEFUNSH(VTYSH_RIPD
, vtysh_quit_ripd
, vtysh_quit_ripd_cmd
, "quit",
1664 "Exit current mode and down to previous mode\n")
1666 return vtysh_exit_ripd(self
, vty
, argc
, argv
);
1669 DEFUNSH(VTYSH_RIPNGD
, vtysh_exit_ripngd
, vtysh_exit_ripngd_cmd
, "exit",
1670 "Exit current mode and down to previous mode\n")
1672 return vtysh_exit(vty
);
1675 DEFUNSH(VTYSH_RIPNGD
, vtysh_quit_ripngd
, vtysh_quit_ripngd_cmd
, "quit",
1676 "Exit current mode and down to previous mode\n")
1678 return vtysh_exit_ripngd(self
, vty
, argc
, argv
);
1681 DEFUNSH(VTYSH_RMAP
, vtysh_exit_rmap
, vtysh_exit_rmap_cmd
, "exit",
1682 "Exit current mode and down to previous mode\n")
1684 return vtysh_exit(vty
);
1687 DEFUNSH(VTYSH_RMAP
, vtysh_quit_rmap
, vtysh_quit_rmap_cmd
, "quit",
1688 "Exit current mode and down to previous mode\n")
1690 return vtysh_exit_rmap(self
, vty
, argc
, argv
);
1693 DEFUNSH(VTYSH_BGPD
, vtysh_exit_bgpd
, vtysh_exit_bgpd_cmd
, "exit",
1694 "Exit current mode and down to previous mode\n")
1696 return vtysh_exit(vty
);
1699 DEFUNSH(VTYSH_BGPD
, vtysh_quit_bgpd
, vtysh_quit_bgpd_cmd
, "quit",
1700 "Exit current mode and down to previous mode\n")
1702 return vtysh_exit_bgpd(self
, vty
, argc
, argv
);
1705 DEFUNSH(VTYSH_OSPFD
, vtysh_exit_ospfd
, vtysh_exit_ospfd_cmd
, "exit",
1706 "Exit current mode and down to previous mode\n")
1708 return vtysh_exit(vty
);
1711 DEFUNSH(VTYSH_OSPFD
, vtysh_quit_ospfd
, vtysh_quit_ospfd_cmd
, "quit",
1712 "Exit current mode and down to previous mode\n")
1714 return vtysh_exit_ospfd(self
, vty
, argc
, argv
);
1717 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_eigrpd
, vtysh_exit_eigrpd_cmd
, "exit",
1718 "Exit current mode and down to previous mode\n")
1720 return vtysh_exit(vty
);
1723 DEFUNSH(VTYSH_EIGRPD
, vtysh_quit_eigrpd
, vtysh_quit_eigrpd_cmd
, "quit",
1724 "Exit current mode and down to previous mode\n")
1726 return vtysh_exit(vty
);
1729 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_babeld
, vtysh_exit_babeld_cmd
, "exit",
1730 "Exit current mode and down to previous mode\n")
1732 return vtysh_exit(vty
);
1735 DEFUNSH(VTYSH_BABELD
, vtysh_quit_babeld
, vtysh_quit_babeld_cmd
, "quit",
1736 "Exit current mode and down to previous mode\n")
1738 return vtysh_exit(vty
);
1741 DEFUNSH(VTYSH_OSPF6D
, vtysh_exit_ospf6d
, vtysh_exit_ospf6d_cmd
, "exit",
1742 "Exit current mode and down to previous mode\n")
1744 return vtysh_exit(vty
);
1747 DEFUNSH(VTYSH_OSPF6D
, vtysh_quit_ospf6d
, vtysh_quit_ospf6d_cmd
, "quit",
1748 "Exit current mode and down to previous mode\n")
1750 return vtysh_exit_ospf6d(self
, vty
, argc
, argv
);
1753 #if defined(HAVE_LDPD)
1754 DEFUNSH(VTYSH_LDPD
, vtysh_exit_ldpd
, vtysh_exit_ldpd_cmd
, "exit",
1755 "Exit current mode and down to previous mode\n")
1757 return vtysh_exit(vty
);
1760 ALIAS(vtysh_exit_ldpd
, vtysh_quit_ldpd_cmd
, "quit",
1761 "Exit current mode and down to previous mode\n")
1764 DEFUNSH(VTYSH_ISISD
, vtysh_exit_isisd
, vtysh_exit_isisd_cmd
, "exit",
1765 "Exit current mode and down to previous mode\n")
1767 return vtysh_exit(vty
);
1770 DEFUNSH(VTYSH_ISISD
, vtysh_quit_isisd
, vtysh_quit_isisd_cmd
, "quit",
1771 "Exit current mode and down to previous mode\n")
1773 return vtysh_exit_isisd(self
, vty
, argc
, argv
);
1776 DEFUNSH(VTYSH_ALL
, vtysh_exit_line_vty
, vtysh_exit_line_vty_cmd
, "exit",
1777 "Exit current mode and down to previous mode\n")
1779 return vtysh_exit(vty
);
1782 DEFUNSH(VTYSH_ALL
, vtysh_quit_line_vty
, vtysh_quit_line_vty_cmd
, "quit",
1783 "Exit current mode and down to previous mode\n")
1785 return vtysh_exit_line_vty(self
, vty
, argc
, argv
);
1788 DEFUNSH(VTYSH_INTERFACE
, vtysh_interface
, vtysh_interface_cmd
,
1789 "interface IFNAME [vrf NAME]",
1790 "Select an interface to configure\n"
1791 "Interface's name\n" VRF_CMD_HELP_STR
)
1793 vty
->node
= INTERFACE_NODE
;
1797 DEFUNSH(VTYSH_ZEBRA
, vtysh_pseudowire
, vtysh_pseudowire_cmd
,
1798 "pseudowire IFNAME",
1799 "Static pseudowire configuration\n"
1800 "Pseudowire name\n")
1802 vty
->node
= PW_NODE
;
1806 /* TODO Implement "no interface command in isisd. */
1807 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_RIPNGD
| VTYSH_OSPFD
| VTYSH_OSPF6D
1809 vtysh_no_interface_cmd
, "no interface IFNAME", NO_STR
1810 "Delete a pseudo interface's configuration\n"
1811 "Interface's name\n")
1813 DEFSH(VTYSH_ZEBRA
, vtysh_no_interface_vrf_cmd
, "no interface IFNAME vrf NAME",
1815 "Delete a pseudo interface's configuration\n"
1816 "Interface's name\n" VRF_CMD_HELP_STR
)
1818 DEFUNSH(VTYSH_ZEBRA
, vtysh_logicalrouter
, vtysh_logicalrouter_cmd
,
1819 "logical-router (1-65535) ns NAME",
1820 "Enable a logical-router\n"
1821 "Specify the logical-router indentifier\n"
1823 "The file name in " NS_RUN_DIR
", or a full pathname\n")
1825 vty
->node
= LOGICALROUTER_NODE
;
1829 DEFSH(VTYSH_ZEBRA
, vtysh_no_logicalrouter_cmd
,
1830 "no logical-router (1-65535) ns NAME", NO_STR
1831 "Enable a Logical-Router\n"
1832 "Specify the Logical-Router identifier\n"
1834 "The file name in " NS_RUN_DIR
", or a full pathname\n")
1836 DEFUNSH(VTYSH_VRF
, vtysh_vrf
, vtysh_vrf_cmd
, "vrf NAME",
1837 "Select a VRF to configure\n"
1840 vty
->node
= VRF_NODE
;
1844 DEFSH(VTYSH_ZEBRA
, vtysh_no_vrf_cmd
, "no vrf NAME", NO_STR
1845 "Delete a pseudo vrf's configuration\n"
1848 DEFUNSH(VTYSH_NS
, vtysh_exit_logicalrouter
,
1849 vtysh_exit_logicalrouter_cmd
, "exit",
1850 "Exit current mode and down to previous mode\n")
1852 return vtysh_exit(vty
);
1855 DEFUNSH(VTYSH_NS
, vtysh_quit_logicalrouter
,
1856 vtysh_quit_logicalrouter_cmd
, "quit",
1857 "Exit current mode and down to previous mode\n")
1859 return vtysh_exit_logicalrouter(self
, vty
, argc
, argv
);
1862 DEFUNSH(VTYSH_VRF
, vtysh_exit_vrf
, vtysh_exit_vrf_cmd
, "exit",
1863 "Exit current mode and down to previous mode\n")
1865 return vtysh_exit(vty
);
1868 DEFUNSH(VTYSH_VRF
, vtysh_quit_vrf
, vtysh_quit_vrf_cmd
, "quit",
1869 "Exit current mode and down to previous mode\n")
1871 return vtysh_exit_vrf(self
, vty
, argc
, argv
);
1874 /* TODO Implement interface description commands in ripngd, ospf6d
1876 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_OSPFD
| VTYSH_EIGRPD
,
1877 vtysh_interface_desc_cmd
, "description LINE...",
1878 "Interface specific description\n"
1879 "Characters describing this interface\n")
1881 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_OSPFD
| VTYSH_EIGRPD
,
1882 vtysh_no_interface_desc_cmd
, "no description",
1883 NO_STR
"Interface specific description\n")
1885 DEFUNSH(VTYSH_INTERFACE
, vtysh_exit_interface
, vtysh_exit_interface_cmd
, "exit",
1886 "Exit current mode and down to previous mode\n")
1888 return vtysh_exit(vty
);
1891 DEFUNSH(VTYSH_INTERFACE
, vtysh_quit_interface
, vtysh_quit_interface_cmd
, "quit",
1892 "Exit current mode and down to previous mode\n")
1894 return vtysh_exit_interface(self
, vty
, argc
, argv
);
1897 DEFUN (vtysh_show_thread
,
1898 vtysh_show_thread_cmd
,
1899 "show thread cpu [FILTER]",
1901 "Thread information\n"
1902 "Thread CPU usage\n"
1903 "Display filter (rwtexb)\n")
1907 int ret
= CMD_SUCCESS
;
1910 const char *filter
=
1911 argv_find(argv
, argc
, "FILTER", &idx
) ? argv
[idx
]->arg
: "";
1913 snprintf(line
, sizeof(line
), "do show thread cpu %s\n", filter
);
1914 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1915 if (vtysh_client
[i
].fd
>= 0) {
1916 fprintf(stdout
, "Thread statistics for %s:\n",
1917 vtysh_client
[i
].name
);
1918 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
1920 fprintf(stdout
, "\n");
1925 DEFUN (vtysh_show_work_queues
,
1926 vtysh_show_work_queues_cmd
,
1929 "Work Queue information\n")
1932 int ret
= CMD_SUCCESS
;
1933 char line
[] = "do show work-queues\n";
1935 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1936 if (vtysh_client
[i
].fd
>= 0) {
1937 fprintf(stdout
, "Work queue statistics for %s:\n",
1938 vtysh_client
[i
].name
);
1939 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
1941 fprintf(stdout
, "\n");
1947 DEFUN (vtysh_show_work_queues_daemon
,
1948 vtysh_show_work_queues_daemon_cmd
,
1949 "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd>",
1951 "Work Queue information\n"
1952 "For the zebra daemon\n"
1953 "For the rip daemon\n"
1954 "For the ripng daemon\n"
1955 "For the ospf daemon\n"
1956 "For the ospfv6 daemon\n"
1957 "For the bgp daemon\n"
1958 "For the isis daemon\n")
1960 int idx_protocol
= 2;
1962 int ret
= CMD_SUCCESS
;
1964 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
1965 if (strmatch(vtysh_client
[i
].name
, argv
[idx_protocol
]->text
))
1969 ret
= vtysh_client_execute(&vtysh_client
[i
], "show work-queues\n",
1975 DEFUNSH(VTYSH_ZEBRA
, vtysh_link_params
, vtysh_link_params_cmd
, "link-params",
1978 vty
->node
= LINK_PARAMS_NODE
;
1982 DEFUNSH(VTYSH_ZEBRA
, exit_link_params
, exit_link_params_cmd
, "exit-link-params",
1983 "Exit from Link Params configuration node\n")
1985 if (vty
->node
== LINK_PARAMS_NODE
)
1986 vty
->node
= INTERFACE_NODE
;
1990 static int show_per_daemon(const char *line
, const char *headline
)
1993 int ret
= CMD_SUCCESS
;
1995 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1996 if (vtysh_client
[i
].fd
>= 0) {
1997 fprintf(outputfile
, headline
, vtysh_client
[i
].name
);
1998 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
2000 fprintf(stdout
, "\n");
2006 DEFUNSH_HIDDEN (0x00,
2008 vtysh_debug_all_cmd
,
2012 "Toggle all debugs on or off\n")
2017 DEFUN (vtysh_show_debugging
,
2018 vtysh_show_debugging_cmd
,
2023 return show_per_daemon("do show debugging\n", "");
2026 DEFUN (vtysh_show_debugging_hashtable
,
2027 vtysh_show_debugging_hashtable_cmd
,
2028 "show debugging hashtable [statistics]",
2031 "Statistics about hash tables\n"
2032 "Statistics about hash tables\n")
2034 fprintf(stdout
, "\n");
2036 "Load factor (LF) - average number of elements across all buckets\n");
2038 "Full load factor (FLF) - average number of elements across full buckets\n\n");
2040 "Standard deviation (SD) is calculated for both the LF and FLF\n");
2042 "and indicates the typical deviation of bucket chain length\n");
2043 fprintf(stdout
, "from the value in the corresponding load factor.\n\n");
2045 return show_per_daemon("do show debugging hashtable\n",
2046 "Hashtable statistics for %s:\n");
2050 DEFUN (vtysh_show_memory
,
2051 vtysh_show_memory_cmd
,
2054 "Memory statistics\n")
2056 return show_per_daemon("show memory\n", "Memory statistics for %s:\n");
2059 DEFUN (vtysh_show_modules
,
2060 vtysh_show_modules_cmd
,
2065 return show_per_daemon("show modules\n",
2066 "Module information for %s:\n");
2069 /* Logging commands. */
2070 DEFUN (vtysh_show_logging
,
2071 vtysh_show_logging_cmd
,
2074 "Show current logging configuration\n")
2076 return show_per_daemon("do show logging\n",
2077 "Logging configuration for %s:\n");
2080 DEFUNSH(VTYSH_ALL
, vtysh_log_stdout
, vtysh_log_stdout_cmd
, "log stdout",
2082 "Set stdout logging level\n")
2087 DEFUNSH(VTYSH_ALL
, vtysh_log_stdout_level
, vtysh_log_stdout_level_cmd
,
2088 "log stdout <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2090 "Set stdout logging level\n" LOG_LEVEL_DESC
)
2095 DEFUNSH(VTYSH_ALL
, no_vtysh_log_stdout
, no_vtysh_log_stdout_cmd
,
2096 "no log stdout [LEVEL]", NO_STR
2098 "Cancel logging to stdout\n"
2104 DEFUNSH(VTYSH_ALL
, vtysh_log_file
, vtysh_log_file_cmd
, "log file FILENAME",
2107 "Logging filename\n")
2112 DEFUNSH(VTYSH_ALL
, vtysh_log_file_level
, vtysh_log_file_level_cmd
,
2113 "log file FILENAME <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2116 "Logging filename\n" LOG_LEVEL_DESC
)
2121 DEFUNSH(VTYSH_ALL
, no_vtysh_log_file
, no_vtysh_log_file_cmd
,
2122 "no log file [FILENAME [LEVEL]]", NO_STR
2124 "Cancel logging to file\n"
2125 "Logging file name\n"
2131 DEFUNSH(VTYSH_ALL
, vtysh_log_monitor
, vtysh_log_monitor_cmd
,
2132 "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
2134 "Set terminal line (monitor) logging level\n" LOG_LEVEL_DESC
)
2139 DEFUNSH(VTYSH_ALL
, no_vtysh_log_monitor
, no_vtysh_log_monitor_cmd
,
2140 "no log monitor [LEVEL]", NO_STR
2142 "Disable terminal line (monitor) logging\n"
2148 DEFUNSH(VTYSH_ALL
, vtysh_log_syslog
, vtysh_log_syslog_cmd
,
2149 "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
2151 "Set syslog logging level\n" LOG_LEVEL_DESC
)
2156 DEFUNSH(VTYSH_ALL
, no_vtysh_log_syslog
, no_vtysh_log_syslog_cmd
,
2157 "no log syslog [LEVEL]", NO_STR
2159 "Cancel logging to syslog\n"
2165 DEFUNSH(VTYSH_ALL
, vtysh_log_facility
, vtysh_log_facility_cmd
,
2166 "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>",
2168 "Facility parameter for syslog messages\n" LOG_FACILITY_DESC
)
2173 DEFUNSH(VTYSH_ALL
, no_vtysh_log_facility
, no_vtysh_log_facility_cmd
,
2174 "no log facility [FACILITY]", NO_STR
2176 "Reset syslog facility to default (daemon)\n"
2177 "Syslog facility\n")
2183 VTYSH_ALL
, vtysh_log_trap
, vtysh_log_trap_cmd
,
2184 "log trap <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2186 "(Deprecated) Set logging level and default for all destinations\n" LOG_LEVEL_DESC
)
2191 DEFUNSH_DEPRECATED(VTYSH_ALL
, no_vtysh_log_trap
, no_vtysh_log_trap_cmd
,
2192 "no log trap [LEVEL]", NO_STR
2194 "Permit all logging information\n"
2200 DEFUNSH(VTYSH_ALL
, vtysh_log_record_priority
, vtysh_log_record_priority_cmd
,
2201 "log record-priority",
2203 "Log the priority of the message within the message\n")
2208 DEFUNSH(VTYSH_ALL
, no_vtysh_log_record_priority
,
2209 no_vtysh_log_record_priority_cmd
, "no log record-priority", NO_STR
2211 "Do not log the priority of the message within the message\n")
2216 DEFUNSH(VTYSH_ALL
, vtysh_log_timestamp_precision
,
2217 vtysh_log_timestamp_precision_cmd
, "log timestamp precision (0-6)",
2219 "Timestamp configuration\n"
2220 "Set the timestamp precision\n"
2221 "Number of subsecond digits\n")
2226 DEFUNSH(VTYSH_ALL
, no_vtysh_log_timestamp_precision
,
2227 no_vtysh_log_timestamp_precision_cmd
, "no log timestamp precision",
2230 "Timestamp configuration\n"
2231 "Reset the timestamp precision to the default value of 0\n")
2236 DEFUNSH(VTYSH_ALL
, vtysh_service_password_encrypt
,
2237 vtysh_service_password_encrypt_cmd
, "service password-encryption",
2238 "Set up miscellaneous service\n"
2239 "Enable encrypted passwords\n")
2244 DEFUNSH(VTYSH_ALL
, no_vtysh_service_password_encrypt
,
2245 no_vtysh_service_password_encrypt_cmd
, "no service password-encryption",
2247 "Set up miscellaneous service\n"
2248 "Enable encrypted passwords\n")
2253 DEFUNSH(VTYSH_ALL
, vtysh_config_password
, vtysh_password_cmd
,
2254 "password [(8-8)] LINE",
2255 "Assign the terminal connection password\n"
2256 "Specifies a HIDDEN password will follow\n"
2257 "The password string\n")
2262 DEFUNSH(VTYSH_ALL
, vtysh_config_enable_password
, vtysh_enable_password_cmd
,
2263 "enable password [(8-8)] LINE",
2264 "Modify enable password parameters\n"
2265 "Assign the privileged level password\n"
2266 "Specifies a HIDDEN password will follow\n"
2267 "The 'enable' password string\n")
2272 DEFUNSH(VTYSH_ALL
, no_vtysh_config_enable_password
,
2273 no_vtysh_enable_password_cmd
, "no enable password", NO_STR
2274 "Modify enable password parameters\n"
2275 "Assign the privileged level password\n")
2280 DEFUN (vtysh_write_terminal
,
2281 vtysh_write_terminal_cmd
,
2282 "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
2283 "Write running configuration to memory, network, or terminal\n"
2284 "Write to terminal\n"
2285 "For the zebra daemon\n"
2286 "For the rip daemon\n"
2287 "For the ripng daemon\n"
2288 "For the ospf daemon\n"
2289 "For the ospfv6 daemon\n"
2290 "For the ldpd daemon\n"
2291 "For the bgp daemon\n"
2292 "For the isis daemon\n"
2293 "For the pim daemon\n")
2296 char line
[] = "do write terminal\n";
2297 FILE *fp
= outputfile
;
2299 if (fp
== stdout
&& vtysh_pager_name
) {
2300 fp
= popen(vtysh_pager_name
, "w");
2307 fprintf(outputfile
, "Building configuration...\n");
2308 fprintf(outputfile
, "\nCurrent configuration:\n");
2309 fprintf(outputfile
, "!\n");
2311 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2313 || (strmatch(vtysh_client
[i
].name
, argv
[2]->text
)))
2314 vtysh_client_config(&vtysh_client
[i
], line
);
2316 /* Integrate vtysh specific configuration. */
2317 vtysh_config_write();
2319 vtysh_config_dump(fp
);
2321 if (vtysh_pager_name
&& fp
&& fp
!= outputfile
) {
2323 if (pclose(fp
) == -1) {
2330 fprintf(outputfile
, "end\n");
2334 DEFUN (vtysh_show_running_config
,
2335 vtysh_show_running_config_cmd
,
2336 "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
2338 "Current operating configuration\n"
2339 "For the zebra daemon\n"
2340 "For the rip daemon\n"
2341 "For the ripng daemon\n"
2342 "For the ospf daemon\n"
2343 "For the ospfv6 daemon\n"
2344 "For the ldp daemon\n"
2345 "For the bgp daemon\n"
2346 "For the isis daemon\n"
2347 "For the pim daemon\n")
2349 return vtysh_write_terminal(self
, vty
, argc
, argv
);
2352 DEFUN (vtysh_integrated_config
,
2353 vtysh_integrated_config_cmd
,
2354 "service integrated-vtysh-config",
2355 "Set up miscellaneous service\n"
2356 "Write configuration into integrated file\n")
2358 vtysh_write_integrated
= WRITE_INTEGRATED_YES
;
2362 DEFUN (no_vtysh_integrated_config
,
2363 no_vtysh_integrated_config_cmd
,
2364 "no service integrated-vtysh-config",
2366 "Set up miscellaneous service\n"
2367 "Write configuration into integrated file\n")
2369 vtysh_write_integrated
= WRITE_INTEGRATED_NO
;
2373 static void backup_config_file(const char *fbackup
)
2375 char *integrate_sav
= NULL
;
2377 integrate_sav
= malloc(strlen(fbackup
) + strlen(CONF_BACKUP_EXT
) + 1);
2378 strcpy(integrate_sav
, fbackup
);
2379 strcat(integrate_sav
, CONF_BACKUP_EXT
);
2381 /* Move current configuration file to backup config file. */
2382 unlink(integrate_sav
);
2383 rename(fbackup
, integrate_sav
);
2384 free(integrate_sav
);
2387 int vtysh_write_config_integrated(void)
2390 char line
[] = "do write terminal\n";
2393 struct passwd
*pwentry
;
2394 struct group
*grentry
;
2400 fprintf(stdout
, "Building Configuration...\n");
2402 backup_config_file(frr_config
);
2403 fp
= fopen(frr_config
, "w");
2406 "%% Error: failed to open configuration file %s: %s\n",
2407 frr_config
, safe_strerror(errno
));
2408 return CMD_WARNING_CONFIG_FAILED
;
2412 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2413 vtysh_client_config(&vtysh_client
[i
], line
);
2415 vtysh_config_write();
2416 vtysh_config_dump(fp
);
2418 if (fchmod(fd
, CONFIGFILE_MASK
) != 0) {
2419 printf("%% Warning: can't chmod configuration file %s: %s\n",
2420 frr_config
, safe_strerror(errno
));
2425 pwentry
= getpwnam(FRR_USER
);
2427 uid
= pwentry
->pw_uid
;
2429 printf("%% Warning: could not look up user \"%s\"\n", FRR_USER
);
2434 grentry
= getgrnam(FRR_GROUP
);
2436 gid
= grentry
->gr_gid
;
2438 printf("%% Warning: could not look up group \"%s\"\n",
2444 if (!fstat(fd
, &st
)) {
2445 if (st
.st_uid
== uid
)
2447 if (st
.st_gid
== gid
)
2449 if ((uid
!= (uid_t
)-1 || gid
!= (gid_t
)-1)
2450 && fchown(fd
, uid
, gid
)) {
2451 printf("%% Warning: can't chown configuration file %s: %s\n",
2452 frr_config
, safe_strerror(errno
));
2456 printf("%% Warning: stat() failed on %s: %s\n", frr_config
,
2457 safe_strerror(errno
));
2463 printf("Integrated configuration saved to %s\n", frr_config
);
2471 static bool want_config_integrated(void)
2475 switch (vtysh_write_integrated
) {
2476 case WRITE_INTEGRATED_UNSPECIFIED
:
2477 if (stat(frr_config
, &s
) && errno
== ENOENT
)
2480 case WRITE_INTEGRATED_NO
:
2482 case WRITE_INTEGRATED_YES
:
2488 DEFUN (vtysh_write_memory
,
2489 vtysh_write_memory_cmd
,
2490 "write [<memory|file>]",
2491 "Write running configuration to memory, network, or terminal\n"
2492 "Write configuration to the file (same as write file)\n"
2493 "Write configuration to the file (same as write memory)\n")
2495 int ret
= CMD_SUCCESS
;
2496 char line
[] = "do write memory\n";
2500 "Note: this version of vtysh never writes vtysh.conf\n");
2502 /* If integrated frr.conf explicitely set. */
2503 if (want_config_integrated()) {
2504 ret
= CMD_WARNING_CONFIG_FAILED
;
2505 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2506 if (vtysh_client
[i
].flag
== VTYSH_WATCHFRR
)
2508 if (i
< array_size(vtysh_client
) && vtysh_client
[i
].fd
!= -1)
2509 ret
= vtysh_client_execute(&vtysh_client
[i
],
2510 "do write integrated",
2514 * If watchfrr returns CMD_WARNING_CONFIG_FAILED this means
2515 * that it could not write the config, but additionally
2516 * indicates that we should not try either
2518 if (ret
!= CMD_SUCCESS
&& ret
!= CMD_WARNING_CONFIG_FAILED
) {
2519 printf("\nWarning: attempting direct configuration write without "
2520 "watchfrr.\nFile permissions and ownership may be "
2521 "incorrect, or write may fail.\n\n");
2522 ret
= vtysh_write_config_integrated();
2527 fprintf(outputfile
, "Building Configuration...\n");
2529 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2530 ret
= vtysh_client_execute(&vtysh_client
[i
], line
, outputfile
);
2535 DEFUN (vtysh_copy_running_config
,
2536 vtysh_copy_running_config_cmd
,
2537 "copy running-config startup-config",
2538 "Copy from one file to another\n"
2539 "Copy from current system configuration\n"
2540 "Copy to startup configuration\n")
2542 return vtysh_write_memory(self
, vty
, argc
, argv
);
2545 DEFUN (vtysh_terminal_length
,
2546 vtysh_terminal_length_cmd
,
2547 "terminal length (0-512)",
2548 "Set terminal line parameters\n"
2549 "Set number of lines on a screen\n"
2550 "Number of lines on screen (0 for no pausing)\n")
2554 char *endptr
= NULL
;
2555 char default_pager
[10];
2557 lines
= strtol(argv
[idx_number
]->arg
, &endptr
, 10);
2558 if (lines
< 0 || lines
> 512 || *endptr
!= '\0') {
2559 fprintf(outputfile
, "length is malformed\n");
2563 if (vtysh_pager_name
) {
2564 free(vtysh_pager_name
);
2565 vtysh_pager_name
= NULL
;
2569 snprintf(default_pager
, 10, "more -%i", lines
);
2570 vtysh_pager_name
= strdup(default_pager
);
2576 DEFUN (vtysh_terminal_no_length
,
2577 vtysh_terminal_no_length_cmd
,
2578 "terminal no length",
2579 "Set terminal line parameters\n"
2581 "Set number of lines on a screen\n")
2583 if (vtysh_pager_name
) {
2584 free(vtysh_pager_name
);
2585 vtysh_pager_name
= NULL
;
2592 DEFUN (vtysh_show_daemons
,
2593 vtysh_show_daemons_cmd
,
2596 "Show list of running daemons\n")
2600 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2601 if (vtysh_client
[i
].fd
>= 0)
2602 fprintf(outputfile
, " %s", vtysh_client
[i
].name
);
2603 fprintf(outputfile
, "\n");
2608 /* Execute command in child process. */
2609 static void execute_command(const char *command
, int argc
, const char *arg1
,
2619 /* Failure of fork(). */
2620 fprintf(stderr
, "Can't fork: %s\n", safe_strerror(errno
));
2622 } else if (pid
== 0) {
2623 /* This is child process. */
2626 execlp(command
, command
, (const char *)NULL
);
2629 execlp(command
, command
, arg1
, (const char *)NULL
);
2632 execlp(command
, command
, arg1
, arg2
,
2633 (const char *)NULL
);
2637 /* When execlp suceed, this part is not executed. */
2638 fprintf(stderr
, "Can't execute %s: %s\n", command
,
2639 safe_strerror(errno
));
2642 /* This is parent. */
2644 wait4(pid
, &status
, 0, NULL
);
2652 "Send echo messages\n"
2653 "Ping destination address or hostname\n")
2657 argv_find(argv
, argc
, "WORD", &idx
);
2658 execute_command("ping", 1, argv
[idx
]->arg
, NULL
);
2662 ALIAS(vtysh_ping
, vtysh_ping_ip_cmd
, "ping ip WORD",
2663 "Send echo messages\n"
2665 "Ping destination address or hostname\n")
2667 DEFUN (vtysh_traceroute
,
2668 vtysh_traceroute_cmd
,
2670 "Trace route to destination\n"
2671 "Trace route to destination address or hostname\n")
2675 argv_find(argv
, argc
, "WORD", &idx
);
2676 execute_command("traceroute", 1, argv
[idx
]->arg
, NULL
);
2680 ALIAS(vtysh_traceroute
, vtysh_traceroute_ip_cmd
, "traceroute ip WORD",
2681 "Trace route to destination\n"
2683 "Trace route to destination address or hostname\n")
2685 DEFUN (vtysh_mtrace
,
2688 "Multicast trace route to multicast source\n"
2689 "Multicast trace route to multicast source address\n")
2693 argv_find(argv
, argc
, "WORD", &idx
);
2694 execute_command("mtracebis", 1, argv
[idx
]->arg
, NULL
);
2701 "Send echo messages\n"
2703 "Ping destination address or hostname\n")
2705 execute_command("ping6", 1, argv
[2]->arg
, NULL
);
2709 DEFUN (vtysh_traceroute6
,
2710 vtysh_traceroute6_cmd
,
2711 "traceroute ipv6 WORD",
2712 "Trace route to destination\n"
2714 "Trace route to destination address or hostname\n")
2716 execute_command("traceroute6", 1, argv
[2]->arg
, NULL
);
2720 #if defined(HAVE_SHELL_ACCESS)
2721 DEFUN (vtysh_telnet
,
2724 "Open a telnet connection\n"
2725 "IP address or hostname of a remote system\n")
2727 execute_command("telnet", 1, argv
[1]->arg
, NULL
);
2731 DEFUN (vtysh_telnet_port
,
2732 vtysh_telnet_port_cmd
,
2734 "Open a telnet connection\n"
2735 "IP address or hostname of a remote system\n"
2736 "TCP Port number\n")
2738 execute_command("telnet", 2, argv
[1]->arg
, argv
[2]->arg
);
2745 "Open an ssh connection\n"
2748 execute_command("ssh", 1, argv
[1]->arg
, NULL
);
2752 DEFUN (vtysh_start_shell
,
2753 vtysh_start_shell_cmd
,
2755 "Start UNIX shell\n")
2757 execute_command("sh", 0, NULL
, NULL
);
2761 DEFUN (vtysh_start_bash
,
2762 vtysh_start_bash_cmd
,
2764 "Start UNIX shell\n"
2767 execute_command("bash", 0, NULL
, NULL
);
2771 DEFUN (vtysh_start_zsh
,
2772 vtysh_start_zsh_cmd
,
2774 "Start UNIX shell\n"
2777 execute_command("zsh", 0, NULL
, NULL
);
2784 "list [permutations]",
2785 "Print command list\n"
2786 "Print all possible command permutations\n")
2788 return cmd_list_cmds(vty
, argc
== 2);
2791 DEFUN (vtysh_output_file
,
2792 vtysh_output_file_cmd
,
2794 "Direct vtysh output to file\n"
2795 "Direct vtysh output to file\n"
2796 "Path to dump output to\n")
2798 const char *path
= argv
[argc
- 1]->arg
;
2799 outputfile
= fopen(path
, "a");
2801 fprintf(stdout
, "Failed to open file '%s': %s\n", path
,
2802 safe_strerror(errno
));
2803 outputfile
= stdout
;
2808 DEFUN (no_vtysh_output_file
,
2809 no_vtysh_output_file_cmd
,
2810 "no output file [FILE]",
2812 "Direct vtysh output to file\n"
2813 "Direct vtysh output to file\n"
2814 "Path to dump output to\n")
2816 if (outputfile
!= stdout
) {
2818 outputfile
= stdout
;
2826 "Find CLI command containing text\n"
2827 "Text to search for\n")
2829 char *text
= argv_concat(argv
, argc
, 1);
2830 const struct cmd_node
*node
;
2831 const struct cmd_element
*cli
;
2834 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
2835 node
= vector_slot(cmdvec
, i
);
2838 clis
= node
->cmd_vector
;
2839 for (unsigned int j
= 0; j
< vector_active(clis
); j
++) {
2840 cli
= vector_slot(clis
, j
);
2841 if (strcasestr(cli
->string
, text
))
2842 fprintf(stdout
, " (%s) %s\n",
2843 node_names
[node
->node
], cli
->string
);
2847 XFREE(MTYPE_TMP
, text
);
2852 static void vtysh_install_default(enum node_type node
)
2854 install_element(node
, &config_list_cmd
);
2855 install_element(node
, &find_cmd
);
2856 install_element(node
, &vtysh_output_file_cmd
);
2857 install_element(node
, &no_vtysh_output_file_cmd
);
2860 /* Making connection to protocol daemon. */
2861 static int vtysh_connect(struct vtysh_client
*vclient
)
2865 struct sockaddr_un addr
;
2869 if (!vclient
->path
[0])
2870 snprintf(vclient
->path
, sizeof(vclient
->path
), "%s/%s.vty",
2871 vtydir
, vclient
->name
);
2872 path
= vclient
->path
;
2874 /* Stat socket to see if we have permission to access it. */
2875 ret
= stat(path
, &s_stat
);
2876 if (ret
< 0 && errno
!= ENOENT
) {
2877 fprintf(stderr
, "vtysh_connect(%s): stat = %s\n", path
,
2878 safe_strerror(errno
));
2883 if (!S_ISSOCK(s_stat
.st_mode
)) {
2884 fprintf(stderr
, "vtysh_connect(%s): Not a socket\n",
2890 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
2893 fprintf(stderr
, "vtysh_connect(%s): socket = %s\n", path
,
2894 safe_strerror(errno
));
2899 memset(&addr
, 0, sizeof(struct sockaddr_un
));
2900 addr
.sun_family
= AF_UNIX
;
2901 strlcpy(addr
.sun_path
, path
, sizeof(addr
.sun_path
));
2902 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
2903 len
= addr
.sun_len
= SUN_LEN(&addr
);
2905 len
= sizeof(addr
.sun_family
) + strlen(addr
.sun_path
);
2906 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
2908 ret
= connect(sock
, (struct sockaddr
*)&addr
, len
);
2911 fprintf(stderr
, "vtysh_connect(%s): connect = %s\n", path
,
2912 safe_strerror(errno
));
2922 /* Return true if str ends with suffix, else return false */
2923 static int ends_with(const char *str
, const char *suffix
)
2925 if (!str
|| !suffix
)
2927 size_t lenstr
= strlen(str
);
2928 size_t lensuffix
= strlen(suffix
);
2929 if (lensuffix
> lenstr
)
2931 return strncmp(str
+ lenstr
- lensuffix
, suffix
, lensuffix
) == 0;
2934 static void vtysh_client_sorted_insert(struct vtysh_client
*head_client
,
2935 struct vtysh_client
*client
)
2937 struct vtysh_client
*prev_node
, *current_node
;
2939 prev_node
= head_client
;
2940 current_node
= head_client
->next
;
2941 while (current_node
) {
2942 if (strcmp(current_node
->path
, client
->path
) > 0)
2945 prev_node
= current_node
;
2946 current_node
= current_node
->next
;
2948 client
->next
= current_node
;
2949 prev_node
->next
= client
;
2952 #define MAXIMUM_INSTANCES 10
2954 static void vtysh_update_all_insances(struct vtysh_client
*head_client
)
2956 struct vtysh_client
*client
;
2958 struct dirent
*file
;
2961 if (head_client
->flag
!= VTYSH_OSPFD
)
2964 /* ls vty_sock_dir and look for all files ending in .vty */
2965 dir
= opendir(vtydir
);
2967 while ((file
= readdir(dir
)) != NULL
) {
2968 if (begins_with(file
->d_name
, "ospfd-")
2969 && ends_with(file
->d_name
, ".vty")) {
2970 if (n
== MAXIMUM_INSTANCES
) {
2972 "Parsing %s, client limit(%d) reached!\n",
2976 client
= (struct vtysh_client
*)malloc(
2977 sizeof(struct vtysh_client
));
2979 client
->name
= "ospfd";
2980 client
->flag
= VTYSH_OSPFD
;
2981 snprintf(client
->path
, sizeof(client
->path
),
2982 "%s/%s", vtydir
, file
->d_name
);
2983 client
->next
= NULL
;
2984 vtysh_client_sorted_insert(head_client
, client
);
2992 static int vtysh_connect_all_instances(struct vtysh_client
*head_client
)
2994 struct vtysh_client
*client
;
2997 vtysh_update_all_insances(head_client
);
2999 client
= head_client
->next
;
3001 if (vtysh_connect(client
) == 0)
3003 client
= client
->next
;
3009 int vtysh_connect_all(const char *daemon_name
)
3015 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
3017 || !strcmp(daemon_name
, vtysh_client
[i
].name
)) {
3019 if (vtysh_connect(&vtysh_client
[i
]) == 0)
3022 rc
+= vtysh_connect_all_instances(&vtysh_client
[i
]);
3026 fprintf(stderr
, "Error: no daemons match name %s!\n",
3031 /* To disable readline's filename completion. */
3032 static char *vtysh_completion_entry_function(const char *ignore
,
3038 void vtysh_readline_init(void)
3040 /* readline related settings. */
3042 rl_bind_key('?', (rl_command_func_t
*)vtysh_rl_describe
);
3043 rl_completion_entry_function
= vtysh_completion_entry_function
;
3044 rl_attempted_completion_function
=
3045 (rl_completion_func_t
*)new_completion
;
3048 char *vtysh_prompt(void)
3050 static char buf
[100];
3052 snprintf(buf
, sizeof buf
, cmd_prompt(vty
->node
), cmd_hostname_get());
3056 static void vtysh_ac_line(void *arg
, const char *line
)
3060 for (i
= 0; i
< vector_active(comps
); i
++)
3061 if (!strcmp(line
, (char *)vector_slot(comps
, i
)))
3063 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, line
));
3066 static void vtysh_autocomplete(vector comps
, struct cmd_token
*token
)
3071 snprintf(accmd
, sizeof(accmd
), "autocomplete %d %s %s", token
->type
,
3072 token
->text
, token
->varname
? token
->varname
: "-");
3074 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3075 vtysh_client_run_all(&vtysh_client
[i
], accmd
, 1, NULL
,
3076 vtysh_ac_line
, comps
);
3079 static const struct cmd_variable_handler vtysh_var_handler
[] = {
3083 .completions
= vtysh_autocomplete
},
3084 {.completions
= NULL
}};
3088 if (outputfile
!= stdout
)
3092 void vtysh_init_vty(void)
3094 /* Make vty structure. */
3096 vty
->type
= VTY_SHELL
;
3097 vty
->node
= VIEW_NODE
;
3099 /* set default output */
3100 outputfile
= stdout
;
3102 /* Initialize commands. */
3104 cmd_variable_handler_register(vtysh_var_handler
);
3106 /* Install nodes. */
3107 install_node(&bgp_node
, NULL
);
3108 install_node(&rip_node
, NULL
);
3109 install_node(&interface_node
, NULL
);
3110 install_node(&pw_node
, NULL
);
3111 install_node(&link_params_node
, NULL
);
3112 install_node(&logicalrouter_node
, NULL
);
3113 install_node(&vrf_node
, NULL
);
3114 install_node(&rmap_node
, NULL
);
3115 install_node(&zebra_node
, NULL
);
3116 install_node(&bgp_vpnv4_node
, NULL
);
3117 install_node(&bgp_vpnv6_node
, NULL
);
3118 install_node(&bgp_flowspecv4_node
, NULL
);
3119 install_node(&bgp_flowspecv6_node
, NULL
);
3120 install_node(&bgp_ipv4_node
, NULL
);
3121 install_node(&bgp_ipv4m_node
, NULL
);
3122 install_node(&bgp_ipv4l_node
, NULL
);
3123 install_node(&bgp_ipv6_node
, NULL
);
3124 install_node(&bgp_ipv6m_node
, NULL
);
3125 install_node(&bgp_ipv6l_node
, NULL
);
3126 install_node(&bgp_vrf_policy_node
, NULL
);
3127 install_node(&bgp_evpn_node
, NULL
);
3128 install_node(&bgp_evpn_vni_node
, NULL
);
3129 install_node(&bgp_vnc_defaults_node
, NULL
);
3130 install_node(&bgp_vnc_nve_group_node
, NULL
);
3131 install_node(&bgp_vnc_l2_group_node
, NULL
);
3132 install_node(&ospf_node
, NULL
);
3133 install_node(&eigrp_node
, NULL
);
3134 install_node(&babel_node
, NULL
);
3135 install_node(&ripng_node
, NULL
);
3136 install_node(&ospf6_node
, NULL
);
3137 install_node(&ldp_node
, NULL
);
3138 install_node(&ldp_ipv4_node
, NULL
);
3139 install_node(&ldp_ipv6_node
, NULL
);
3140 install_node(&ldp_ipv4_iface_node
, NULL
);
3141 install_node(&ldp_ipv6_iface_node
, NULL
);
3142 install_node(&ldp_l2vpn_node
, NULL
);
3143 install_node(&ldp_pseudowire_node
, NULL
);
3144 install_node(&keychain_node
, NULL
);
3145 install_node(&keychain_key_node
, NULL
);
3146 install_node(&isis_node
, NULL
);
3147 install_node(&vty_node
, NULL
);
3148 #if defined(HAVE_RPKI)
3149 install_node(&rpki_node
, NULL
);
3152 struct cmd_node
*node
;
3153 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
3154 node
= vector_slot(cmdvec
, i
);
3155 if (!node
|| node
->node
== VIEW_NODE
)
3157 vtysh_install_default(node
->node
);
3160 install_element(VIEW_NODE
, &vtysh_enable_cmd
);
3161 install_element(ENABLE_NODE
, &vtysh_config_terminal_cmd
);
3162 install_element(ENABLE_NODE
, &vtysh_disable_cmd
);
3164 /* "exit" command. */
3165 install_element(VIEW_NODE
, &vtysh_exit_all_cmd
);
3166 install_element(CONFIG_NODE
, &vtysh_exit_all_cmd
);
3167 install_element(VIEW_NODE
, &vtysh_quit_all_cmd
);
3168 install_element(CONFIG_NODE
, &vtysh_quit_all_cmd
);
3169 install_element(RIP_NODE
, &vtysh_exit_ripd_cmd
);
3170 install_element(RIP_NODE
, &vtysh_quit_ripd_cmd
);
3171 install_element(RIPNG_NODE
, &vtysh_exit_ripngd_cmd
);
3172 install_element(RIPNG_NODE
, &vtysh_quit_ripngd_cmd
);
3173 install_element(OSPF_NODE
, &vtysh_exit_ospfd_cmd
);
3174 install_element(OSPF_NODE
, &vtysh_quit_ospfd_cmd
);
3175 install_element(EIGRP_NODE
, &vtysh_exit_eigrpd_cmd
);
3176 install_element(EIGRP_NODE
, &vtysh_quit_eigrpd_cmd
);
3177 install_element(BABEL_NODE
, &vtysh_exit_babeld_cmd
);
3178 install_element(BABEL_NODE
, &vtysh_quit_babeld_cmd
);
3179 install_element(OSPF6_NODE
, &vtysh_exit_ospf6d_cmd
);
3180 install_element(OSPF6_NODE
, &vtysh_quit_ospf6d_cmd
);
3181 #if defined(HAVE_LDPD)
3182 install_element(LDP_NODE
, &vtysh_exit_ldpd_cmd
);
3183 install_element(LDP_NODE
, &vtysh_quit_ldpd_cmd
);
3184 install_element(LDP_IPV4_NODE
, &vtysh_exit_ldpd_cmd
);
3185 install_element(LDP_IPV4_NODE
, &vtysh_quit_ldpd_cmd
);
3186 install_element(LDP_IPV4_NODE
, &ldp_exit_address_family_cmd
);
3187 install_element(LDP_IPV6_NODE
, &vtysh_exit_ldpd_cmd
);
3188 install_element(LDP_IPV6_NODE
, &vtysh_quit_ldpd_cmd
);
3189 install_element(LDP_IPV6_NODE
, &ldp_exit_address_family_cmd
);
3190 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
3191 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
3192 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
3193 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
3194 install_element(LDP_L2VPN_NODE
, &vtysh_exit_ldpd_cmd
);
3195 install_element(LDP_L2VPN_NODE
, &vtysh_quit_ldpd_cmd
);
3196 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_exit_ldpd_cmd
);
3197 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_quit_ldpd_cmd
);
3199 install_element(BGP_NODE
, &vtysh_exit_bgpd_cmd
);
3200 install_element(BGP_NODE
, &vtysh_quit_bgpd_cmd
);
3201 install_element(BGP_VPNV4_NODE
, &vtysh_exit_bgpd_cmd
);
3202 install_element(BGP_VPNV4_NODE
, &vtysh_quit_bgpd_cmd
);
3203 install_element(BGP_VPNV6_NODE
, &vtysh_exit_bgpd_cmd
);
3204 install_element(BGP_VPNV6_NODE
, &vtysh_quit_bgpd_cmd
);
3205 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_exit_bgpd_cmd
);
3206 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_quit_bgpd_cmd
);
3207 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_exit_bgpd_cmd
);
3208 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_quit_bgpd_cmd
);
3209 install_element(BGP_IPV4_NODE
, &vtysh_exit_bgpd_cmd
);
3210 install_element(BGP_IPV4_NODE
, &vtysh_quit_bgpd_cmd
);
3211 install_element(BGP_IPV4M_NODE
, &vtysh_exit_bgpd_cmd
);
3212 install_element(BGP_IPV4M_NODE
, &vtysh_quit_bgpd_cmd
);
3213 install_element(BGP_IPV4L_NODE
, &vtysh_exit_bgpd_cmd
);
3214 install_element(BGP_IPV4L_NODE
, &vtysh_quit_bgpd_cmd
);
3215 install_element(BGP_IPV6_NODE
, &vtysh_exit_bgpd_cmd
);
3216 install_element(BGP_IPV6_NODE
, &vtysh_quit_bgpd_cmd
);
3217 install_element(BGP_IPV6M_NODE
, &vtysh_exit_bgpd_cmd
);
3218 install_element(BGP_IPV6M_NODE
, &vtysh_quit_bgpd_cmd
);
3219 install_element(BGP_EVPN_NODE
, &vtysh_quit_bgpd_cmd
);
3220 install_element(BGP_EVPN_NODE
, &vtysh_exit_bgpd_cmd
);
3221 install_element(BGP_EVPN_VNI_NODE
, &vtysh_exit_bgpd_cmd
);
3222 install_element(BGP_EVPN_VNI_NODE
, &vtysh_quit_bgpd_cmd
);
3223 install_element(BGP_IPV6L_NODE
, &vtysh_exit_bgpd_cmd
);
3224 install_element(BGP_IPV6L_NODE
, &vtysh_quit_bgpd_cmd
);
3225 #if defined(ENABLE_BGP_VNC)
3226 install_element(BGP_VRF_POLICY_NODE
, &vtysh_exit_bgpd_cmd
);
3227 install_element(BGP_VRF_POLICY_NODE
, &vtysh_quit_bgpd_cmd
);
3228 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_exit_bgpd_cmd
);
3229 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_quit_bgpd_cmd
);
3230 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
3231 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
3232 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
3233 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
3235 install_element(ISIS_NODE
, &vtysh_exit_isisd_cmd
);
3236 install_element(ISIS_NODE
, &vtysh_quit_isisd_cmd
);
3237 install_element(KEYCHAIN_NODE
, &vtysh_exit_ripd_cmd
);
3238 install_element(KEYCHAIN_NODE
, &vtysh_quit_ripd_cmd
);
3239 install_element(KEYCHAIN_KEY_NODE
, &vtysh_exit_ripd_cmd
);
3240 install_element(KEYCHAIN_KEY_NODE
, &vtysh_quit_ripd_cmd
);
3241 install_element(RMAP_NODE
, &vtysh_exit_rmap_cmd
);
3242 install_element(RMAP_NODE
, &vtysh_quit_rmap_cmd
);
3243 install_element(VTY_NODE
, &vtysh_exit_line_vty_cmd
);
3244 install_element(VTY_NODE
, &vtysh_quit_line_vty_cmd
);
3246 /* "end" command. */
3247 install_element(CONFIG_NODE
, &vtysh_end_all_cmd
);
3248 install_element(ENABLE_NODE
, &vtysh_end_all_cmd
);
3249 install_element(RIP_NODE
, &vtysh_end_all_cmd
);
3250 install_element(RIPNG_NODE
, &vtysh_end_all_cmd
);
3251 install_element(OSPF_NODE
, &vtysh_end_all_cmd
);
3252 install_element(EIGRP_NODE
, &vtysh_end_all_cmd
);
3253 install_element(BABEL_NODE
, &vtysh_end_all_cmd
);
3254 install_element(OSPF6_NODE
, &vtysh_end_all_cmd
);
3255 install_element(LDP_NODE
, &vtysh_end_all_cmd
);
3256 install_element(LDP_IPV4_NODE
, &vtysh_end_all_cmd
);
3257 install_element(LDP_IPV6_NODE
, &vtysh_end_all_cmd
);
3258 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_end_all_cmd
);
3259 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_end_all_cmd
);
3260 install_element(LDP_L2VPN_NODE
, &vtysh_end_all_cmd
);
3261 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_end_all_cmd
);
3262 install_element(BGP_NODE
, &vtysh_end_all_cmd
);
3263 install_element(BGP_IPV4_NODE
, &vtysh_end_all_cmd
);
3264 install_element(BGP_IPV4M_NODE
, &vtysh_end_all_cmd
);
3265 install_element(BGP_IPV4L_NODE
, &vtysh_end_all_cmd
);
3266 install_element(BGP_VPNV4_NODE
, &vtysh_end_all_cmd
);
3267 install_element(BGP_VPNV6_NODE
, &vtysh_end_all_cmd
);
3268 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_end_all_cmd
);
3269 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_end_all_cmd
);
3270 install_element(BGP_IPV6_NODE
, &vtysh_end_all_cmd
);
3271 install_element(BGP_IPV6M_NODE
, &vtysh_end_all_cmd
);
3272 install_element(BGP_IPV6L_NODE
, &vtysh_end_all_cmd
);
3273 install_element(BGP_VRF_POLICY_NODE
, &vtysh_end_all_cmd
);
3274 install_element(BGP_EVPN_NODE
, &vtysh_end_all_cmd
);
3275 install_element(BGP_EVPN_VNI_NODE
, &vtysh_end_all_cmd
);
3276 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_end_all_cmd
);
3277 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_end_all_cmd
);
3278 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_end_all_cmd
);
3279 install_element(ISIS_NODE
, &vtysh_end_all_cmd
);
3280 install_element(KEYCHAIN_NODE
, &vtysh_end_all_cmd
);
3281 install_element(KEYCHAIN_KEY_NODE
, &vtysh_end_all_cmd
);
3282 install_element(RMAP_NODE
, &vtysh_end_all_cmd
);
3283 install_element(VTY_NODE
, &vtysh_end_all_cmd
);
3285 install_element(INTERFACE_NODE
, &vtysh_interface_desc_cmd
);
3286 install_element(INTERFACE_NODE
, &vtysh_no_interface_desc_cmd
);
3287 install_element(INTERFACE_NODE
, &vtysh_end_all_cmd
);
3288 install_element(INTERFACE_NODE
, &vtysh_exit_interface_cmd
);
3289 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);
3290 install_element(LINK_PARAMS_NODE
, &vtysh_end_all_cmd
);
3291 install_element(LINK_PARAMS_NODE
, &vtysh_exit_interface_cmd
);
3292 install_element(INTERFACE_NODE
, &vtysh_quit_interface_cmd
);
3294 install_element(PW_NODE
, &vtysh_end_all_cmd
);
3295 install_element(PW_NODE
, &vtysh_exit_interface_cmd
);
3296 install_element(PW_NODE
, &vtysh_quit_interface_cmd
);
3298 install_element(LOGICALROUTER_NODE
, &vtysh_end_all_cmd
);
3300 install_element(CONFIG_NODE
, &vtysh_logicalrouter_cmd
);
3301 install_element(CONFIG_NODE
, &vtysh_no_logicalrouter_cmd
);
3302 install_element(LOGICALROUTER_NODE
, &vtysh_exit_logicalrouter_cmd
);
3303 install_element(LOGICALROUTER_NODE
, &vtysh_quit_logicalrouter_cmd
);
3305 install_element(VRF_NODE
, &vtysh_end_all_cmd
);
3306 install_element(VRF_NODE
, &vtysh_exit_vrf_cmd
);
3307 install_element(VRF_NODE
, &vtysh_quit_vrf_cmd
);
3309 install_element(CONFIG_NODE
, &router_eigrp_cmd
);
3310 install_element(CONFIG_NODE
, &router_babel_cmd
);
3311 install_element(CONFIG_NODE
, &router_rip_cmd
);
3312 install_element(CONFIG_NODE
, &router_ripng_cmd
);
3313 install_element(CONFIG_NODE
, &router_ospf_cmd
);
3314 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
3315 #if defined(HAVE_LDPD)
3316 install_element(CONFIG_NODE
, &ldp_mpls_ldp_cmd
);
3317 install_element(LDP_NODE
, &ldp_address_family_ipv4_cmd
);
3318 install_element(LDP_NODE
, &ldp_address_family_ipv6_cmd
);
3319 install_element(LDP_IPV4_NODE
, &ldp_interface_ifname_cmd
);
3320 install_element(LDP_IPV6_NODE
, &ldp_interface_ifname_cmd
);
3321 install_element(CONFIG_NODE
, &ldp_l2vpn_word_type_vpls_cmd
);
3322 install_element(LDP_L2VPN_NODE
, &ldp_member_pseudowire_ifname_cmd
);
3324 install_element(CONFIG_NODE
, &router_isis_cmd
);
3325 install_element(CONFIG_NODE
, &router_bgp_cmd
);
3326 install_element(BGP_NODE
, &address_family_vpnv4_cmd
);
3327 install_element(BGP_NODE
, &address_family_vpnv6_cmd
);
3328 #if defined(ENABLE_BGP_VNC)
3329 install_element(BGP_NODE
, &vnc_vrf_policy_cmd
);
3330 install_element(BGP_NODE
, &vnc_defaults_cmd
);
3331 install_element(BGP_NODE
, &vnc_nve_group_cmd
);
3332 install_element(BGP_NODE
, &vnc_l2_group_cmd
);
3334 install_element(BGP_NODE
, &address_family_ipv4_cmd
);
3335 install_element(BGP_NODE
, &address_family_ipv4_multicast_cmd
);
3336 install_element(BGP_NODE
, &address_family_ipv4_vpn_cmd
);
3337 install_element(BGP_NODE
, &address_family_ipv4_labeled_unicast_cmd
);
3338 install_element(BGP_NODE
, &address_family_ipv6_cmd
);
3339 install_element(BGP_NODE
, &address_family_ipv6_multicast_cmd
);
3340 install_element(BGP_NODE
, &address_family_ipv6_vpn_cmd
);
3341 install_element(BGP_NODE
, &address_family_ipv6_labeled_unicast_cmd
);
3342 install_element(BGP_NODE
, &address_family_evpn_cmd
);
3343 install_element(BGP_NODE
, &address_family_flowspecv4_cmd
);
3344 install_element(BGP_NODE
, &address_family_flowspecv6_cmd
);
3345 #if defined(HAVE_CUMULUS)
3346 install_element(BGP_NODE
, &address_family_evpn2_cmd
);
3348 install_element(BGP_VPNV4_NODE
, &exit_address_family_cmd
);
3349 install_element(BGP_VPNV6_NODE
, &exit_address_family_cmd
);
3350 install_element(BGP_IPV4_NODE
, &exit_address_family_cmd
);
3351 install_element(BGP_IPV4M_NODE
, &exit_address_family_cmd
);
3352 install_element(BGP_IPV4L_NODE
, &exit_address_family_cmd
);
3353 install_element(BGP_IPV6_NODE
, &exit_address_family_cmd
);
3354 install_element(BGP_IPV6M_NODE
, &exit_address_family_cmd
);
3355 install_element(BGP_EVPN_NODE
, &exit_address_family_cmd
);
3356 install_element(BGP_IPV6L_NODE
, &exit_address_family_cmd
);
3357 install_element(BGP_FLOWSPECV4_NODE
, &exit_address_family_cmd
);
3358 install_element(BGP_FLOWSPECV6_NODE
, &exit_address_family_cmd
);
3360 #if defined(HAVE_RPKI)
3361 install_element(CONFIG_NODE
, &rpki_cmd
);
3362 install_element(RPKI_NODE
, &rpki_exit_cmd
);
3363 install_element(RPKI_NODE
, &rpki_quit_cmd
);
3364 install_element(RPKI_NODE
, &vtysh_end_all_cmd
);
3368 install_element(BGP_EVPN_NODE
, &bgp_evpn_vni_cmd
);
3369 install_element(BGP_EVPN_VNI_NODE
, &exit_vni_cmd
);
3371 install_element(BGP_VRF_POLICY_NODE
, &exit_vrf_policy_cmd
);
3372 install_element(BGP_VNC_DEFAULTS_NODE
, &exit_vnc_config_cmd
);
3373 install_element(BGP_VNC_NVE_GROUP_NODE
, &exit_vnc_config_cmd
);
3374 install_element(BGP_VNC_L2_GROUP_NODE
, &exit_vnc_config_cmd
);
3376 install_element(CONFIG_NODE
, &key_chain_cmd
);
3377 install_element(CONFIG_NODE
, &vtysh_route_map_cmd
);
3378 install_element(CONFIG_NODE
, &vtysh_line_vty_cmd
);
3379 install_element(KEYCHAIN_NODE
, &key_cmd
);
3380 install_element(KEYCHAIN_NODE
, &key_chain_cmd
);
3381 install_element(KEYCHAIN_KEY_NODE
, &key_chain_cmd
);
3382 install_element(CONFIG_NODE
, &vtysh_interface_cmd
);
3383 install_element(CONFIG_NODE
, &vtysh_no_interface_cmd
);
3384 install_element(CONFIG_NODE
, &vtysh_no_interface_vrf_cmd
);
3385 install_element(CONFIG_NODE
, &vtysh_pseudowire_cmd
);
3386 install_element(INTERFACE_NODE
, &vtysh_link_params_cmd
);
3387 install_element(ENABLE_NODE
, &vtysh_show_running_config_cmd
);
3388 install_element(ENABLE_NODE
, &vtysh_copy_running_config_cmd
);
3390 install_element(CONFIG_NODE
, &vtysh_vrf_cmd
);
3391 install_element(CONFIG_NODE
, &vtysh_no_vrf_cmd
);
3393 /* "write terminal" command. */
3394 install_element(ENABLE_NODE
, &vtysh_write_terminal_cmd
);
3396 install_element(CONFIG_NODE
, &vtysh_integrated_config_cmd
);
3397 install_element(CONFIG_NODE
, &no_vtysh_integrated_config_cmd
);
3399 /* "write memory" command. */
3400 install_element(ENABLE_NODE
, &vtysh_write_memory_cmd
);
3402 install_element(VIEW_NODE
, &vtysh_terminal_length_cmd
);
3403 install_element(VIEW_NODE
, &vtysh_terminal_no_length_cmd
);
3404 install_element(VIEW_NODE
, &vtysh_show_daemons_cmd
);
3406 install_element(VIEW_NODE
, &vtysh_ping_cmd
);
3407 install_element(VIEW_NODE
, &vtysh_ping_ip_cmd
);
3408 install_element(VIEW_NODE
, &vtysh_traceroute_cmd
);
3409 install_element(VIEW_NODE
, &vtysh_traceroute_ip_cmd
);
3410 install_element(VIEW_NODE
, &vtysh_mtrace_cmd
);
3411 install_element(VIEW_NODE
, &vtysh_ping6_cmd
);
3412 install_element(VIEW_NODE
, &vtysh_traceroute6_cmd
);
3413 #if defined(HAVE_SHELL_ACCESS)
3414 install_element(VIEW_NODE
, &vtysh_telnet_cmd
);
3415 install_element(VIEW_NODE
, &vtysh_telnet_port_cmd
);
3416 install_element(VIEW_NODE
, &vtysh_ssh_cmd
);
3418 #if defined(HAVE_SHELL_ACCESS)
3419 install_element(ENABLE_NODE
, &vtysh_start_shell_cmd
);
3420 install_element(ENABLE_NODE
, &vtysh_start_bash_cmd
);
3421 install_element(ENABLE_NODE
, &vtysh_start_zsh_cmd
);
3425 install_element(VIEW_NODE
, &vtysh_show_debugging_cmd
);
3426 install_element(VIEW_NODE
, &vtysh_show_debugging_hashtable_cmd
);
3427 install_element(ENABLE_NODE
, &vtysh_debug_all_cmd
);
3428 install_element(CONFIG_NODE
, &vtysh_debug_all_cmd
);
3430 /* misc lib show commands */
3431 install_element(VIEW_NODE
, &vtysh_show_memory_cmd
);
3432 install_element(VIEW_NODE
, &vtysh_show_modules_cmd
);
3433 install_element(VIEW_NODE
, &vtysh_show_work_queues_cmd
);
3434 install_element(VIEW_NODE
, &vtysh_show_work_queues_daemon_cmd
);
3435 install_element(VIEW_NODE
, &vtysh_show_thread_cmd
);
3438 install_element(VIEW_NODE
, &vtysh_show_logging_cmd
);
3439 install_element(CONFIG_NODE
, &vtysh_log_stdout_cmd
);
3440 install_element(CONFIG_NODE
, &vtysh_log_stdout_level_cmd
);
3441 install_element(CONFIG_NODE
, &no_vtysh_log_stdout_cmd
);
3442 install_element(CONFIG_NODE
, &vtysh_log_file_cmd
);
3443 install_element(CONFIG_NODE
, &vtysh_log_file_level_cmd
);
3444 install_element(CONFIG_NODE
, &no_vtysh_log_file_cmd
);
3445 install_element(CONFIG_NODE
, &vtysh_log_monitor_cmd
);
3446 install_element(CONFIG_NODE
, &no_vtysh_log_monitor_cmd
);
3447 install_element(CONFIG_NODE
, &vtysh_log_syslog_cmd
);
3448 install_element(CONFIG_NODE
, &no_vtysh_log_syslog_cmd
);
3449 install_element(CONFIG_NODE
, &vtysh_log_trap_cmd
);
3450 install_element(CONFIG_NODE
, &no_vtysh_log_trap_cmd
);
3451 install_element(CONFIG_NODE
, &vtysh_log_facility_cmd
);
3452 install_element(CONFIG_NODE
, &no_vtysh_log_facility_cmd
);
3453 install_element(CONFIG_NODE
, &vtysh_log_record_priority_cmd
);
3454 install_element(CONFIG_NODE
, &no_vtysh_log_record_priority_cmd
);
3455 install_element(CONFIG_NODE
, &vtysh_log_timestamp_precision_cmd
);
3456 install_element(CONFIG_NODE
, &no_vtysh_log_timestamp_precision_cmd
);
3458 install_element(CONFIG_NODE
, &vtysh_service_password_encrypt_cmd
);
3459 install_element(CONFIG_NODE
, &no_vtysh_service_password_encrypt_cmd
);
3461 install_element(CONFIG_NODE
, &vtysh_password_cmd
);
3462 install_element(CONFIG_NODE
, &vtysh_enable_password_cmd
);
3463 install_element(CONFIG_NODE
, &no_vtysh_enable_password_cmd
);