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_IPV4M_NODE
343 || saved_node
== BGP_IPV4L_NODE
344 || saved_node
== BGP_IPV6L_NODE
345 || saved_node
== BGP_IPV6M_NODE
346 || saved_node
== BGP_EVPN_NODE
347 || saved_node
== LDP_IPV4_NODE
348 || saved_node
== LDP_IPV6_NODE
)
350 vtysh_execute("exit-address-family");
351 } else if ((saved_node
== BGP_EVPN_VNI_NODE
) && (tried
== 1)) {
352 vtysh_execute("exit-vni");
353 } else if (saved_node
== BGP_VRF_POLICY_NODE
&& (tried
== 1)) {
354 vtysh_execute("exit-vrf-policy");
355 } else if ((saved_node
== BGP_VNC_DEFAULTS_NODE
356 || saved_node
== BGP_VNC_NVE_GROUP_NODE
357 || saved_node
== BGP_VNC_L2_GROUP_NODE
)
359 vtysh_execute("exit-vnc");
360 } else if ((saved_node
== KEYCHAIN_KEY_NODE
361 || saved_node
== LDP_PSEUDOWIRE_NODE
362 || saved_node
== LDP_IPV4_IFACE_NODE
363 || saved_node
== LDP_IPV6_IFACE_NODE
)
365 vtysh_execute("exit");
367 vtysh_execute("end");
368 vtysh_execute("configure terminal");
371 /* If command didn't succeed in any node, continue with return value
378 cmd_free_strvec(vline
);
383 case CMD_WARNING_CONFIG_FAILED
:
384 if (vty
->type
== VTY_FILE
)
385 fprintf(stdout
, "Warning...\n");
387 case CMD_ERR_AMBIGUOUS
:
388 fprintf(stdout
, "%% Ambiguous command.\n");
390 case CMD_ERR_NO_MATCH
:
391 fprintf(stdout
, "%% Unknown command.\n");
393 case CMD_ERR_INCOMPLETE
:
394 fprintf(stdout
, "%% Command incomplete.\n");
396 case CMD_SUCCESS_DAEMON
: {
398 * FIXME: Don't open pager for exit commands. popen() causes
399 * problems if exited from vtysh at all. This hack shouldn't
400 * cause any problem but is really ugly.
403 if (pager
&& vtysh_pager_name
&& outputfile
== stdout
404 && (strncmp(line
, "exit", 4) != 0)) {
405 fp
= popen(vtysh_pager_name
, "w");
407 perror("popen failed for pager");
413 if (!strcmp(cmd
->string
, "configure terminal")) {
414 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
415 cmd_stat
= vtysh_client_execute(
416 &vtysh_client
[i
], line
, fp
);
417 if (cmd_stat
== CMD_WARNING
)
423 vline
= cmd_make_strvec(line
);
426 if (pager
&& vtysh_pager_name
&& fp
427 && fp
!= outputfile
&& closepager
) {
428 if (pclose(fp
) == -1) {
429 perror("pclose failed for pager");
436 ret
= cmd_execute_command(vline
, vty
, &cmd
, 1);
437 cmd_free_strvec(vline
);
438 if (ret
!= CMD_SUCCESS_DAEMON
)
440 } else if (cmd
->func
) {
441 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
446 cmd_stat
= CMD_SUCCESS
;
447 struct vtysh_client
*vc
;
448 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
449 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
450 if (vtysh_client
[i
].fd
< 0
451 && (cmd
->daemon
== vtysh_client
[i
].flag
)) {
452 bool any_inst
= false;
453 for (vc
= &vtysh_client
[i
]; vc
;
459 "%s is not running\n",
460 vtysh_client
[i
].name
);
464 cmd_stat
= vtysh_client_execute(
465 &vtysh_client
[i
], line
, fp
);
466 if (cmd_stat
!= CMD_SUCCESS
)
470 if (cmd_stat
!= CMD_SUCCESS
)
474 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
477 if (pager
&& vtysh_pager_name
&& fp
&& closepager
&& fp
!= outputfile
) {
478 if (pclose(fp
) == -1) {
479 perror("pclose failed for pager");
486 int vtysh_execute_no_pager(const char *line
)
488 return vtysh_execute_func(line
, 0);
491 int vtysh_execute(const char *line
)
493 return vtysh_execute_func(line
, 1);
496 static char *trim(char *s
)
507 while (end
>= s
&& isspace((int)*end
))
511 while (*s
&& isspace((int)*s
))
517 int vtysh_mark_file(const char *filename
)
524 const struct cmd_element
*cmd
;
525 int saved_ret
, prev_node
;
527 char *vty_buf_copy
= NULL
;
528 char *vty_buf_trimmed
= NULL
;
530 if (strncmp("-", filename
, 1) == 0)
533 confp
= fopen(filename
, "r");
536 fprintf(stderr
, "%% Can't open config file %s due to '%s'.\n",
537 filename
, safe_strerror(errno
));
538 return (CMD_ERR_NO_FILE
);
542 vty
->wfd
= STDERR_FILENO
;
543 vty
->type
= VTY_TERM
;
544 vty
->node
= CONFIG_NODE
;
546 vtysh_execute_no_pager("enable");
547 vtysh_execute_no_pager("configure terminal");
548 vty_buf_copy
= XCALLOC(MTYPE_VTYSH_CMD
, VTY_BUFSIZ
);
550 while (fgets(vty
->buf
, VTY_BUFSIZ
, confp
)) {
553 strcpy(vty_buf_copy
, vty
->buf
);
554 vty_buf_trimmed
= trim(vty_buf_copy
);
557 case LDP_IPV4_IFACE_NODE
:
558 if (strncmp(vty_buf_copy
, " ", 3)) {
559 fprintf(outputfile
, " end\n");
560 vty
->node
= LDP_IPV4_NODE
;
563 case LDP_IPV6_IFACE_NODE
:
564 if (strncmp(vty_buf_copy
, " ", 3)) {
565 fprintf(outputfile
, " end\n");
566 vty
->node
= LDP_IPV6_NODE
;
569 case LDP_PSEUDOWIRE_NODE
:
570 if (strncmp(vty_buf_copy
, " ", 2)) {
571 fprintf(outputfile
, " end\n");
572 vty
->node
= LDP_L2VPN_NODE
;
579 if (vty_buf_trimmed
[0] == '!' || vty_buf_trimmed
[0] == '#') {
580 fprintf(outputfile
, "%s", vty
->buf
);
584 /* Split readline string up into the vector. */
585 vline
= cmd_make_strvec(vty
->buf
);
588 fprintf(outputfile
, "%s", vty
->buf
);
592 /* Ignore the "end" lines, we will generate these where
594 if (strlen(vty_buf_trimmed
) == 3
595 && strncmp("end", vty_buf_trimmed
, 3) == 0) {
596 cmd_free_strvec(vline
);
600 prev_node
= vty
->node
;
601 saved_ret
= ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
603 /* If command doesn't succeeded in current node, try to walk up
605 * Changing vty->node is enough to try it just out without
608 while (ret
!= CMD_SUCCESS
&& ret
!= CMD_SUCCESS_DAEMON
609 && ret
!= CMD_WARNING
&& ret
!= CMD_WARNING_CONFIG_FAILED
610 && vty
->node
> CONFIG_NODE
) {
611 vty
->node
= node_parent(vty
->node
);
612 ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
616 /* If command succeeded in any other node than current (tried >
618 * to move into node in the vtysh where it succeeded. */
619 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
620 || ret
== CMD_WARNING
) {
621 if ((prev_node
== BGP_VPNV4_NODE
622 || prev_node
== BGP_VPNV6_NODE
623 || prev_node
== BGP_IPV4_NODE
624 || prev_node
== BGP_IPV6_NODE
625 || prev_node
== BGP_IPV4L_NODE
626 || prev_node
== BGP_IPV6L_NODE
627 || prev_node
== BGP_IPV4M_NODE
628 || prev_node
== BGP_IPV6M_NODE
629 || prev_node
== BGP_EVPN_NODE
)
631 fprintf(outputfile
, "exit-address-family\n");
632 } else if ((prev_node
== BGP_EVPN_VNI_NODE
)
634 fprintf(outputfile
, "exit-vni\n");
635 } else if ((prev_node
== KEYCHAIN_KEY_NODE
)
637 fprintf(outputfile
, "exit\n");
639 fprintf(outputfile
, "end\n");
642 /* If command didn't succeed in any node, continue with return
647 vty
->node
= prev_node
;
650 cmd_free_strvec(vline
);
653 case CMD_WARNING_CONFIG_FAILED
:
654 if (vty
->type
== VTY_FILE
)
655 fprintf(stderr
, "line %d: Warning...: %s\n",
659 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
661 case CMD_ERR_AMBIGUOUS
:
662 fprintf(stderr
, "line %d: %% Ambiguous command: %s\n",
666 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
667 return CMD_ERR_AMBIGUOUS
;
668 case CMD_ERR_NO_MATCH
:
669 fprintf(stderr
, "line %d: %% Unknown command: %s\n",
673 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
674 return CMD_ERR_NO_MATCH
;
675 case CMD_ERR_INCOMPLETE
:
676 fprintf(stderr
, "line %d: %% Command incomplete: %s\n",
680 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
681 return CMD_ERR_INCOMPLETE
;
683 fprintf(stdout
, "%s", vty
->buf
);
685 case CMD_SUCCESS_DAEMON
: {
687 int cmd_stat
= CMD_SUCCESS
;
689 fprintf(outputfile
, "%s", vty
->buf
);
690 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
691 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
692 cmd_stat
= vtysh_client_execute(
693 &vtysh_client
[i
], vty
->buf
,
695 if (cmd_stat
!= CMD_SUCCESS
)
699 if (cmd_stat
!= CMD_SUCCESS
)
703 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
707 /* This is the end */
708 fprintf(outputfile
, "\nend\n");
710 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
718 /* Configration make from file. */
719 int vtysh_config_from_file(struct vty
*vty
, FILE *fp
)
722 const struct cmd_element
*cmd
;
724 int retcode
= CMD_SUCCESS
;
726 while (fgets(vty
->buf
, VTY_BUFSIZ
, fp
)) {
729 ret
= command_config_read_one_line(vty
, &cmd
, 1);
733 case CMD_WARNING_CONFIG_FAILED
:
734 if (vty
->type
== VTY_FILE
)
735 fprintf(stderr
, "line %d: Warning[%d]...: %s\n",
736 lineno
, vty
->node
, vty
->buf
);
737 retcode
= ret
; /* once we have an error, we remember &
740 case CMD_ERR_AMBIGUOUS
:
742 "line %d: %% Ambiguous command[%d]: %s\n",
743 lineno
, vty
->node
, vty
->buf
);
744 retcode
= CMD_ERR_AMBIGUOUS
; /* once we have an error,
748 case CMD_ERR_NO_MATCH
:
749 fprintf(stderr
, "line %d: %% Unknown command[%d]: %s",
750 lineno
, vty
->node
, vty
->buf
);
751 retcode
= CMD_ERR_NO_MATCH
; /* once we have an error, we
752 remember & return that */
754 case CMD_ERR_INCOMPLETE
:
756 "line %d: %% Command incomplete[%d]: %s\n",
757 lineno
, vty
->node
, vty
->buf
);
758 retcode
= CMD_ERR_INCOMPLETE
; /* once we have an error,
762 case CMD_SUCCESS_DAEMON
: {
764 int cmd_stat
= CMD_SUCCESS
;
766 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
767 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
768 cmd_stat
= vtysh_client_execute(
769 &vtysh_client
[i
], vty
->buf
,
772 * CMD_WARNING - Can mean that the
774 * parsed successfully but it was
776 * in a few spots. As such if we
778 * CMD_WARNING from a daemon we
780 * talking to the other daemons for the
784 if (cmd_stat
!= CMD_SUCCESS
785 && cmd_stat
!= CMD_WARNING
) {
787 "line %d: Failure to communicate[%d] to %s, line: %s\n",
789 vtysh_client
[i
].name
,
796 if (cmd_stat
!= CMD_SUCCESS
)
800 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
808 /* We don't care about the point of the cursor when '?' is typed. */
809 static int vtysh_rl_describe(void)
816 struct cmd_token
*token
;
818 vline
= cmd_make_strvec(rl_line_buffer
);
820 /* In case of '> ?'. */
822 vline
= vector_init(1);
823 vector_set(vline
, NULL
);
824 } else if (rl_end
&& isspace((int)rl_line_buffer
[rl_end
- 1]))
825 vector_set(vline
, NULL
);
827 fprintf(stdout
, "\n");
829 describe
= cmd_describe_command(vline
, vty
, &ret
);
831 /* Ambiguous and no match error. */
833 case CMD_ERR_AMBIGUOUS
:
834 cmd_free_strvec(vline
);
835 vector_free(describe
);
836 fprintf(stdout
, "%% Ambiguous command.\n");
840 case CMD_ERR_NO_MATCH
:
841 cmd_free_strvec(vline
);
843 vector_free(describe
);
844 fprintf(stdout
, "%% There is no matched command.\n");
850 /* Get width of command string. */
852 for (i
= 0; i
< vector_active(describe
); i
++)
853 if ((token
= vector_slot(describe
, i
)) != NULL
) {
854 if (token
->text
[0] == '\0')
857 int len
= strlen(token
->text
);
863 for (i
= 0; i
< vector_active(describe
); i
++)
864 if ((token
= vector_slot(describe
, i
)) != NULL
) {
866 fprintf(stdout
, " %-s\n", token
->text
);
868 fprintf(stdout
, " %-*s %s\n", width
,
869 token
->text
, token
->desc
);
871 if (IS_VARYING_TOKEN(token
->type
)) {
872 const char *ref
= vector_slot(
873 vline
, vector_active(vline
) - 1);
875 vector varcomps
= vector_init(VECTOR_MIN_SIZE
);
876 cmd_variable_complete(token
, ref
, varcomps
);
878 if (vector_active(varcomps
) > 0) {
880 rl_get_screen_size(&rows
, &cols
);
882 char *ac
= cmd_variable_comp2str(
884 fprintf(stdout
, "%s\n", ac
);
885 XFREE(MTYPE_TMP
, ac
);
888 vector_free(varcomps
);
892 cmd_free_strvec(vline
);
893 vector_free(describe
);
900 /* Result of cmd_complete_command() call will be stored here
901 * and used in new_completion() in order to put the space in
902 * correct places only. */
905 static char *command_generator(const char *text
, int state
)
908 static char **matched
= NULL
;
909 static int index
= 0;
915 if (vty
->node
== AUTH_NODE
|| vty
->node
== AUTH_ENABLE_NODE
)
918 vline
= cmd_make_strvec(rl_line_buffer
);
922 if (rl_end
&& isspace((int)rl_line_buffer
[rl_end
- 1]))
923 vector_set(vline
, NULL
);
925 matched
= cmd_complete_command(vline
, vty
, &complete_status
);
926 cmd_free_strvec(vline
);
929 if (matched
&& matched
[index
])
930 /* this is free()'d by readline, but we leak 1 count of
931 * MTYPE_COMPLETION */
932 return matched
[index
++];
934 XFREE(MTYPE_TMP
, matched
);
940 static char **new_completion(char *text
, int start
, int end
)
944 matches
= rl_completion_matches(text
, command_generator
);
948 if (complete_status
!= CMD_COMPLETE_FULL_MATCH
)
949 /* only append a space on full match */
950 rl_completion_append_character
= '\0';
956 /* Vty node structures. */
957 static struct cmd_node bgp_node
= {
958 BGP_NODE
, "%s(config-router)# ",
961 static struct cmd_node rip_node
= {
962 RIP_NODE
, "%s(config-router)# ",
965 static struct cmd_node isis_node
= {
966 ISIS_NODE
, "%s(config-router)# ",
969 static struct cmd_node interface_node
= {
970 INTERFACE_NODE
, "%s(config-if)# ",
973 static struct cmd_node pw_node
= {
974 PW_NODE
, "%s(config-pw)# ",
977 static struct cmd_node logicalrouter_node
= {
978 LOGICALROUTER_NODE
, "%s(config-logical-router)# ",
981 static struct cmd_node vrf_node
= {
982 VRF_NODE
, "%s(config-vrf)# ",
985 static struct cmd_node rmap_node
= {RMAP_NODE
, "%s(config-route-map)# "};
987 static struct cmd_node zebra_node
= {ZEBRA_NODE
, "%s(config-router)# "};
989 static struct cmd_node bgp_vpnv4_node
= {BGP_VPNV4_NODE
,
990 "%s(config-router-af)# "};
992 static struct cmd_node bgp_vpnv6_node
= {BGP_VPNV6_NODE
,
993 "%s(config-router-af)# "};
995 static struct cmd_node bgp_ipv4_node
= {BGP_IPV4_NODE
,
996 "%s(config-router-af)# "};
998 static struct cmd_node bgp_ipv4m_node
= {BGP_IPV4M_NODE
,
999 "%s(config-router-af)# "};
1001 static struct cmd_node bgp_ipv4l_node
= {BGP_IPV4L_NODE
,
1002 "%s(config-router-af)# "};
1004 static struct cmd_node bgp_ipv6_node
= {BGP_IPV6_NODE
,
1005 "%s(config-router-af)# "};
1007 static struct cmd_node bgp_ipv6m_node
= {BGP_IPV6M_NODE
,
1008 "%s(config-router-af)# "};
1010 static struct cmd_node bgp_evpn_node
= {BGP_EVPN_NODE
,
1011 "%s(config-router-af)# "};
1013 static struct cmd_node bgp_evpn_vni_node
= {BGP_EVPN_VNI_NODE
,
1014 "%s(config-router-af-vni)# "};
1016 static struct cmd_node bgp_ipv6l_node
= {BGP_IPV6L_NODE
,
1017 "%s(config-router-af)# "};
1019 static struct cmd_node bgp_vnc_defaults_node
= {
1020 BGP_VNC_DEFAULTS_NODE
, "%s(config-router-vnc-defaults)# "};
1022 static struct cmd_node bgp_vnc_nve_group_node
= {
1023 BGP_VNC_NVE_GROUP_NODE
, "%s(config-router-vnc-nve-group)# "};
1025 static struct cmd_node bgp_vrf_policy_node
= {BGP_VRF_POLICY_NODE
,
1026 "%s(config-router-vrf-policy)# "};
1028 static struct cmd_node bgp_vnc_l2_group_node
= {
1029 BGP_VNC_L2_GROUP_NODE
, "%s(config-router-vnc-l2-group)# "};
1031 static struct cmd_node ospf_node
= {OSPF_NODE
, "%s(config-router)# "};
1033 static struct cmd_node eigrp_node
= {EIGRP_NODE
, "%s(config-router)# "};
1035 static struct cmd_node babel_node
= {BABEL_NODE
, "%s(config-router)# "};
1037 static struct cmd_node ripng_node
= {RIPNG_NODE
, "%s(config-router)# "};
1039 static struct cmd_node ospf6_node
= {OSPF6_NODE
, "%s(config-ospf6)# "};
1041 static struct cmd_node ldp_node
= {LDP_NODE
, "%s(config-ldp)# "};
1043 static struct cmd_node ldp_ipv4_node
= {LDP_IPV4_NODE
, "%s(config-ldp-af)# "};
1045 static struct cmd_node ldp_ipv6_node
= {LDP_IPV6_NODE
, "%s(config-ldp-af)# "};
1047 static struct cmd_node ldp_ipv4_iface_node
= {LDP_IPV4_IFACE_NODE
,
1048 "%s(config-ldp-af-if)# "};
1050 static struct cmd_node ldp_ipv6_iface_node
= {LDP_IPV6_IFACE_NODE
,
1051 "%s(config-ldp-af-if)# "};
1053 static struct cmd_node ldp_l2vpn_node
= {LDP_L2VPN_NODE
, "%s(config-l2vpn)# "};
1055 static struct cmd_node ldp_pseudowire_node
= {LDP_PSEUDOWIRE_NODE
,
1056 "%s(config-l2vpn-pw)# "};
1058 static struct cmd_node keychain_node
= {KEYCHAIN_NODE
, "%s(config-keychain)# "};
1060 static struct cmd_node keychain_key_node
= {KEYCHAIN_KEY_NODE
,
1061 "%s(config-keychain-key)# "};
1063 struct cmd_node link_params_node
= {
1064 LINK_PARAMS_NODE
, "%s(config-link-params)# ",
1067 #if defined(HAVE_RPKI)
1068 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
1071 /* Defined in lib/vty.c */
1072 extern struct cmd_node vty_node
;
1074 /* When '^Z' is received from vty, move down to the enable mode. */
1075 static int vtysh_end(void)
1077 switch (vty
->node
) {
1080 /* Nothing to do. */
1083 vty
->node
= ENABLE_NODE
;
1089 DEFUNSH(VTYSH_REALLYALL
, vtysh_end_all
, vtysh_end_all_cmd
, "end",
1090 "End current mode and change to enable mode\n")
1095 DEFUNSH(VTYSH_BGPD
, router_bgp
, router_bgp_cmd
,
1096 "router bgp [(1-4294967295) [<view|vrf> WORD]]",
1097 ROUTER_STR BGP_STR AS_STR
1098 "BGP view\nBGP VRF\n"
1101 vty
->node
= BGP_NODE
;
1105 DEFUNSH(VTYSH_BGPD
, address_family_vpnv4
, address_family_vpnv4_cmd
,
1106 "address-family vpnv4 [unicast]",
1107 "Enter Address Family command mode\n"
1109 "Address Family modifier\n")
1111 vty
->node
= BGP_VPNV4_NODE
;
1115 DEFUNSH(VTYSH_BGPD
, address_family_vpnv6
, address_family_vpnv6_cmd
,
1116 "address-family vpnv6 [unicast]",
1117 "Enter Address Family command mode\n"
1119 "Address Family modifier\n")
1121 vty
->node
= BGP_VPNV6_NODE
;
1125 DEFUNSH(VTYSH_BGPD
, address_family_ipv4
, address_family_ipv4_cmd
,
1126 "address-family ipv4 [unicast]",
1127 "Enter Address Family command mode\n"
1129 "Address Family Modifier\n")
1131 vty
->node
= BGP_IPV4_NODE
;
1135 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_multicast
,
1136 address_family_ipv4_multicast_cmd
, "address-family ipv4 multicast",
1137 "Enter Address Family command mode\n"
1139 "Address Family modifier\n")
1141 vty
->node
= BGP_IPV4M_NODE
;
1145 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_vpn
, address_family_ipv4_vpn_cmd
,
1146 "address-family ipv4 vpn",
1147 "Enter Address Family command mode\n"
1149 "Address Family modifier\n")
1151 vty
->node
= BGP_VPNV4_NODE
;
1155 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_labeled_unicast
,
1156 address_family_ipv4_labeled_unicast_cmd
,
1157 "address-family ipv4 labeled-unicast",
1158 "Enter Address Family command mode\n"
1160 "Address Family modifier\n")
1162 vty
->node
= BGP_IPV4L_NODE
;
1166 DEFUNSH(VTYSH_BGPD
, address_family_ipv6
, address_family_ipv6_cmd
,
1167 "address-family ipv6 [unicast]",
1168 "Enter Address Family command mode\n"
1170 "Address Family modifier\n")
1172 vty
->node
= BGP_IPV6_NODE
;
1176 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_multicast
,
1177 address_family_ipv6_multicast_cmd
, "address-family ipv6 multicast",
1178 "Enter Address Family command mode\n"
1180 "Address Family modifier\n")
1182 vty
->node
= BGP_IPV6M_NODE
;
1186 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_vpn
, address_family_ipv6_vpn_cmd
,
1187 "address-family ipv6 vpn",
1188 "Enter Address Family command mode\n"
1190 "Address Family modifier\n")
1192 vty
->node
= BGP_VPNV6_NODE
;
1196 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_labeled_unicast
,
1197 address_family_ipv6_labeled_unicast_cmd
,
1198 "address-family ipv6 labeled-unicast",
1199 "Enter Address Family command mode\n"
1201 "Address Family modifier\n")
1203 vty
->node
= BGP_IPV6L_NODE
;
1207 #if defined(HAVE_RPKI)
1208 DEFUNSH(VTYSH_BGPD
, rpki
, rpki_cmd
, "rpki",
1209 "Enable rpki and enter rpki configuration mode\n")
1211 vty
->node
= RPKI_NODE
;
1215 DEFUNSH(VTYSH_BGPD
, rpki_exit
, rpki_exit_cmd
, "exit",
1216 "Exit current mode and down to previous mode\n")
1218 vty
->node
= CONFIG_NODE
;
1222 DEFUNSH(VTYSH_BGPD
, rpki_quit
, rpki_quit_cmd
, "quit",
1223 "Exit current mode and down to previous mode\n")
1225 return rpki_exit(self
, vty
, argc
, argv
);
1229 DEFUNSH(VTYSH_BGPD
, address_family_evpn
, address_family_evpn_cmd
,
1230 "address-family <l2vpn evpn>",
1231 "Enter Address Family command mode\n"
1233 "Address Family modifier\n")
1235 vty
->node
= BGP_EVPN_NODE
;
1239 #if defined(HAVE_CUMULUS)
1240 DEFUNSH_HIDDEN(VTYSH_BGPD
, address_family_evpn2
, address_family_evpn2_cmd
,
1241 "address-family evpn",
1242 "Enter Address Family command mode\n"
1243 "EVPN Address family\n")
1245 vty
->node
= BGP_EVPN_NODE
;
1250 DEFUNSH(VTYSH_BGPD
, bgp_evpn_vni
, bgp_evpn_vni_cmd
, "vni (1-16777215)",
1251 "VXLAN Network Identifier\n"
1254 vty
->node
= BGP_EVPN_VNI_NODE
;
1258 #if defined(ENABLE_BGP_VNC)
1259 DEFUNSH(VTYSH_BGPD
, vnc_defaults
, vnc_defaults_cmd
, "vnc defaults",
1260 "VNC/RFP related configuration\n"
1261 "Configure default NVE group\n")
1263 vty
->node
= BGP_VNC_DEFAULTS_NODE
;
1267 DEFUNSH(VTYSH_BGPD
, vnc_nve_group
, vnc_nve_group_cmd
, "vnc nve-group NAME",
1268 "VNC/RFP related configuration\n"
1269 "Configure a NVE group\n"
1272 vty
->node
= BGP_VNC_NVE_GROUP_NODE
;
1276 DEFUNSH(VTYSH_BGPD
, vnc_vrf_policy
, vnc_vrf_policy_cmd
, "vrf-policy NAME",
1277 "Configure a VRF policy group\n"
1280 vty
->node
= BGP_VRF_POLICY_NODE
;
1284 DEFUNSH(VTYSH_BGPD
, vnc_l2_group
, vnc_l2_group_cmd
, "vnc l2-group NAME",
1285 "VNC/RFP related configuration\n"
1286 "Configure a L2 group\n"
1289 vty
->node
= BGP_VNC_L2_GROUP_NODE
;
1294 DEFUNSH(VTYSH_RIPD
, key_chain
, key_chain_cmd
, "key chain WORD",
1295 "Authentication key management\n"
1296 "Key-chain management\n"
1299 vty
->node
= KEYCHAIN_NODE
;
1303 DEFUNSH(VTYSH_RIPD
, key
, key_cmd
, "key (0-2147483647)",
1305 "Key identifier number\n")
1307 vty
->node
= KEYCHAIN_KEY_NODE
;
1311 DEFUNSH(VTYSH_RIPD
, router_rip
, router_rip_cmd
, "router rip",
1314 vty
->node
= RIP_NODE
;
1318 DEFUNSH(VTYSH_RIPNGD
, router_ripng
, router_ripng_cmd
, "router ripng",
1319 ROUTER_STR
"RIPng\n")
1321 vty
->node
= RIPNG_NODE
;
1325 DEFUNSH(VTYSH_OSPFD
, router_ospf
, router_ospf_cmd
,
1326 "router ospf [(1-65535)] [vrf NAME]",
1327 "Enable a routing process\n"
1328 "Start OSPF configuration\n"
1329 "Instance ID\n" VRF_CMD_HELP_STR
)
1331 vty
->node
= OSPF_NODE
;
1335 DEFUNSH(VTYSH_EIGRPD
, router_eigrp
, router_eigrp_cmd
, "router eigrp (1-65535)",
1336 "Enable a routing process\n"
1337 "Start EIGRP configuration\n"
1338 "AS number to use\n")
1340 vty
->node
= EIGRP_NODE
;
1344 DEFUNSH(VTYSH_BABELD
, router_babel
, router_babel_cmd
, "router babel",
1345 "Enable a routing process\n"
1346 "Make Babel instance command\n")
1348 vty
->node
= BABEL_NODE
;
1352 DEFUNSH(VTYSH_OSPF6D
, router_ospf6
, router_ospf6_cmd
, "router ospf6",
1353 ROUTER_STR OSPF6_STR
)
1355 vty
->node
= OSPF6_NODE
;
1359 #if defined(HAVE_LDPD)
1360 DEFUNSH(VTYSH_LDPD
, ldp_mpls_ldp
, ldp_mpls_ldp_cmd
, "mpls ldp",
1361 "Global MPLS configuration subcommands\n"
1362 "Label Distribution Protocol\n")
1364 vty
->node
= LDP_NODE
;
1368 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv4
, ldp_address_family_ipv4_cmd
,
1369 "address-family ipv4",
1370 "Configure Address Family and its parameters\n"
1373 vty
->node
= LDP_IPV4_NODE
;
1377 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv6
, ldp_address_family_ipv6_cmd
,
1378 "address-family ipv6",
1379 "Configure Address Family and its parameters\n"
1382 vty
->node
= LDP_IPV6_NODE
;
1386 DEFUNSH(VTYSH_LDPD
, ldp_exit_address_family
, ldp_exit_address_family_cmd
,
1387 "exit-address-family", "Exit from Address Family configuration mode\n")
1389 if (vty
->node
== LDP_IPV4_NODE
|| vty
->node
== LDP_IPV6_NODE
)
1390 vty
->node
= LDP_NODE
;
1394 DEFUNSH(VTYSH_LDPD
, ldp_interface_ifname
, ldp_interface_ifname_cmd
,
1396 "Enable LDP on an interface and enter interface submode\n"
1397 "Interface's name\n")
1399 switch (vty
->node
) {
1401 vty
->node
= LDP_IPV4_IFACE_NODE
;
1404 vty
->node
= LDP_IPV6_IFACE_NODE
;
1413 DEFUNSH(VTYSH_LDPD
, ldp_l2vpn_word_type_vpls
, ldp_l2vpn_word_type_vpls_cmd
,
1414 "l2vpn WORD type vpls",
1415 "Configure l2vpn commands\n"
1418 "Virtual Private LAN Service\n")
1420 vty
->node
= LDP_L2VPN_NODE
;
1424 DEFUNSH(VTYSH_LDPD
, ldp_member_pseudowire_ifname
,
1425 ldp_member_pseudowire_ifname_cmd
, "member pseudowire IFNAME",
1426 "L2VPN member configuration\n"
1427 "Pseudowire interface\n"
1428 "Interface's name\n")
1430 vty
->node
= LDP_PSEUDOWIRE_NODE
;
1435 DEFUNSH(VTYSH_ISISD
, router_isis
, router_isis_cmd
, "router isis WORD",
1438 "ISO Routing area tag\n")
1440 vty
->node
= ISIS_NODE
;
1444 DEFUNSH(VTYSH_RMAP
, vtysh_route_map
, vtysh_route_map_cmd
,
1445 "route-map WORD <deny|permit> (1-65535)",
1446 "Create route-map or enter route-map command mode\n"
1448 "Route map denies set operations\n"
1449 "Route map permits set operations\n"
1450 "Sequence to insert to/delete from existing route-map entry\n")
1452 vty
->node
= RMAP_NODE
;
1456 DEFUNSH(VTYSH_ALL
, vtysh_line_vty
, vtysh_line_vty_cmd
, "line vty",
1457 "Configure a terminal line\n"
1458 "Virtual terminal\n")
1460 vty
->node
= VTY_NODE
;
1464 DEFUNSH(VTYSH_REALLYALL
, vtysh_enable
, vtysh_enable_cmd
, "enable",
1465 "Turn on privileged mode command\n")
1467 vty
->node
= ENABLE_NODE
;
1471 DEFUNSH(VTYSH_REALLYALL
, vtysh_disable
, vtysh_disable_cmd
, "disable",
1472 "Turn off privileged mode command\n")
1474 if (vty
->node
== ENABLE_NODE
)
1475 vty
->node
= VIEW_NODE
;
1479 DEFUNSH(VTYSH_REALLYALL
, vtysh_config_terminal
, vtysh_config_terminal_cmd
,
1480 "configure terminal",
1481 "Configuration from vty interface\n"
1482 "Configuration terminal\n")
1484 vty
->node
= CONFIG_NODE
;
1488 static int vtysh_exit(struct vty
*vty
)
1490 switch (vty
->node
) {
1496 vty
->node
= ENABLE_NODE
;
1498 case INTERFACE_NODE
:
1500 case LOGICALROUTER_NODE
:
1512 case LDP_L2VPN_NODE
:
1518 vtysh_execute("end");
1519 vtysh_execute("configure terminal");
1520 vty
->node
= CONFIG_NODE
;
1522 case BGP_VPNV4_NODE
:
1523 case BGP_VPNV6_NODE
:
1525 case BGP_IPV4M_NODE
:
1526 case BGP_IPV4L_NODE
:
1528 case BGP_IPV6M_NODE
:
1529 case BGP_IPV6L_NODE
:
1530 case BGP_VRF_POLICY_NODE
:
1532 case BGP_VNC_DEFAULTS_NODE
:
1533 case BGP_VNC_NVE_GROUP_NODE
:
1534 case BGP_VNC_L2_GROUP_NODE
:
1535 vty
->node
= BGP_NODE
;
1537 case BGP_EVPN_VNI_NODE
:
1538 vty
->node
= BGP_EVPN_NODE
;
1542 vty
->node
= LDP_NODE
;
1544 case LDP_IPV4_IFACE_NODE
:
1545 vty
->node
= LDP_IPV4_NODE
;
1547 case LDP_IPV6_IFACE_NODE
:
1548 vty
->node
= LDP_IPV6_NODE
;
1550 case LDP_PSEUDOWIRE_NODE
:
1551 vty
->node
= LDP_L2VPN_NODE
;
1553 case KEYCHAIN_KEY_NODE
:
1554 vty
->node
= KEYCHAIN_NODE
;
1556 case LINK_PARAMS_NODE
:
1557 vty
->node
= INTERFACE_NODE
;
1565 DEFUNSH(VTYSH_REALLYALL
, vtysh_exit_all
, vtysh_exit_all_cmd
, "exit",
1566 "Exit current mode and down to previous mode\n")
1568 return vtysh_exit(vty
);
1571 DEFUNSH(VTYSH_ALL
, vtysh_quit_all
, vtysh_quit_all_cmd
, "quit",
1572 "Exit current mode and down to previous mode\n")
1574 return vtysh_exit_all(self
, vty
, argc
, argv
);
1577 DEFUNSH(VTYSH_BGPD
, exit_address_family
, exit_address_family_cmd
,
1578 "exit-address-family", "Exit from Address Family configuration mode\n")
1580 if (vty
->node
== BGP_IPV4_NODE
|| vty
->node
== BGP_IPV4M_NODE
1581 || vty
->node
== BGP_IPV4L_NODE
|| vty
->node
== BGP_VPNV4_NODE
1582 || vty
->node
== BGP_VPNV6_NODE
|| vty
->node
== BGP_IPV6_NODE
1583 || vty
->node
== BGP_IPV6L_NODE
|| vty
->node
== BGP_IPV6M_NODE
1584 || vty
->node
== BGP_EVPN_NODE
)
1585 vty
->node
= BGP_NODE
;
1589 DEFUNSH(VTYSH_BGPD
, exit_vni
, exit_vni_cmd
, "exit-vni", "Exit from VNI mode\n")
1591 if (vty
->node
== BGP_EVPN_VNI_NODE
)
1592 vty
->node
= BGP_EVPN_NODE
;
1596 DEFUNSH(VTYSH_BGPD
, exit_vnc_config
, exit_vnc_config_cmd
, "exit-vnc",
1597 "Exit from VNC configuration mode\n")
1599 if (vty
->node
== BGP_VNC_DEFAULTS_NODE
1600 || vty
->node
== BGP_VNC_NVE_GROUP_NODE
1601 || vty
->node
== BGP_VNC_L2_GROUP_NODE
)
1602 vty
->node
= BGP_NODE
;
1606 DEFUNSH(VTYSH_BGPD
, exit_vrf_policy
, exit_vrf_policy_cmd
, "exit-vrf-policy",
1607 "Exit from VRF configuration mode\n")
1609 if (vty
->node
== BGP_VRF_POLICY_NODE
)
1610 vty
->node
= BGP_NODE
;
1614 DEFUNSH(VTYSH_RIPD
, vtysh_exit_ripd
, vtysh_exit_ripd_cmd
, "exit",
1615 "Exit current mode and down to previous mode\n")
1617 return vtysh_exit(vty
);
1620 DEFUNSH(VTYSH_RIPD
, vtysh_quit_ripd
, vtysh_quit_ripd_cmd
, "quit",
1621 "Exit current mode and down to previous mode\n")
1623 return vtysh_exit_ripd(self
, vty
, argc
, argv
);
1626 DEFUNSH(VTYSH_RIPNGD
, vtysh_exit_ripngd
, vtysh_exit_ripngd_cmd
, "exit",
1627 "Exit current mode and down to previous mode\n")
1629 return vtysh_exit(vty
);
1632 DEFUNSH(VTYSH_RIPNGD
, vtysh_quit_ripngd
, vtysh_quit_ripngd_cmd
, "quit",
1633 "Exit current mode and down to previous mode\n")
1635 return vtysh_exit_ripngd(self
, vty
, argc
, argv
);
1638 DEFUNSH(VTYSH_RMAP
, vtysh_exit_rmap
, vtysh_exit_rmap_cmd
, "exit",
1639 "Exit current mode and down to previous mode\n")
1641 return vtysh_exit(vty
);
1644 DEFUNSH(VTYSH_RMAP
, vtysh_quit_rmap
, vtysh_quit_rmap_cmd
, "quit",
1645 "Exit current mode and down to previous mode\n")
1647 return vtysh_exit_rmap(self
, vty
, argc
, argv
);
1650 DEFUNSH(VTYSH_BGPD
, vtysh_exit_bgpd
, vtysh_exit_bgpd_cmd
, "exit",
1651 "Exit current mode and down to previous mode\n")
1653 return vtysh_exit(vty
);
1656 DEFUNSH(VTYSH_BGPD
, vtysh_quit_bgpd
, vtysh_quit_bgpd_cmd
, "quit",
1657 "Exit current mode and down to previous mode\n")
1659 return vtysh_exit_bgpd(self
, vty
, argc
, argv
);
1662 DEFUNSH(VTYSH_OSPFD
, vtysh_exit_ospfd
, vtysh_exit_ospfd_cmd
, "exit",
1663 "Exit current mode and down to previous mode\n")
1665 return vtysh_exit(vty
);
1668 DEFUNSH(VTYSH_OSPFD
, vtysh_quit_ospfd
, vtysh_quit_ospfd_cmd
, "quit",
1669 "Exit current mode and down to previous mode\n")
1671 return vtysh_exit_ospfd(self
, vty
, argc
, argv
);
1674 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_eigrpd
, vtysh_exit_eigrpd_cmd
, "exit",
1675 "Exit current mode and down to previous mode\n")
1677 return vtysh_exit(vty
);
1680 DEFUNSH(VTYSH_EIGRPD
, vtysh_quit_eigrpd
, vtysh_quit_eigrpd_cmd
, "quit",
1681 "Exit current mode and down to previous mode\n")
1683 return vtysh_exit(vty
);
1686 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_babeld
, vtysh_exit_babeld_cmd
, "exit",
1687 "Exit current mode and down to previous mode\n")
1689 return vtysh_exit(vty
);
1692 DEFUNSH(VTYSH_BABELD
, vtysh_quit_babeld
, vtysh_quit_babeld_cmd
, "quit",
1693 "Exit current mode and down to previous mode\n")
1695 return vtysh_exit(vty
);
1698 DEFUNSH(VTYSH_OSPF6D
, vtysh_exit_ospf6d
, vtysh_exit_ospf6d_cmd
, "exit",
1699 "Exit current mode and down to previous mode\n")
1701 return vtysh_exit(vty
);
1704 DEFUNSH(VTYSH_OSPF6D
, vtysh_quit_ospf6d
, vtysh_quit_ospf6d_cmd
, "quit",
1705 "Exit current mode and down to previous mode\n")
1707 return vtysh_exit_ospf6d(self
, vty
, argc
, argv
);
1710 #if defined(HAVE_LDPD)
1711 DEFUNSH(VTYSH_LDPD
, vtysh_exit_ldpd
, vtysh_exit_ldpd_cmd
, "exit",
1712 "Exit current mode and down to previous mode\n")
1714 return vtysh_exit(vty
);
1717 ALIAS(vtysh_exit_ldpd
, vtysh_quit_ldpd_cmd
, "quit",
1718 "Exit current mode and down to previous mode\n")
1721 DEFUNSH(VTYSH_ISISD
, vtysh_exit_isisd
, vtysh_exit_isisd_cmd
, "exit",
1722 "Exit current mode and down to previous mode\n")
1724 return vtysh_exit(vty
);
1727 DEFUNSH(VTYSH_ISISD
, vtysh_quit_isisd
, vtysh_quit_isisd_cmd
, "quit",
1728 "Exit current mode and down to previous mode\n")
1730 return vtysh_exit_isisd(self
, vty
, argc
, argv
);
1733 DEFUNSH(VTYSH_ALL
, vtysh_exit_line_vty
, vtysh_exit_line_vty_cmd
, "exit",
1734 "Exit current mode and down to previous mode\n")
1736 return vtysh_exit(vty
);
1739 DEFUNSH(VTYSH_ALL
, vtysh_quit_line_vty
, vtysh_quit_line_vty_cmd
, "quit",
1740 "Exit current mode and down to previous mode\n")
1742 return vtysh_exit_line_vty(self
, vty
, argc
, argv
);
1745 DEFUNSH(VTYSH_INTERFACE
, vtysh_interface
, vtysh_interface_cmd
,
1746 "interface IFNAME [vrf NAME]",
1747 "Select an interface to configure\n"
1748 "Interface's name\n" VRF_CMD_HELP_STR
)
1750 vty
->node
= INTERFACE_NODE
;
1754 DEFUNSH(VTYSH_ZEBRA
, vtysh_pseudowire
, vtysh_pseudowire_cmd
,
1755 "pseudowire IFNAME",
1756 "Static pseudowire configuration\n"
1757 "Pseudowire name\n")
1759 vty
->node
= PW_NODE
;
1763 /* TODO Implement "no interface command in isisd. */
1764 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_RIPNGD
| VTYSH_OSPFD
| VTYSH_OSPF6D
1766 vtysh_no_interface_cmd
, "no interface IFNAME", NO_STR
1767 "Delete a pseudo interface's configuration\n"
1768 "Interface's name\n")
1770 DEFSH(VTYSH_ZEBRA
, vtysh_no_interface_vrf_cmd
, "no interface IFNAME vrf NAME",
1772 "Delete a pseudo interface's configuration\n"
1773 "Interface's name\n" VRF_CMD_HELP_STR
)
1775 DEFUNSH(VTYSH_ZEBRA
, vtysh_logicalrouter
, vtysh_logicalrouter_cmd
,
1776 "logical-router (1-65535) ns NAME",
1777 "Enable a logical-router\n"
1778 "Specify the logical-router indentifier\n"
1780 "The file name in " NS_RUN_DIR
", or a full pathname\n")
1782 vty
->node
= LOGICALROUTER_NODE
;
1786 DEFSH(VTYSH_ZEBRA
, vtysh_no_logicalrouter_cmd
,
1787 "no logical-router (1-65535) ns NAME", NO_STR
1788 "Enable a Logical-Router\n"
1789 "Specify the Logical-Router identifier\n"
1791 "The file name in " NS_RUN_DIR
", or a full pathname\n")
1793 DEFUNSH(VTYSH_VRF
, vtysh_vrf
, vtysh_vrf_cmd
, "vrf NAME",
1794 "Select a VRF to configure\n"
1797 vty
->node
= VRF_NODE
;
1801 DEFSH(VTYSH_ZEBRA
, vtysh_no_vrf_cmd
, "no vrf NAME", NO_STR
1802 "Delete a pseudo vrf's configuration\n"
1805 DEFUNSH(VTYSH_NS
, vtysh_exit_logicalrouter
, vtysh_exit_logicalrouter_cmd
,
1806 "exit", "Exit current mode and down to previous mode\n")
1808 return vtysh_exit(vty
);
1811 DEFUNSH(VTYSH_NS
, vtysh_quit_logicalrouter
, vtysh_quit_logicalrouter_cmd
,
1812 "quit", "Exit current mode and down to previous mode\n")
1814 return vtysh_exit_logicalrouter(self
, vty
, argc
, argv
);
1817 DEFUNSH(VTYSH_VRF
, vtysh_exit_vrf
, vtysh_exit_vrf_cmd
, "exit",
1818 "Exit current mode and down to previous mode\n")
1820 return vtysh_exit(vty
);
1823 DEFUNSH(VTYSH_VRF
, vtysh_quit_vrf
, vtysh_quit_vrf_cmd
, "quit",
1824 "Exit current mode and down to previous mode\n")
1826 return vtysh_exit_vrf(self
, vty
, argc
, argv
);
1829 /* TODO Implement interface description commands in ripngd, ospf6d
1831 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_OSPFD
| VTYSH_EIGRPD
,
1832 vtysh_interface_desc_cmd
, "description LINE...",
1833 "Interface specific description\n"
1834 "Characters describing this interface\n")
1836 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_OSPFD
| VTYSH_EIGRPD
,
1837 vtysh_no_interface_desc_cmd
, "no description",
1838 NO_STR
"Interface specific description\n")
1840 DEFUNSH(VTYSH_INTERFACE
, vtysh_exit_interface
, vtysh_exit_interface_cmd
, "exit",
1841 "Exit current mode and down to previous mode\n")
1843 return vtysh_exit(vty
);
1846 DEFUNSH(VTYSH_INTERFACE
, vtysh_quit_interface
, vtysh_quit_interface_cmd
, "quit",
1847 "Exit current mode and down to previous mode\n")
1849 return vtysh_exit_interface(self
, vty
, argc
, argv
);
1852 DEFUN (vtysh_show_thread
,
1853 vtysh_show_thread_cmd
,
1854 "show thread cpu [FILTER]",
1856 "Thread information\n"
1857 "Thread CPU usage\n"
1858 "Display filter (rwtexb)\n")
1862 int ret
= CMD_SUCCESS
;
1865 const char *filter
=
1866 argv_find(argv
, argc
, "FILTER", &idx
) ? argv
[idx
]->arg
: "";
1868 snprintf(line
, sizeof(line
), "do show thread cpu %s\n", filter
);
1869 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1870 if (vtysh_client
[i
].fd
>= 0) {
1871 fprintf(stdout
, "Thread statistics for %s:\n",
1872 vtysh_client
[i
].name
);
1873 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
1875 fprintf(stdout
, "\n");
1880 DEFUN (vtysh_show_work_queues
,
1881 vtysh_show_work_queues_cmd
,
1884 "Work Queue information\n")
1887 int ret
= CMD_SUCCESS
;
1888 char line
[] = "do show work-queues\n";
1890 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1891 if (vtysh_client
[i
].fd
>= 0) {
1892 fprintf(stdout
, "Work queue statistics for %s:\n",
1893 vtysh_client
[i
].name
);
1894 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
1896 fprintf(stdout
, "\n");
1902 DEFUN (vtysh_show_work_queues_daemon
,
1903 vtysh_show_work_queues_daemon_cmd
,
1904 "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd>",
1906 "Work Queue information\n"
1907 "For the zebra daemon\n"
1908 "For the rip daemon\n"
1909 "For the ripng daemon\n"
1910 "For the ospf daemon\n"
1911 "For the ospfv6 daemon\n"
1912 "For the bgp daemon\n"
1913 "For the isis daemon\n")
1915 int idx_protocol
= 2;
1917 int ret
= CMD_SUCCESS
;
1919 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
1920 if (strmatch(vtysh_client
[i
].name
, argv
[idx_protocol
]->text
))
1924 ret
= vtysh_client_execute(&vtysh_client
[i
], "show work-queues\n",
1930 DEFUNSH(VTYSH_ZEBRA
, vtysh_link_params
, vtysh_link_params_cmd
, "link-params",
1933 vty
->node
= LINK_PARAMS_NODE
;
1937 DEFUNSH(VTYSH_ZEBRA
, exit_link_params
, exit_link_params_cmd
, "exit-link-params",
1938 "Exit from Link Params configuration node\n")
1940 if (vty
->node
== LINK_PARAMS_NODE
)
1941 vty
->node
= INTERFACE_NODE
;
1945 static int show_per_daemon(const char *line
, const char *headline
)
1948 int ret
= CMD_SUCCESS
;
1950 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1951 if (vtysh_client
[i
].fd
>= 0) {
1952 fprintf(outputfile
, headline
, vtysh_client
[i
].name
);
1953 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
1955 fprintf(stdout
, "\n");
1961 DEFUNSH_HIDDEN (0x00,
1963 vtysh_debug_all_cmd
,
1967 "Toggle all debugs on or off\n")
1972 DEFUN (vtysh_show_debugging
,
1973 vtysh_show_debugging_cmd
,
1978 return show_per_daemon("do show debugging\n", "");
1981 DEFUN (vtysh_show_debugging_hashtable
,
1982 vtysh_show_debugging_hashtable_cmd
,
1983 "show debugging hashtable [statistics]",
1986 "Statistics about hash tables\n"
1987 "Statistics about hash tables\n")
1989 fprintf(stdout
, "\n");
1991 "Load factor (LF) - average number of elements across all buckets\n");
1993 "Full load factor (FLF) - average number of elements across full buckets\n\n");
1995 "Standard deviation (SD) is calculated for both the LF and FLF\n");
1997 "and indicates the typical deviation of bucket chain length\n");
1998 fprintf(stdout
, "from the value in the corresponding load factor.\n\n");
2000 return show_per_daemon("do show debugging hashtable\n",
2001 "Hashtable statistics for %s:\n");
2005 DEFUN (vtysh_show_memory
,
2006 vtysh_show_memory_cmd
,
2009 "Memory statistics\n")
2011 return show_per_daemon("show memory\n", "Memory statistics for %s:\n");
2014 DEFUN (vtysh_show_modules
,
2015 vtysh_show_modules_cmd
,
2020 return show_per_daemon("show modules\n",
2021 "Module information for %s:\n");
2024 /* Logging commands. */
2025 DEFUN (vtysh_show_logging
,
2026 vtysh_show_logging_cmd
,
2029 "Show current logging configuration\n")
2031 return show_per_daemon("do show logging\n",
2032 "Logging configuration for %s:\n");
2035 DEFUNSH(VTYSH_ALL
, vtysh_log_stdout
, vtysh_log_stdout_cmd
, "log stdout",
2037 "Set stdout logging level\n")
2042 DEFUNSH(VTYSH_ALL
, vtysh_log_stdout_level
, vtysh_log_stdout_level_cmd
,
2043 "log stdout <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2045 "Set stdout logging level\n" LOG_LEVEL_DESC
)
2050 DEFUNSH(VTYSH_ALL
, no_vtysh_log_stdout
, no_vtysh_log_stdout_cmd
,
2051 "no log stdout [LEVEL]", NO_STR
2053 "Cancel logging to stdout\n"
2059 DEFUNSH(VTYSH_ALL
, vtysh_log_file
, vtysh_log_file_cmd
, "log file FILENAME",
2062 "Logging filename\n")
2067 DEFUNSH(VTYSH_ALL
, vtysh_log_file_level
, vtysh_log_file_level_cmd
,
2068 "log file FILENAME <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2071 "Logging filename\n" LOG_LEVEL_DESC
)
2076 DEFUNSH(VTYSH_ALL
, no_vtysh_log_file
, no_vtysh_log_file_cmd
,
2077 "no log file [FILENAME [LEVEL]]", NO_STR
2079 "Cancel logging to file\n"
2080 "Logging file name\n"
2086 DEFUNSH(VTYSH_ALL
, vtysh_log_monitor
, vtysh_log_monitor_cmd
,
2087 "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
2089 "Set terminal line (monitor) logging level\n" LOG_LEVEL_DESC
)
2094 DEFUNSH(VTYSH_ALL
, no_vtysh_log_monitor
, no_vtysh_log_monitor_cmd
,
2095 "no log monitor [LEVEL]", NO_STR
2097 "Disable terminal line (monitor) logging\n"
2103 DEFUNSH(VTYSH_ALL
, vtysh_log_syslog
, vtysh_log_syslog_cmd
,
2104 "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
2106 "Set syslog logging level\n" LOG_LEVEL_DESC
)
2111 DEFUNSH(VTYSH_ALL
, no_vtysh_log_syslog
, no_vtysh_log_syslog_cmd
,
2112 "no log syslog [LEVEL]", NO_STR
2114 "Cancel logging to syslog\n"
2120 DEFUNSH(VTYSH_ALL
, vtysh_log_facility
, vtysh_log_facility_cmd
,
2121 "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>",
2123 "Facility parameter for syslog messages\n" LOG_FACILITY_DESC
)
2129 DEFUNSH(VTYSH_ALL
, no_vtysh_log_facility
, no_vtysh_log_facility_cmd
,
2130 "no log facility [FACILITY]", NO_STR
2132 "Reset syslog facility to default (daemon)\n"
2133 "Syslog facility\n")
2140 VTYSH_ALL
, vtysh_log_trap
, vtysh_log_trap_cmd
,
2141 "log trap <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2143 "(Deprecated) Set logging level and default for all destinations\n" LOG_LEVEL_DESC
)
2149 DEFUNSH_DEPRECATED(VTYSH_ALL
, no_vtysh_log_trap
, no_vtysh_log_trap_cmd
,
2150 "no log trap [LEVEL]", NO_STR
2152 "Permit all logging information\n"
2158 DEFUNSH(VTYSH_ALL
, vtysh_log_record_priority
, vtysh_log_record_priority_cmd
,
2159 "log record-priority",
2161 "Log the priority of the message within the message\n")
2166 DEFUNSH(VTYSH_ALL
, no_vtysh_log_record_priority
,
2167 no_vtysh_log_record_priority_cmd
, "no log record-priority", NO_STR
2169 "Do not log the priority of the message within the message\n")
2174 DEFUNSH(VTYSH_ALL
, vtysh_log_timestamp_precision
,
2175 vtysh_log_timestamp_precision_cmd
, "log timestamp precision (0-6)",
2177 "Timestamp configuration\n"
2178 "Set the timestamp precision\n"
2179 "Number of subsecond digits\n")
2184 DEFUNSH(VTYSH_ALL
, no_vtysh_log_timestamp_precision
,
2185 no_vtysh_log_timestamp_precision_cmd
, "no log timestamp precision",
2188 "Timestamp configuration\n"
2189 "Reset the timestamp precision to the default value of 0\n")
2194 DEFUNSH(VTYSH_ALL
, vtysh_service_password_encrypt
,
2195 vtysh_service_password_encrypt_cmd
, "service password-encryption",
2196 "Set up miscellaneous service\n"
2197 "Enable encrypted passwords\n")
2202 DEFUNSH(VTYSH_ALL
, no_vtysh_service_password_encrypt
,
2203 no_vtysh_service_password_encrypt_cmd
, "no service password-encryption",
2205 "Set up miscellaneous service\n"
2206 "Enable encrypted passwords\n")
2211 DEFUNSH(VTYSH_ALL
, vtysh_config_password
, vtysh_password_cmd
,
2212 "password [(8-8)] LINE",
2213 "Assign the terminal connection password\n"
2214 "Specifies a HIDDEN password will follow\n"
2215 "The password string\n")
2220 DEFUNSH(VTYSH_ALL
, vtysh_config_enable_password
, vtysh_enable_password_cmd
,
2221 "enable password [(8-8)] LINE",
2222 "Modify enable password parameters\n"
2223 "Assign the privileged level password\n"
2224 "Specifies a HIDDEN password will follow\n"
2225 "The 'enable' password string\n")
2230 DEFUNSH(VTYSH_ALL
, no_vtysh_config_enable_password
,
2231 no_vtysh_enable_password_cmd
, "no enable password", NO_STR
2232 "Modify enable password parameters\n"
2233 "Assign the privileged level password\n")
2238 DEFUN (vtysh_write_terminal
,
2239 vtysh_write_terminal_cmd
,
2240 "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
2241 "Write running configuration to memory, network, or terminal\n"
2242 "Write to terminal\n"
2243 "For the zebra daemon\n"
2244 "For the rip daemon\n"
2245 "For the ripng daemon\n"
2246 "For the ospf daemon\n"
2247 "For the ospfv6 daemon\n"
2248 "For the ldpd daemon\n"
2249 "For the bgp daemon\n"
2250 "For the isis daemon\n"
2251 "For the pim daemon\n")
2254 char line
[] = "do write terminal\n";
2255 FILE *fp
= outputfile
;
2257 if (fp
== stdout
&& vtysh_pager_name
) {
2258 fp
= popen(vtysh_pager_name
, "w");
2265 fprintf(outputfile
, "Building configuration...\n");
2266 fprintf(outputfile
, "\nCurrent configuration:\n");
2267 fprintf(outputfile
, "!\n");
2269 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2271 || (strmatch(vtysh_client
[i
].name
, argv
[2]->text
)))
2272 vtysh_client_config(&vtysh_client
[i
], line
);
2274 /* Integrate vtysh specific configuration. */
2275 vtysh_config_write();
2277 vtysh_config_dump(fp
);
2279 if (vtysh_pager_name
&& fp
&& fp
!= outputfile
) {
2281 if (pclose(fp
) == -1) {
2288 fprintf(outputfile
, "end\n");
2292 DEFUN (vtysh_show_running_config
,
2293 vtysh_show_running_config_cmd
,
2294 "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
2296 "Current operating configuration\n"
2297 "For the zebra daemon\n"
2298 "For the rip daemon\n"
2299 "For the ripng daemon\n"
2300 "For the ospf daemon\n"
2301 "For the ospfv6 daemon\n"
2302 "For the ldp daemon\n"
2303 "For the bgp daemon\n"
2304 "For the isis daemon\n"
2305 "For the pim daemon\n")
2307 return vtysh_write_terminal(self
, vty
, argc
, argv
);
2310 DEFUN (vtysh_integrated_config
,
2311 vtysh_integrated_config_cmd
,
2312 "service integrated-vtysh-config",
2313 "Set up miscellaneous service\n"
2314 "Write configuration into integrated file\n")
2316 vtysh_write_integrated
= WRITE_INTEGRATED_YES
;
2320 DEFUN (no_vtysh_integrated_config
,
2321 no_vtysh_integrated_config_cmd
,
2322 "no service integrated-vtysh-config",
2324 "Set up miscellaneous service\n"
2325 "Write configuration into integrated file\n")
2327 vtysh_write_integrated
= WRITE_INTEGRATED_NO
;
2331 static void backup_config_file(const char *fbackup
)
2333 char *integrate_sav
= NULL
;
2335 integrate_sav
= malloc(strlen(fbackup
) + strlen(CONF_BACKUP_EXT
) + 1);
2336 strcpy(integrate_sav
, fbackup
);
2337 strcat(integrate_sav
, CONF_BACKUP_EXT
);
2339 /* Move current configuration file to backup config file. */
2340 unlink(integrate_sav
);
2341 rename(fbackup
, integrate_sav
);
2342 free(integrate_sav
);
2345 int vtysh_write_config_integrated(void)
2348 char line
[] = "do write terminal\n";
2351 struct passwd
*pwentry
;
2352 struct group
*grentry
;
2358 fprintf(stdout
, "Building Configuration...\n");
2360 backup_config_file(frr_config
);
2361 fp
= fopen(frr_config
, "w");
2364 "%% Error: failed to open configuration file %s: %s\n",
2365 frr_config
, safe_strerror(errno
));
2366 return CMD_WARNING_CONFIG_FAILED
;
2370 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2371 vtysh_client_config(&vtysh_client
[i
], line
);
2373 vtysh_config_write();
2374 vtysh_config_dump(fp
);
2376 if (fchmod(fd
, CONFIGFILE_MASK
) != 0) {
2377 printf("%% Warning: can't chmod configuration file %s: %s\n",
2378 frr_config
, safe_strerror(errno
));
2383 pwentry
= getpwnam(FRR_USER
);
2385 uid
= pwentry
->pw_uid
;
2387 printf("%% Warning: could not look up user \"%s\"\n", FRR_USER
);
2392 grentry
= getgrnam(FRR_GROUP
);
2394 gid
= grentry
->gr_gid
;
2396 printf("%% Warning: could not look up group \"%s\"\n",
2402 if (!fstat(fd
, &st
)) {
2403 if (st
.st_uid
== uid
)
2405 if (st
.st_gid
== gid
)
2407 if ((uid
!= (uid_t
)-1 || gid
!= (gid_t
)-1)
2408 && fchown(fd
, uid
, gid
)) {
2409 printf("%% Warning: can't chown configuration file %s: %s\n",
2410 frr_config
, safe_strerror(errno
));
2414 printf("%% Warning: stat() failed on %s: %s\n", frr_config
,
2415 safe_strerror(errno
));
2421 printf("Integrated configuration saved to %s\n", frr_config
);
2429 static bool want_config_integrated(void)
2433 switch (vtysh_write_integrated
) {
2434 case WRITE_INTEGRATED_UNSPECIFIED
:
2435 if (stat(frr_config
, &s
) && errno
== ENOENT
)
2438 case WRITE_INTEGRATED_NO
:
2440 case WRITE_INTEGRATED_YES
:
2446 DEFUN (vtysh_write_memory
,
2447 vtysh_write_memory_cmd
,
2448 "write [<memory|file>]",
2449 "Write running configuration to memory, network, or terminal\n"
2450 "Write configuration to the file (same as write file)\n"
2451 "Write configuration to the file (same as write memory)\n")
2453 int ret
= CMD_SUCCESS
;
2454 char line
[] = "do write memory\n";
2458 "Note: this version of vtysh never writes vtysh.conf\n");
2460 /* If integrated frr.conf explicitely set. */
2461 if (want_config_integrated()) {
2462 ret
= CMD_WARNING_CONFIG_FAILED
;
2463 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2464 if (vtysh_client
[i
].flag
== VTYSH_WATCHFRR
)
2466 if (i
< array_size(vtysh_client
) && vtysh_client
[i
].fd
!= -1)
2467 ret
= vtysh_client_execute(&vtysh_client
[i
],
2468 "do write integrated",
2471 if (ret
!= CMD_SUCCESS
) {
2472 printf("\nWarning: attempting direct configuration write without "
2473 "watchfrr.\nFile permissions and ownership may be "
2474 "incorrect, or write may fail.\n\n");
2475 ret
= vtysh_write_config_integrated();
2480 fprintf(outputfile
, "Building Configuration...\n");
2482 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2483 ret
= vtysh_client_execute(&vtysh_client
[i
], line
, outputfile
);
2488 DEFUN (vtysh_copy_running_config
,
2489 vtysh_copy_running_config_cmd
,
2490 "copy running-config startup-config",
2491 "Copy from one file to another\n"
2492 "Copy from current system configuration\n"
2493 "Copy to startup configuration\n")
2495 return vtysh_write_memory(self
, vty
, argc
, argv
);
2498 DEFUN (vtysh_terminal_length
,
2499 vtysh_terminal_length_cmd
,
2500 "terminal length (0-512)",
2501 "Set terminal line parameters\n"
2502 "Set number of lines on a screen\n"
2503 "Number of lines on screen (0 for no pausing)\n")
2507 char *endptr
= NULL
;
2508 char default_pager
[10];
2510 lines
= strtol(argv
[idx_number
]->arg
, &endptr
, 10);
2511 if (lines
< 0 || lines
> 512 || *endptr
!= '\0') {
2512 fprintf(outputfile
, "length is malformed\n");
2516 if (vtysh_pager_name
) {
2517 free(vtysh_pager_name
);
2518 vtysh_pager_name
= NULL
;
2522 snprintf(default_pager
, 10, "more -%i", lines
);
2523 vtysh_pager_name
= strdup(default_pager
);
2529 DEFUN (vtysh_terminal_no_length
,
2530 vtysh_terminal_no_length_cmd
,
2531 "terminal no length",
2532 "Set terminal line parameters\n"
2534 "Set number of lines on a screen\n")
2536 if (vtysh_pager_name
) {
2537 free(vtysh_pager_name
);
2538 vtysh_pager_name
= NULL
;
2545 DEFUN (vtysh_show_daemons
,
2546 vtysh_show_daemons_cmd
,
2549 "Show list of running daemons\n")
2553 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2554 if (vtysh_client
[i
].fd
>= 0)
2555 fprintf(outputfile
, " %s", vtysh_client
[i
].name
);
2556 fprintf(outputfile
, "\n");
2561 /* Execute command in child process. */
2562 static void execute_command(const char *command
, int argc
, const char *arg1
,
2572 /* Failure of fork(). */
2573 fprintf(stderr
, "Can't fork: %s\n", safe_strerror(errno
));
2575 } else if (pid
== 0) {
2576 /* This is child process. */
2579 execlp(command
, command
, (const char *)NULL
);
2582 execlp(command
, command
, arg1
, (const char *)NULL
);
2585 execlp(command
, command
, arg1
, arg2
,
2586 (const char *)NULL
);
2590 /* When execlp suceed, this part is not executed. */
2591 fprintf(stderr
, "Can't execute %s: %s\n", command
,
2592 safe_strerror(errno
));
2595 /* This is parent. */
2597 wait4(pid
, &status
, 0, NULL
);
2605 "Send echo messages\n"
2606 "Ping destination address or hostname\n")
2610 argv_find(argv
, argc
, "WORD", &idx
);
2611 execute_command("ping", 1, argv
[idx
]->arg
, NULL
);
2615 ALIAS(vtysh_ping
, vtysh_ping_ip_cmd
, "ping ip WORD",
2616 "Send echo messages\n"
2618 "Ping destination address or hostname\n")
2620 DEFUN (vtysh_traceroute
,
2621 vtysh_traceroute_cmd
,
2623 "Trace route to destination\n"
2624 "Trace route to destination address or hostname\n")
2628 argv_find(argv
, argc
, "WORD", &idx
);
2629 execute_command("traceroute", 1, argv
[idx
]->arg
, NULL
);
2633 ALIAS(vtysh_traceroute
, vtysh_traceroute_ip_cmd
, "traceroute ip WORD",
2634 "Trace route to destination\n"
2636 "Trace route to destination address or hostname\n")
2638 DEFUN (vtysh_mtrace
,
2641 "Multicast trace route to multicast source\n"
2642 "Multicast trace route to multicast source address\n")
2646 argv_find(argv
, argc
, "WORD", &idx
);
2647 execute_command("mtracebis", 1, argv
[idx
]->arg
, NULL
);
2654 "Send echo messages\n"
2656 "Ping destination address or hostname\n")
2658 execute_command("ping6", 1, argv
[2]->arg
, NULL
);
2662 DEFUN (vtysh_traceroute6
,
2663 vtysh_traceroute6_cmd
,
2664 "traceroute ipv6 WORD",
2665 "Trace route to destination\n"
2667 "Trace route to destination address or hostname\n")
2669 execute_command("traceroute6", 1, argv
[2]->arg
, NULL
);
2673 #if defined(HAVE_SHELL_ACCESS)
2674 DEFUN (vtysh_telnet
,
2677 "Open a telnet connection\n"
2678 "IP address or hostname of a remote system\n")
2680 execute_command("telnet", 1, argv
[1]->arg
, NULL
);
2684 DEFUN (vtysh_telnet_port
,
2685 vtysh_telnet_port_cmd
,
2687 "Open a telnet connection\n"
2688 "IP address or hostname of a remote system\n"
2689 "TCP Port number\n")
2691 execute_command("telnet", 2, argv
[1]->arg
, argv
[2]->arg
);
2698 "Open an ssh connection\n"
2701 execute_command("ssh", 1, argv
[1]->arg
, NULL
);
2705 DEFUN (vtysh_start_shell
,
2706 vtysh_start_shell_cmd
,
2708 "Start UNIX shell\n")
2710 execute_command("sh", 0, NULL
, NULL
);
2714 DEFUN (vtysh_start_bash
,
2715 vtysh_start_bash_cmd
,
2717 "Start UNIX shell\n"
2720 execute_command("bash", 0, NULL
, NULL
);
2724 DEFUN (vtysh_start_zsh
,
2725 vtysh_start_zsh_cmd
,
2727 "Start UNIX shell\n"
2730 execute_command("zsh", 0, NULL
, NULL
);
2737 "list [permutations]",
2738 "Print command list\n"
2739 "Print all possible command permutations\n")
2741 return cmd_list_cmds(vty
, argc
== 2);
2744 DEFUN (vtysh_output_file
,
2745 vtysh_output_file_cmd
,
2747 "Direct vtysh output to file\n"
2748 "Direct vtysh output to file\n"
2749 "Path to dump output to\n")
2751 const char *path
= argv
[argc
- 1]->arg
;
2752 outputfile
= fopen(path
, "a");
2754 fprintf(stdout
, "Failed to open file '%s': %s\n", path
,
2755 safe_strerror(errno
));
2756 outputfile
= stdout
;
2761 DEFUN (no_vtysh_output_file
,
2762 no_vtysh_output_file_cmd
,
2763 "no output file [FILE]",
2765 "Direct vtysh output to file\n"
2766 "Direct vtysh output to file\n"
2767 "Path to dump output to\n")
2769 if (outputfile
!= stdout
) {
2771 outputfile
= stdout
;
2779 "Find CLI command containing text\n"
2780 "Text to search for\n")
2782 char *text
= argv_concat(argv
, argc
, 1);
2783 const struct cmd_node
*node
;
2784 const struct cmd_element
*cli
;
2787 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
2788 node
= vector_slot(cmdvec
, i
);
2791 clis
= node
->cmd_vector
;
2792 for (unsigned int j
= 0; j
< vector_active(clis
); j
++) {
2793 cli
= vector_slot(clis
, j
);
2794 if (strcasestr(cli
->string
, text
))
2795 fprintf(stdout
, " (%s) %s\n",
2796 node_names
[node
->node
], cli
->string
);
2800 XFREE(MTYPE_TMP
, text
);
2805 static void vtysh_install_default(enum node_type node
)
2807 install_element(node
, &config_list_cmd
);
2808 install_element(node
, &find_cmd
);
2809 install_element(node
, &vtysh_output_file_cmd
);
2810 install_element(node
, &no_vtysh_output_file_cmd
);
2813 /* Making connection to protocol daemon. */
2814 static int vtysh_connect(struct vtysh_client
*vclient
)
2818 struct sockaddr_un addr
;
2822 if (!vclient
->path
[0])
2823 snprintf(vclient
->path
, sizeof(vclient
->path
), "%s/%s.vty",
2824 vtydir
, vclient
->name
);
2825 path
= vclient
->path
;
2827 /* Stat socket to see if we have permission to access it. */
2828 ret
= stat(path
, &s_stat
);
2829 if (ret
< 0 && errno
!= ENOENT
) {
2830 fprintf(stderr
, "vtysh_connect(%s): stat = %s\n", path
,
2831 safe_strerror(errno
));
2836 if (!S_ISSOCK(s_stat
.st_mode
)) {
2837 fprintf(stderr
, "vtysh_connect(%s): Not a socket\n",
2843 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
2846 fprintf(stderr
, "vtysh_connect(%s): socket = %s\n", path
,
2847 safe_strerror(errno
));
2852 memset(&addr
, 0, sizeof(struct sockaddr_un
));
2853 addr
.sun_family
= AF_UNIX
;
2854 strlcpy(addr
.sun_path
, path
, sizeof(addr
.sun_path
));
2855 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
2856 len
= addr
.sun_len
= SUN_LEN(&addr
);
2858 len
= sizeof(addr
.sun_family
) + strlen(addr
.sun_path
);
2859 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
2861 ret
= connect(sock
, (struct sockaddr
*)&addr
, len
);
2864 fprintf(stderr
, "vtysh_connect(%s): connect = %s\n", path
,
2865 safe_strerror(errno
));
2875 /* Return true if str ends with suffix, else return false */
2876 static int ends_with(const char *str
, const char *suffix
)
2878 if (!str
|| !suffix
)
2880 size_t lenstr
= strlen(str
);
2881 size_t lensuffix
= strlen(suffix
);
2882 if (lensuffix
> lenstr
)
2884 return strncmp(str
+ lenstr
- lensuffix
, suffix
, lensuffix
) == 0;
2887 static void vtysh_client_sorted_insert(struct vtysh_client
*head_client
,
2888 struct vtysh_client
*client
)
2890 struct vtysh_client
*prev_node
, *current_node
;
2892 prev_node
= head_client
;
2893 current_node
= head_client
->next
;
2894 while (current_node
) {
2895 if (strcmp(current_node
->path
, client
->path
) > 0)
2898 prev_node
= current_node
;
2899 current_node
= current_node
->next
;
2901 client
->next
= current_node
;
2902 prev_node
->next
= client
;
2905 #define MAXIMUM_INSTANCES 10
2907 static void vtysh_update_all_insances(struct vtysh_client
*head_client
)
2909 struct vtysh_client
*client
;
2911 struct dirent
*file
;
2914 if (head_client
->flag
!= VTYSH_OSPFD
)
2917 /* ls vty_sock_dir and look for all files ending in .vty */
2918 dir
= opendir(vtydir
);
2920 while ((file
= readdir(dir
)) != NULL
) {
2921 if (begins_with(file
->d_name
, "ospfd-")
2922 && ends_with(file
->d_name
, ".vty")) {
2923 if (n
== MAXIMUM_INSTANCES
) {
2925 "Parsing %s, client limit(%d) reached!\n",
2929 client
= (struct vtysh_client
*)malloc(
2930 sizeof(struct vtysh_client
));
2932 client
->name
= "ospfd";
2933 client
->flag
= VTYSH_OSPFD
;
2934 snprintf(client
->path
, sizeof(client
->path
),
2935 "%s/%s", vtydir
, file
->d_name
);
2936 client
->next
= NULL
;
2937 vtysh_client_sorted_insert(head_client
, client
);
2945 static int vtysh_connect_all_instances(struct vtysh_client
*head_client
)
2947 struct vtysh_client
*client
;
2950 vtysh_update_all_insances(head_client
);
2952 client
= head_client
->next
;
2954 if (vtysh_connect(client
) == 0)
2956 client
= client
->next
;
2962 int vtysh_connect_all(const char *daemon_name
)
2968 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
2970 || !strcmp(daemon_name
, vtysh_client
[i
].name
)) {
2972 if (vtysh_connect(&vtysh_client
[i
]) == 0)
2975 rc
+= vtysh_connect_all_instances(&vtysh_client
[i
]);
2979 fprintf(stderr
, "Error: no daemons match name %s!\n",
2984 /* To disable readline's filename completion. */
2985 static char *vtysh_completion_entry_function(const char *ignore
,
2991 void vtysh_readline_init(void)
2993 /* readline related settings. */
2995 rl_bind_key('?', (rl_command_func_t
*)vtysh_rl_describe
);
2996 rl_completion_entry_function
= vtysh_completion_entry_function
;
2997 rl_attempted_completion_function
=
2998 (rl_completion_func_t
*)new_completion
;
3001 char *vtysh_prompt(void)
3003 static char buf
[100];
3005 snprintf(buf
, sizeof buf
, cmd_prompt(vty
->node
), cmd_hostname_get());
3009 static void vtysh_ac_line(void *arg
, const char *line
)
3013 for (i
= 0; i
< vector_active(comps
); i
++)
3014 if (!strcmp(line
, (char *)vector_slot(comps
, i
)))
3016 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, line
));
3019 static void vtysh_autocomplete(vector comps
, struct cmd_token
*token
)
3024 snprintf(accmd
, sizeof(accmd
), "autocomplete %d %s %s", token
->type
,
3025 token
->text
, token
->varname
? token
->varname
: "-");
3027 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3028 vtysh_client_run_all(&vtysh_client
[i
], accmd
, 1, NULL
,
3029 vtysh_ac_line
, comps
);
3032 static const struct cmd_variable_handler vtysh_var_handler
[] = {
3036 .completions
= vtysh_autocomplete
},
3037 {.completions
= NULL
}};
3041 if (outputfile
!= stdout
)
3045 void vtysh_init_vty(void)
3047 /* Make vty structure. */
3049 vty
->type
= VTY_SHELL
;
3050 vty
->node
= VIEW_NODE
;
3052 /* set default output */
3053 outputfile
= stdout
;
3055 /* Initialize commands. */
3057 cmd_variable_handler_register(vtysh_var_handler
);
3059 /* Install nodes. */
3060 install_node(&bgp_node
, NULL
);
3061 install_node(&rip_node
, NULL
);
3062 install_node(&interface_node
, NULL
);
3063 install_node(&pw_node
, NULL
);
3064 install_node(&link_params_node
, NULL
);
3065 install_node(&logicalrouter_node
, NULL
);
3066 install_node(&vrf_node
, NULL
);
3067 install_node(&rmap_node
, NULL
);
3068 install_node(&zebra_node
, NULL
);
3069 install_node(&bgp_vpnv4_node
, NULL
);
3070 install_node(&bgp_vpnv6_node
, NULL
);
3071 install_node(&bgp_ipv4_node
, NULL
);
3072 install_node(&bgp_ipv4m_node
, NULL
);
3073 install_node(&bgp_ipv4l_node
, NULL
);
3074 install_node(&bgp_ipv6_node
, NULL
);
3075 install_node(&bgp_ipv6m_node
, NULL
);
3076 install_node(&bgp_ipv6l_node
, NULL
);
3077 install_node(&bgp_vrf_policy_node
, NULL
);
3078 install_node(&bgp_evpn_node
, NULL
);
3079 install_node(&bgp_evpn_vni_node
, NULL
);
3080 install_node(&bgp_vnc_defaults_node
, NULL
);
3081 install_node(&bgp_vnc_nve_group_node
, NULL
);
3082 install_node(&bgp_vnc_l2_group_node
, NULL
);
3083 install_node(&ospf_node
, NULL
);
3084 install_node(&eigrp_node
, NULL
);
3085 install_node(&babel_node
, NULL
);
3086 install_node(&ripng_node
, NULL
);
3087 install_node(&ospf6_node
, NULL
);
3088 install_node(&ldp_node
, NULL
);
3089 install_node(&ldp_ipv4_node
, NULL
);
3090 install_node(&ldp_ipv6_node
, NULL
);
3091 install_node(&ldp_ipv4_iface_node
, NULL
);
3092 install_node(&ldp_ipv6_iface_node
, NULL
);
3093 install_node(&ldp_l2vpn_node
, NULL
);
3094 install_node(&ldp_pseudowire_node
, NULL
);
3095 install_node(&keychain_node
, NULL
);
3096 install_node(&keychain_key_node
, NULL
);
3097 install_node(&isis_node
, NULL
);
3098 install_node(&vty_node
, NULL
);
3099 #if defined(HAVE_RPKI)
3100 install_node(&rpki_node
, NULL
);
3103 struct cmd_node
*node
;
3104 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
3105 node
= vector_slot(cmdvec
, i
);
3106 if (!node
|| node
->node
== VIEW_NODE
)
3108 vtysh_install_default(node
->node
);
3111 install_element(VIEW_NODE
, &vtysh_enable_cmd
);
3112 install_element(ENABLE_NODE
, &vtysh_config_terminal_cmd
);
3113 install_element(ENABLE_NODE
, &vtysh_disable_cmd
);
3115 /* "exit" command. */
3116 install_element(VIEW_NODE
, &vtysh_exit_all_cmd
);
3117 install_element(CONFIG_NODE
, &vtysh_exit_all_cmd
);
3118 install_element(VIEW_NODE
, &vtysh_quit_all_cmd
);
3119 install_element(CONFIG_NODE
, &vtysh_quit_all_cmd
);
3120 install_element(RIP_NODE
, &vtysh_exit_ripd_cmd
);
3121 install_element(RIP_NODE
, &vtysh_quit_ripd_cmd
);
3122 install_element(RIPNG_NODE
, &vtysh_exit_ripngd_cmd
);
3123 install_element(RIPNG_NODE
, &vtysh_quit_ripngd_cmd
);
3124 install_element(OSPF_NODE
, &vtysh_exit_ospfd_cmd
);
3125 install_element(OSPF_NODE
, &vtysh_quit_ospfd_cmd
);
3126 install_element(EIGRP_NODE
, &vtysh_exit_eigrpd_cmd
);
3127 install_element(EIGRP_NODE
, &vtysh_quit_eigrpd_cmd
);
3128 install_element(BABEL_NODE
, &vtysh_exit_babeld_cmd
);
3129 install_element(BABEL_NODE
, &vtysh_quit_babeld_cmd
);
3130 install_element(OSPF6_NODE
, &vtysh_exit_ospf6d_cmd
);
3131 install_element(OSPF6_NODE
, &vtysh_quit_ospf6d_cmd
);
3132 #if defined(HAVE_LDPD)
3133 install_element(LDP_NODE
, &vtysh_exit_ldpd_cmd
);
3134 install_element(LDP_NODE
, &vtysh_quit_ldpd_cmd
);
3135 install_element(LDP_IPV4_NODE
, &vtysh_exit_ldpd_cmd
);
3136 install_element(LDP_IPV4_NODE
, &vtysh_quit_ldpd_cmd
);
3137 install_element(LDP_IPV4_NODE
, &ldp_exit_address_family_cmd
);
3138 install_element(LDP_IPV6_NODE
, &vtysh_exit_ldpd_cmd
);
3139 install_element(LDP_IPV6_NODE
, &vtysh_quit_ldpd_cmd
);
3140 install_element(LDP_IPV6_NODE
, &ldp_exit_address_family_cmd
);
3141 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
3142 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
3143 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
3144 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
3145 install_element(LDP_L2VPN_NODE
, &vtysh_exit_ldpd_cmd
);
3146 install_element(LDP_L2VPN_NODE
, &vtysh_quit_ldpd_cmd
);
3147 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_exit_ldpd_cmd
);
3148 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_quit_ldpd_cmd
);
3150 install_element(BGP_NODE
, &vtysh_exit_bgpd_cmd
);
3151 install_element(BGP_NODE
, &vtysh_quit_bgpd_cmd
);
3152 install_element(BGP_VPNV4_NODE
, &vtysh_exit_bgpd_cmd
);
3153 install_element(BGP_VPNV4_NODE
, &vtysh_quit_bgpd_cmd
);
3154 install_element(BGP_VPNV6_NODE
, &vtysh_exit_bgpd_cmd
);
3155 install_element(BGP_VPNV6_NODE
, &vtysh_quit_bgpd_cmd
);
3156 install_element(BGP_IPV4_NODE
, &vtysh_exit_bgpd_cmd
);
3157 install_element(BGP_IPV4_NODE
, &vtysh_quit_bgpd_cmd
);
3158 install_element(BGP_IPV4M_NODE
, &vtysh_exit_bgpd_cmd
);
3159 install_element(BGP_IPV4M_NODE
, &vtysh_quit_bgpd_cmd
);
3160 install_element(BGP_IPV4L_NODE
, &vtysh_exit_bgpd_cmd
);
3161 install_element(BGP_IPV4L_NODE
, &vtysh_quit_bgpd_cmd
);
3162 install_element(BGP_IPV6_NODE
, &vtysh_exit_bgpd_cmd
);
3163 install_element(BGP_IPV6_NODE
, &vtysh_quit_bgpd_cmd
);
3164 install_element(BGP_IPV6M_NODE
, &vtysh_exit_bgpd_cmd
);
3165 install_element(BGP_IPV6M_NODE
, &vtysh_quit_bgpd_cmd
);
3166 install_element(BGP_EVPN_NODE
, &vtysh_quit_bgpd_cmd
);
3167 install_element(BGP_EVPN_NODE
, &vtysh_exit_bgpd_cmd
);
3168 install_element(BGP_EVPN_VNI_NODE
, &vtysh_exit_bgpd_cmd
);
3169 install_element(BGP_EVPN_VNI_NODE
, &vtysh_quit_bgpd_cmd
);
3170 install_element(BGP_IPV6L_NODE
, &vtysh_exit_bgpd_cmd
);
3171 install_element(BGP_IPV6L_NODE
, &vtysh_quit_bgpd_cmd
);
3172 #if defined(ENABLE_BGP_VNC)
3173 install_element(BGP_VRF_POLICY_NODE
, &vtysh_exit_bgpd_cmd
);
3174 install_element(BGP_VRF_POLICY_NODE
, &vtysh_quit_bgpd_cmd
);
3175 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_exit_bgpd_cmd
);
3176 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_quit_bgpd_cmd
);
3177 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
3178 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
3179 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
3180 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
3182 install_element(ISIS_NODE
, &vtysh_exit_isisd_cmd
);
3183 install_element(ISIS_NODE
, &vtysh_quit_isisd_cmd
);
3184 install_element(KEYCHAIN_NODE
, &vtysh_exit_ripd_cmd
);
3185 install_element(KEYCHAIN_NODE
, &vtysh_quit_ripd_cmd
);
3186 install_element(KEYCHAIN_KEY_NODE
, &vtysh_exit_ripd_cmd
);
3187 install_element(KEYCHAIN_KEY_NODE
, &vtysh_quit_ripd_cmd
);
3188 install_element(RMAP_NODE
, &vtysh_exit_rmap_cmd
);
3189 install_element(RMAP_NODE
, &vtysh_quit_rmap_cmd
);
3190 install_element(VTY_NODE
, &vtysh_exit_line_vty_cmd
);
3191 install_element(VTY_NODE
, &vtysh_quit_line_vty_cmd
);
3193 /* "end" command. */
3194 install_element(CONFIG_NODE
, &vtysh_end_all_cmd
);
3195 install_element(ENABLE_NODE
, &vtysh_end_all_cmd
);
3196 install_element(RIP_NODE
, &vtysh_end_all_cmd
);
3197 install_element(RIPNG_NODE
, &vtysh_end_all_cmd
);
3198 install_element(OSPF_NODE
, &vtysh_end_all_cmd
);
3199 install_element(EIGRP_NODE
, &vtysh_end_all_cmd
);
3200 install_element(BABEL_NODE
, &vtysh_end_all_cmd
);
3201 install_element(OSPF6_NODE
, &vtysh_end_all_cmd
);
3202 install_element(LDP_NODE
, &vtysh_end_all_cmd
);
3203 install_element(LDP_IPV4_NODE
, &vtysh_end_all_cmd
);
3204 install_element(LDP_IPV6_NODE
, &vtysh_end_all_cmd
);
3205 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_end_all_cmd
);
3206 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_end_all_cmd
);
3207 install_element(LDP_L2VPN_NODE
, &vtysh_end_all_cmd
);
3208 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_end_all_cmd
);
3209 install_element(BGP_NODE
, &vtysh_end_all_cmd
);
3210 install_element(BGP_IPV4_NODE
, &vtysh_end_all_cmd
);
3211 install_element(BGP_IPV4M_NODE
, &vtysh_end_all_cmd
);
3212 install_element(BGP_IPV4L_NODE
, &vtysh_end_all_cmd
);
3213 install_element(BGP_VPNV4_NODE
, &vtysh_end_all_cmd
);
3214 install_element(BGP_VPNV6_NODE
, &vtysh_end_all_cmd
);
3215 install_element(BGP_IPV6_NODE
, &vtysh_end_all_cmd
);
3216 install_element(BGP_IPV6M_NODE
, &vtysh_end_all_cmd
);
3217 install_element(BGP_IPV6L_NODE
, &vtysh_end_all_cmd
);
3218 install_element(BGP_VRF_POLICY_NODE
, &vtysh_end_all_cmd
);
3219 install_element(BGP_EVPN_NODE
, &vtysh_end_all_cmd
);
3220 install_element(BGP_EVPN_VNI_NODE
, &vtysh_end_all_cmd
);
3221 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_end_all_cmd
);
3222 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_end_all_cmd
);
3223 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_end_all_cmd
);
3224 install_element(ISIS_NODE
, &vtysh_end_all_cmd
);
3225 install_element(KEYCHAIN_NODE
, &vtysh_end_all_cmd
);
3226 install_element(KEYCHAIN_KEY_NODE
, &vtysh_end_all_cmd
);
3227 install_element(RMAP_NODE
, &vtysh_end_all_cmd
);
3228 install_element(VTY_NODE
, &vtysh_end_all_cmd
);
3230 install_element(INTERFACE_NODE
, &vtysh_interface_desc_cmd
);
3231 install_element(INTERFACE_NODE
, &vtysh_no_interface_desc_cmd
);
3232 install_element(INTERFACE_NODE
, &vtysh_end_all_cmd
);
3233 install_element(INTERFACE_NODE
, &vtysh_exit_interface_cmd
);
3234 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);
3235 install_element(LINK_PARAMS_NODE
, &vtysh_end_all_cmd
);
3236 install_element(LINK_PARAMS_NODE
, &vtysh_exit_interface_cmd
);
3237 install_element(INTERFACE_NODE
, &vtysh_quit_interface_cmd
);
3239 install_element(PW_NODE
, &vtysh_end_all_cmd
);
3240 install_element(PW_NODE
, &vtysh_exit_interface_cmd
);
3241 install_element(PW_NODE
, &vtysh_quit_interface_cmd
);
3243 install_element(LOGICALROUTER_NODE
, &vtysh_end_all_cmd
);
3245 install_element(CONFIG_NODE
, &vtysh_logicalrouter_cmd
);
3246 install_element(CONFIG_NODE
, &vtysh_no_logicalrouter_cmd
);
3247 install_element(LOGICALROUTER_NODE
, &vtysh_exit_logicalrouter_cmd
);
3248 install_element(LOGICALROUTER_NODE
, &vtysh_quit_logicalrouter_cmd
);
3250 install_element(VRF_NODE
, &vtysh_end_all_cmd
);
3251 install_element(VRF_NODE
, &vtysh_exit_vrf_cmd
);
3252 install_element(VRF_NODE
, &vtysh_quit_vrf_cmd
);
3254 install_element(CONFIG_NODE
, &router_eigrp_cmd
);
3255 install_element(CONFIG_NODE
, &router_babel_cmd
);
3256 install_element(CONFIG_NODE
, &router_rip_cmd
);
3257 install_element(CONFIG_NODE
, &router_ripng_cmd
);
3258 install_element(CONFIG_NODE
, &router_ospf_cmd
);
3259 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
3260 #if defined(HAVE_LDPD)
3261 install_element(CONFIG_NODE
, &ldp_mpls_ldp_cmd
);
3262 install_element(LDP_NODE
, &ldp_address_family_ipv4_cmd
);
3263 install_element(LDP_NODE
, &ldp_address_family_ipv6_cmd
);
3264 install_element(LDP_IPV4_NODE
, &ldp_interface_ifname_cmd
);
3265 install_element(LDP_IPV6_NODE
, &ldp_interface_ifname_cmd
);
3266 install_element(CONFIG_NODE
, &ldp_l2vpn_word_type_vpls_cmd
);
3267 install_element(LDP_L2VPN_NODE
, &ldp_member_pseudowire_ifname_cmd
);
3269 install_element(CONFIG_NODE
, &router_isis_cmd
);
3270 install_element(CONFIG_NODE
, &router_bgp_cmd
);
3271 install_element(BGP_NODE
, &address_family_vpnv4_cmd
);
3272 install_element(BGP_NODE
, &address_family_vpnv6_cmd
);
3273 #if defined(ENABLE_BGP_VNC)
3274 install_element(BGP_NODE
, &vnc_vrf_policy_cmd
);
3275 install_element(BGP_NODE
, &vnc_defaults_cmd
);
3276 install_element(BGP_NODE
, &vnc_nve_group_cmd
);
3277 install_element(BGP_NODE
, &vnc_l2_group_cmd
);
3279 install_element(BGP_NODE
, &address_family_ipv4_cmd
);
3280 install_element(BGP_NODE
, &address_family_ipv4_multicast_cmd
);
3281 install_element(BGP_NODE
, &address_family_ipv4_vpn_cmd
);
3282 install_element(BGP_NODE
, &address_family_ipv4_labeled_unicast_cmd
);
3283 install_element(BGP_NODE
, &address_family_ipv6_cmd
);
3284 install_element(BGP_NODE
, &address_family_ipv6_multicast_cmd
);
3285 install_element(BGP_NODE
, &address_family_ipv6_vpn_cmd
);
3286 install_element(BGP_NODE
, &address_family_ipv6_labeled_unicast_cmd
);
3287 install_element(BGP_NODE
, &address_family_evpn_cmd
);
3288 #if defined(HAVE_CUMULUS)
3289 install_element(BGP_NODE
, &address_family_evpn2_cmd
);
3291 install_element(BGP_VPNV4_NODE
, &exit_address_family_cmd
);
3292 install_element(BGP_VPNV6_NODE
, &exit_address_family_cmd
);
3293 install_element(BGP_IPV4_NODE
, &exit_address_family_cmd
);
3294 install_element(BGP_IPV4M_NODE
, &exit_address_family_cmd
);
3295 install_element(BGP_IPV4L_NODE
, &exit_address_family_cmd
);
3296 install_element(BGP_IPV6_NODE
, &exit_address_family_cmd
);
3297 install_element(BGP_IPV6M_NODE
, &exit_address_family_cmd
);
3298 install_element(BGP_EVPN_NODE
, &exit_address_family_cmd
);
3299 install_element(BGP_IPV6L_NODE
, &exit_address_family_cmd
);
3301 #if defined(HAVE_RPKI)
3302 install_element(CONFIG_NODE
, &rpki_cmd
);
3303 install_element(RPKI_NODE
, &rpki_exit_cmd
);
3304 install_element(RPKI_NODE
, &rpki_quit_cmd
);
3305 install_element(RPKI_NODE
, &vtysh_end_all_cmd
);
3309 install_element(BGP_EVPN_NODE
, &bgp_evpn_vni_cmd
);
3310 install_element(BGP_EVPN_VNI_NODE
, &exit_vni_cmd
);
3312 install_element(BGP_VRF_POLICY_NODE
, &exit_vrf_policy_cmd
);
3313 install_element(BGP_VNC_DEFAULTS_NODE
, &exit_vnc_config_cmd
);
3314 install_element(BGP_VNC_NVE_GROUP_NODE
, &exit_vnc_config_cmd
);
3315 install_element(BGP_VNC_L2_GROUP_NODE
, &exit_vnc_config_cmd
);
3317 install_element(CONFIG_NODE
, &key_chain_cmd
);
3318 install_element(CONFIG_NODE
, &vtysh_route_map_cmd
);
3319 install_element(CONFIG_NODE
, &vtysh_line_vty_cmd
);
3320 install_element(KEYCHAIN_NODE
, &key_cmd
);
3321 install_element(KEYCHAIN_NODE
, &key_chain_cmd
);
3322 install_element(KEYCHAIN_KEY_NODE
, &key_chain_cmd
);
3323 install_element(CONFIG_NODE
, &vtysh_interface_cmd
);
3324 install_element(CONFIG_NODE
, &vtysh_no_interface_cmd
);
3325 install_element(CONFIG_NODE
, &vtysh_no_interface_vrf_cmd
);
3326 install_element(CONFIG_NODE
, &vtysh_pseudowire_cmd
);
3327 install_element(INTERFACE_NODE
, &vtysh_link_params_cmd
);
3328 install_element(ENABLE_NODE
, &vtysh_show_running_config_cmd
);
3329 install_element(ENABLE_NODE
, &vtysh_copy_running_config_cmd
);
3331 install_element(CONFIG_NODE
, &vtysh_vrf_cmd
);
3332 install_element(CONFIG_NODE
, &vtysh_no_vrf_cmd
);
3334 /* "write terminal" command. */
3335 install_element(ENABLE_NODE
, &vtysh_write_terminal_cmd
);
3337 install_element(CONFIG_NODE
, &vtysh_integrated_config_cmd
);
3338 install_element(CONFIG_NODE
, &no_vtysh_integrated_config_cmd
);
3340 /* "write memory" command. */
3341 install_element(ENABLE_NODE
, &vtysh_write_memory_cmd
);
3343 install_element(VIEW_NODE
, &vtysh_terminal_length_cmd
);
3344 install_element(VIEW_NODE
, &vtysh_terminal_no_length_cmd
);
3345 install_element(VIEW_NODE
, &vtysh_show_daemons_cmd
);
3347 install_element(VIEW_NODE
, &vtysh_ping_cmd
);
3348 install_element(VIEW_NODE
, &vtysh_ping_ip_cmd
);
3349 install_element(VIEW_NODE
, &vtysh_traceroute_cmd
);
3350 install_element(VIEW_NODE
, &vtysh_traceroute_ip_cmd
);
3351 install_element(VIEW_NODE
, &vtysh_mtrace_cmd
);
3352 install_element(VIEW_NODE
, &vtysh_ping6_cmd
);
3353 install_element(VIEW_NODE
, &vtysh_traceroute6_cmd
);
3354 #if defined(HAVE_SHELL_ACCESS)
3355 install_element(VIEW_NODE
, &vtysh_telnet_cmd
);
3356 install_element(VIEW_NODE
, &vtysh_telnet_port_cmd
);
3357 install_element(VIEW_NODE
, &vtysh_ssh_cmd
);
3359 #if defined(HAVE_SHELL_ACCESS)
3360 install_element(ENABLE_NODE
, &vtysh_start_shell_cmd
);
3361 install_element(ENABLE_NODE
, &vtysh_start_bash_cmd
);
3362 install_element(ENABLE_NODE
, &vtysh_start_zsh_cmd
);
3366 install_element(VIEW_NODE
, &vtysh_show_debugging_cmd
);
3367 install_element(VIEW_NODE
, &vtysh_show_debugging_hashtable_cmd
);
3368 install_element(VIEW_NODE
, &vtysh_debug_all_cmd
);
3369 install_element(CONFIG_NODE
, &vtysh_debug_all_cmd
);
3371 /* misc lib show commands */
3372 install_element(VIEW_NODE
, &vtysh_show_memory_cmd
);
3373 install_element(VIEW_NODE
, &vtysh_show_modules_cmd
);
3374 install_element(VIEW_NODE
, &vtysh_show_work_queues_cmd
);
3375 install_element(VIEW_NODE
, &vtysh_show_work_queues_daemon_cmd
);
3376 install_element(VIEW_NODE
, &vtysh_show_thread_cmd
);
3379 install_element(VIEW_NODE
, &vtysh_show_logging_cmd
);
3380 install_element(CONFIG_NODE
, &vtysh_log_stdout_cmd
);
3381 install_element(CONFIG_NODE
, &vtysh_log_stdout_level_cmd
);
3382 install_element(CONFIG_NODE
, &no_vtysh_log_stdout_cmd
);
3383 install_element(CONFIG_NODE
, &vtysh_log_file_cmd
);
3384 install_element(CONFIG_NODE
, &vtysh_log_file_level_cmd
);
3385 install_element(CONFIG_NODE
, &no_vtysh_log_file_cmd
);
3386 install_element(CONFIG_NODE
, &vtysh_log_monitor_cmd
);
3387 install_element(CONFIG_NODE
, &no_vtysh_log_monitor_cmd
);
3388 install_element(CONFIG_NODE
, &vtysh_log_syslog_cmd
);
3389 install_element(CONFIG_NODE
, &no_vtysh_log_syslog_cmd
);
3390 install_element(CONFIG_NODE
, &vtysh_log_trap_cmd
);
3391 install_element(CONFIG_NODE
, &no_vtysh_log_trap_cmd
);
3392 install_element(CONFIG_NODE
, &vtysh_log_facility_cmd
);
3393 install_element(CONFIG_NODE
, &no_vtysh_log_facility_cmd
);
3394 install_element(CONFIG_NODE
, &vtysh_log_record_priority_cmd
);
3395 install_element(CONFIG_NODE
, &no_vtysh_log_record_priority_cmd
);
3396 install_element(CONFIG_NODE
, &vtysh_log_timestamp_precision_cmd
);
3397 install_element(CONFIG_NODE
, &no_vtysh_log_timestamp_precision_cmd
);
3399 install_element(CONFIG_NODE
, &vtysh_service_password_encrypt_cmd
);
3400 install_element(CONFIG_NODE
, &no_vtysh_service_password_encrypt_cmd
);
3402 install_element(CONFIG_NODE
, &vtysh_password_cmd
);
3403 install_element(CONFIG_NODE
, &vtysh_enable_password_cmd
);
3404 install_element(CONFIG_NODE
, &no_vtysh_enable_password_cmd
);