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
->fd
= 0; /* stdout */
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
);
752 CMD_ERR_NO_MATCH
; /* once we have an error, we
753 remember & return that */
755 case CMD_ERR_INCOMPLETE
:
757 "line %d: %% Command incomplete[%d]: %s\n",
758 lineno
, vty
->node
, vty
->buf
);
759 retcode
= CMD_ERR_INCOMPLETE
; /* once we have an error,
763 case CMD_SUCCESS_DAEMON
: {
765 int cmd_stat
= CMD_SUCCESS
;
767 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
768 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
769 cmd_stat
= vtysh_client_execute(
770 &vtysh_client
[i
], vty
->buf
,
773 * CMD_WARNING - Can mean that the
775 * parsed successfully but it was
777 * in a few spots. As such if we
779 * CMD_WARNING from a daemon we
781 * talking to the other daemons for the
785 if (cmd_stat
!= CMD_SUCCESS
786 && cmd_stat
!= CMD_WARNING
) {
788 "line %d: Failure to communicate[%d] to %s, line: %s\n",
790 vtysh_client
[i
].name
,
797 if (cmd_stat
!= CMD_SUCCESS
)
801 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
809 /* We don't care about the point of the cursor when '?' is typed. */
810 static int vtysh_rl_describe(void)
817 struct cmd_token
*token
;
819 vline
= cmd_make_strvec(rl_line_buffer
);
821 /* In case of '> ?'. */
823 vline
= vector_init(1);
824 vector_set(vline
, NULL
);
825 } else if (rl_end
&& isspace((int)rl_line_buffer
[rl_end
- 1]))
826 vector_set(vline
, NULL
);
828 fprintf(stdout
, "\n");
830 describe
= cmd_describe_command(vline
, vty
, &ret
);
832 /* Ambiguous and no match error. */
834 case CMD_ERR_AMBIGUOUS
:
835 cmd_free_strvec(vline
);
836 vector_free(describe
);
837 fprintf(stdout
, "%% Ambiguous command.\n");
841 case CMD_ERR_NO_MATCH
:
842 cmd_free_strvec(vline
);
844 vector_free(describe
);
845 fprintf(stdout
, "%% There is no matched command.\n");
851 /* Get width of command string. */
853 for (i
= 0; i
< vector_active(describe
); i
++)
854 if ((token
= vector_slot(describe
, i
)) != NULL
) {
855 if (token
->text
[0] == '\0')
858 int len
= strlen(token
->text
);
864 for (i
= 0; i
< vector_active(describe
); i
++)
865 if ((token
= vector_slot(describe
, i
)) != NULL
) {
867 fprintf(stdout
, " %-s\n", token
->text
);
869 fprintf(stdout
, " %-*s %s\n", width
,
870 token
->text
, token
->desc
);
872 if (IS_VARYING_TOKEN(token
->type
)) {
873 const char *ref
= vector_slot(
874 vline
, vector_active(vline
) - 1);
876 vector varcomps
= vector_init(VECTOR_MIN_SIZE
);
877 cmd_variable_complete(token
, ref
, varcomps
);
879 if (vector_active(varcomps
) > 0) {
881 rl_get_screen_size(&rows
, &cols
);
883 char *ac
= cmd_variable_comp2str(
885 fprintf(stdout
, "%s\n", ac
);
886 XFREE(MTYPE_TMP
, ac
);
889 vector_free(varcomps
);
893 cmd_free_strvec(vline
);
894 vector_free(describe
);
901 /* Result of cmd_complete_command() call will be stored here
902 * and used in new_completion() in order to put the space in
903 * correct places only. */
906 static char *command_generator(const char *text
, int state
)
909 static char **matched
= NULL
;
910 static int index
= 0;
916 if (vty
->node
== AUTH_NODE
|| vty
->node
== AUTH_ENABLE_NODE
)
919 vline
= cmd_make_strvec(rl_line_buffer
);
923 if (rl_end
&& isspace((int)rl_line_buffer
[rl_end
- 1]))
924 vector_set(vline
, NULL
);
926 matched
= cmd_complete_command(vline
, vty
, &complete_status
);
927 cmd_free_strvec(vline
);
930 if (matched
&& matched
[index
])
931 /* this is free()'d by readline, but we leak 1 count of
932 * MTYPE_COMPLETION */
933 return matched
[index
++];
935 XFREE(MTYPE_TMP
, matched
);
941 static char **new_completion(char *text
, int start
, int end
)
945 matches
= rl_completion_matches(text
, command_generator
);
949 if (complete_status
!= CMD_COMPLETE_FULL_MATCH
)
950 /* only append a space on full match */
951 rl_completion_append_character
= '\0';
957 /* Vty node structures. */
958 static struct cmd_node bgp_node
= {
959 BGP_NODE
, "%s(config-router)# ",
962 static struct cmd_node rip_node
= {
963 RIP_NODE
, "%s(config-router)# ",
966 static struct cmd_node isis_node
= {
967 ISIS_NODE
, "%s(config-router)# ",
970 static struct cmd_node interface_node
= {
971 INTERFACE_NODE
, "%s(config-if)# ",
974 static struct cmd_node pw_node
= {
975 PW_NODE
, "%s(config-pw)# ",
978 static struct cmd_node ns_node
= {
979 NS_NODE
, "%s(config-logical-router)# ",
982 static struct cmd_node vrf_node
= {
983 VRF_NODE
, "%s(config-vrf)# ",
986 static struct cmd_node rmap_node
= {RMAP_NODE
, "%s(config-route-map)# "};
988 static struct cmd_node zebra_node
= {ZEBRA_NODE
, "%s(config-router)# "};
990 static struct cmd_node bgp_vpnv4_node
= {BGP_VPNV4_NODE
,
991 "%s(config-router-af)# "};
993 static struct cmd_node bgp_vpnv6_node
= {BGP_VPNV6_NODE
,
994 "%s(config-router-af)# "};
996 static struct cmd_node bgp_ipv4_node
= {BGP_IPV4_NODE
,
997 "%s(config-router-af)# "};
999 static struct cmd_node bgp_ipv4m_node
= {BGP_IPV4M_NODE
,
1000 "%s(config-router-af)# "};
1002 static struct cmd_node bgp_ipv4l_node
= {BGP_IPV4L_NODE
,
1003 "%s(config-router-af)# "};
1005 static struct cmd_node bgp_ipv6_node
= {BGP_IPV6_NODE
,
1006 "%s(config-router-af)# "};
1008 static struct cmd_node bgp_ipv6m_node
= {BGP_IPV6M_NODE
,
1009 "%s(config-router-af)# "};
1011 static struct cmd_node bgp_evpn_node
= {BGP_EVPN_NODE
,
1012 "%s(config-router-af)# "};
1014 static struct cmd_node bgp_evpn_vni_node
= {BGP_EVPN_VNI_NODE
,
1015 "%s(config-router-af-vni)# "};
1017 static struct cmd_node bgp_ipv6l_node
= {BGP_IPV6L_NODE
,
1018 "%s(config-router-af)# "};
1020 static struct cmd_node bgp_vnc_defaults_node
= {
1021 BGP_VNC_DEFAULTS_NODE
, "%s(config-router-vnc-defaults)# "};
1023 static struct cmd_node bgp_vnc_nve_group_node
= {
1024 BGP_VNC_NVE_GROUP_NODE
, "%s(config-router-vnc-nve-group)# "};
1026 static struct cmd_node bgp_vrf_policy_node
= {BGP_VRF_POLICY_NODE
,
1027 "%s(config-router-vrf-policy)# "};
1029 static struct cmd_node bgp_vnc_l2_group_node
= {
1030 BGP_VNC_L2_GROUP_NODE
, "%s(config-router-vnc-l2-group)# "};
1032 static struct cmd_node ospf_node
= {OSPF_NODE
, "%s(config-router)# "};
1034 static struct cmd_node eigrp_node
= {EIGRP_NODE
, "%s(config-router)# "};
1036 static struct cmd_node babel_node
= {BABEL_NODE
, "%s(config-router)# "};
1038 static struct cmd_node ripng_node
= {RIPNG_NODE
, "%s(config-router)# "};
1040 static struct cmd_node ospf6_node
= {OSPF6_NODE
, "%s(config-ospf6)# "};
1042 static struct cmd_node ldp_node
= {LDP_NODE
, "%s(config-ldp)# "};
1044 static struct cmd_node ldp_ipv4_node
= {LDP_IPV4_NODE
, "%s(config-ldp-af)# "};
1046 static struct cmd_node ldp_ipv6_node
= {LDP_IPV6_NODE
, "%s(config-ldp-af)# "};
1048 static struct cmd_node ldp_ipv4_iface_node
= {LDP_IPV4_IFACE_NODE
,
1049 "%s(config-ldp-af-if)# "};
1051 static struct cmd_node ldp_ipv6_iface_node
= {LDP_IPV6_IFACE_NODE
,
1052 "%s(config-ldp-af-if)# "};
1054 static struct cmd_node ldp_l2vpn_node
= {LDP_L2VPN_NODE
, "%s(config-l2vpn)# "};
1056 static struct cmd_node ldp_pseudowire_node
= {LDP_PSEUDOWIRE_NODE
,
1057 "%s(config-l2vpn-pw)# "};
1059 static struct cmd_node keychain_node
= {KEYCHAIN_NODE
, "%s(config-keychain)# "};
1061 static struct cmd_node keychain_key_node
= {KEYCHAIN_KEY_NODE
,
1062 "%s(config-keychain-key)# "};
1064 struct cmd_node link_params_node
= {
1065 LINK_PARAMS_NODE
, "%s(config-link-params)# ",
1068 #if defined(HAVE_RPKI)
1069 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
1072 /* Defined in lib/vty.c */
1073 extern struct cmd_node vty_node
;
1075 /* When '^Z' is received from vty, move down to the enable mode. */
1076 static int vtysh_end(void)
1078 switch (vty
->node
) {
1081 /* Nothing to do. */
1084 vty
->node
= ENABLE_NODE
;
1090 DEFUNSH(VTYSH_REALLYALL
, vtysh_end_all
, vtysh_end_all_cmd
, "end",
1091 "End current mode and change to enable mode\n")
1096 DEFUNSH(VTYSH_BGPD
, router_bgp
, router_bgp_cmd
,
1097 "router bgp [(1-4294967295) [<view|vrf> WORD]]",
1098 ROUTER_STR BGP_STR AS_STR
1099 "BGP view\nBGP VRF\n"
1102 vty
->node
= BGP_NODE
;
1106 DEFUNSH(VTYSH_BGPD
, address_family_vpnv4
, address_family_vpnv4_cmd
,
1107 "address-family vpnv4 [unicast]",
1108 "Enter Address Family command mode\n"
1110 "Address Family modifier\n")
1112 vty
->node
= BGP_VPNV4_NODE
;
1116 DEFUNSH(VTYSH_BGPD
, address_family_vpnv6
, address_family_vpnv6_cmd
,
1117 "address-family vpnv6 [unicast]",
1118 "Enter Address Family command mode\n"
1120 "Address Family modifier\n")
1122 vty
->node
= BGP_VPNV6_NODE
;
1126 DEFUNSH(VTYSH_BGPD
, address_family_ipv4
, address_family_ipv4_cmd
,
1127 "address-family ipv4 [unicast]",
1128 "Enter Address Family command mode\n"
1130 "Address Family Modifier\n")
1132 vty
->node
= BGP_IPV4_NODE
;
1136 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_multicast
,
1137 address_family_ipv4_multicast_cmd
, "address-family ipv4 multicast",
1138 "Enter Address Family command mode\n"
1140 "Address Family modifier\n")
1142 vty
->node
= BGP_IPV4M_NODE
;
1146 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_vpn
, address_family_ipv4_vpn_cmd
,
1147 "address-family ipv4 vpn",
1148 "Enter Address Family command mode\n"
1150 "Address Family modifier\n")
1152 vty
->node
= BGP_VPNV4_NODE
;
1156 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_labeled_unicast
,
1157 address_family_ipv4_labeled_unicast_cmd
,
1158 "address-family ipv4 labeled-unicast",
1159 "Enter Address Family command mode\n"
1161 "Address Family modifier\n")
1163 vty
->node
= BGP_IPV4L_NODE
;
1167 DEFUNSH(VTYSH_BGPD
, address_family_ipv6
, address_family_ipv6_cmd
,
1168 "address-family ipv6 [unicast]",
1169 "Enter Address Family command mode\n"
1171 "Address Family modifier\n")
1173 vty
->node
= BGP_IPV6_NODE
;
1177 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_multicast
,
1178 address_family_ipv6_multicast_cmd
, "address-family ipv6 multicast",
1179 "Enter Address Family command mode\n"
1181 "Address Family modifier\n")
1183 vty
->node
= BGP_IPV6M_NODE
;
1187 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_vpn
, address_family_ipv6_vpn_cmd
,
1188 "address-family ipv6 vpn",
1189 "Enter Address Family command mode\n"
1191 "Address Family modifier\n")
1193 vty
->node
= BGP_VPNV6_NODE
;
1197 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_labeled_unicast
,
1198 address_family_ipv6_labeled_unicast_cmd
,
1199 "address-family ipv6 labeled-unicast",
1200 "Enter Address Family command mode\n"
1202 "Address Family modifier\n")
1204 vty
->node
= BGP_IPV6L_NODE
;
1208 #if defined(HAVE_RPKI)
1213 "Enable rpki and enter rpki configuration mode\n")
1215 vty
->node
= RPKI_NODE
;
1223 "Exit current mode and down to previous mode\n")
1225 vty
->node
= CONFIG_NODE
;
1233 "Exit current mode and down to previous mode\n")
1235 return rpki_exit(self
, vty
, argc
, argv
);
1239 DEFUNSH(VTYSH_BGPD
, address_family_evpn
, address_family_evpn_cmd
,
1240 "address-family <l2vpn evpn>",
1241 "Enter Address Family command mode\n"
1243 "Address Family modifier\n")
1245 vty
->node
= BGP_EVPN_NODE
;
1249 #if defined(HAVE_CUMULUS)
1250 DEFUNSH_HIDDEN(VTYSH_BGPD
, address_family_evpn2
, address_family_evpn2_cmd
,
1251 "address-family evpn",
1252 "Enter Address Family command mode\n"
1253 "EVPN Address family\n")
1255 vty
->node
= BGP_EVPN_NODE
;
1260 DEFUNSH(VTYSH_BGPD
, bgp_evpn_vni
, bgp_evpn_vni_cmd
, "vni (1-16777215)",
1261 "VXLAN Network Identifier\n"
1264 vty
->node
= BGP_EVPN_VNI_NODE
;
1268 #if defined(ENABLE_BGP_VNC)
1269 DEFUNSH(VTYSH_BGPD
, vnc_defaults
, vnc_defaults_cmd
, "vnc defaults",
1270 "VNC/RFP related configuration\n"
1271 "Configure default NVE group\n")
1273 vty
->node
= BGP_VNC_DEFAULTS_NODE
;
1277 DEFUNSH(VTYSH_BGPD
, vnc_nve_group
, vnc_nve_group_cmd
, "vnc nve-group NAME",
1278 "VNC/RFP related configuration\n"
1279 "Configure a NVE group\n"
1282 vty
->node
= BGP_VNC_NVE_GROUP_NODE
;
1286 DEFUNSH(VTYSH_BGPD
, vnc_vrf_policy
, vnc_vrf_policy_cmd
, "vrf-policy NAME",
1287 "Configure a VRF policy group\n"
1290 vty
->node
= BGP_VRF_POLICY_NODE
;
1294 DEFUNSH(VTYSH_BGPD
, vnc_l2_group
, vnc_l2_group_cmd
, "vnc l2-group NAME",
1295 "VNC/RFP related configuration\n"
1296 "Configure a L2 group\n"
1299 vty
->node
= BGP_VNC_L2_GROUP_NODE
;
1304 DEFUNSH(VTYSH_RIPD
, key_chain
, key_chain_cmd
, "key chain WORD",
1305 "Authentication key management\n"
1306 "Key-chain management\n"
1309 vty
->node
= KEYCHAIN_NODE
;
1313 DEFUNSH(VTYSH_RIPD
, key
, key_cmd
, "key (0-2147483647)",
1315 "Key identifier number\n")
1317 vty
->node
= KEYCHAIN_KEY_NODE
;
1321 DEFUNSH(VTYSH_RIPD
, router_rip
, router_rip_cmd
, "router rip",
1324 vty
->node
= RIP_NODE
;
1328 DEFUNSH(VTYSH_RIPNGD
, router_ripng
, router_ripng_cmd
, "router ripng",
1329 ROUTER_STR
"RIPng\n")
1331 vty
->node
= RIPNG_NODE
;
1335 DEFUNSH(VTYSH_OSPFD
, router_ospf
, router_ospf_cmd
,
1336 "router ospf [(1-65535)] [vrf NAME]",
1337 "Enable a routing process\n"
1338 "Start OSPF configuration\n"
1342 vty
->node
= OSPF_NODE
;
1346 DEFUNSH(VTYSH_EIGRPD
, router_eigrp
, router_eigrp_cmd
, "router eigrp (1-65535)",
1347 "Enable a routing process\n"
1348 "Start EIGRP configuration\n"
1349 "AS number to use\n")
1351 vty
->node
= EIGRP_NODE
;
1355 DEFUNSH(VTYSH_BABELD
, router_babel
, router_babel_cmd
, "router babel",
1356 "Enable a routing process\n"
1357 "Make Babel instance command\n")
1359 vty
->node
= BABEL_NODE
;
1363 DEFUNSH(VTYSH_OSPF6D
, router_ospf6
, router_ospf6_cmd
, "router ospf6",
1364 ROUTER_STR OSPF6_STR
)
1366 vty
->node
= OSPF6_NODE
;
1370 #if defined(HAVE_LDPD)
1371 DEFUNSH(VTYSH_LDPD
, ldp_mpls_ldp
, ldp_mpls_ldp_cmd
, "mpls ldp",
1372 "Global MPLS configuration subcommands\n"
1373 "Label Distribution Protocol\n")
1375 vty
->node
= LDP_NODE
;
1379 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv4
, ldp_address_family_ipv4_cmd
,
1380 "address-family ipv4",
1381 "Configure Address Family and its parameters\n"
1384 vty
->node
= LDP_IPV4_NODE
;
1388 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv6
, ldp_address_family_ipv6_cmd
,
1389 "address-family ipv6",
1390 "Configure Address Family and its parameters\n"
1393 vty
->node
= LDP_IPV6_NODE
;
1397 DEFUNSH(VTYSH_LDPD
, ldp_exit_address_family
, ldp_exit_address_family_cmd
,
1398 "exit-address-family", "Exit from Address Family configuration mode\n")
1400 if (vty
->node
== LDP_IPV4_NODE
|| vty
->node
== LDP_IPV6_NODE
)
1401 vty
->node
= LDP_NODE
;
1405 DEFUNSH(VTYSH_LDPD
, ldp_interface_ifname
, ldp_interface_ifname_cmd
,
1407 "Enable LDP on an interface and enter interface submode\n"
1408 "Interface's name\n")
1410 switch (vty
->node
) {
1412 vty
->node
= LDP_IPV4_IFACE_NODE
;
1415 vty
->node
= LDP_IPV6_IFACE_NODE
;
1424 DEFUNSH(VTYSH_LDPD
, ldp_l2vpn_word_type_vpls
, ldp_l2vpn_word_type_vpls_cmd
,
1425 "l2vpn WORD type vpls",
1426 "Configure l2vpn commands\n"
1429 "Virtual Private LAN Service\n")
1431 vty
->node
= LDP_L2VPN_NODE
;
1435 DEFUNSH(VTYSH_LDPD
, ldp_member_pseudowire_ifname
,
1436 ldp_member_pseudowire_ifname_cmd
, "member pseudowire IFNAME",
1437 "L2VPN member configuration\n"
1438 "Pseudowire interface\n"
1439 "Interface's name\n")
1441 vty
->node
= LDP_PSEUDOWIRE_NODE
;
1446 DEFUNSH(VTYSH_ISISD
, router_isis
, router_isis_cmd
, "router isis WORD",
1449 "ISO Routing area tag")
1451 vty
->node
= ISIS_NODE
;
1455 DEFUNSH(VTYSH_RMAP
, vtysh_route_map
, vtysh_route_map_cmd
,
1456 "route-map WORD <deny|permit> (1-65535)",
1457 "Create route-map or enter route-map command mode\n"
1459 "Route map denies set operations\n"
1460 "Route map permits set operations\n"
1461 "Sequence to insert to/delete from existing route-map entry\n")
1463 vty
->node
= RMAP_NODE
;
1467 DEFUNSH(VTYSH_ALL
, vtysh_line_vty
, vtysh_line_vty_cmd
, "line vty",
1468 "Configure a terminal line\n"
1469 "Virtual terminal\n")
1471 vty
->node
= VTY_NODE
;
1475 DEFUNSH(VTYSH_REALLYALL
, vtysh_enable
, vtysh_enable_cmd
, "enable",
1476 "Turn on privileged mode command\n")
1478 vty
->node
= ENABLE_NODE
;
1482 DEFUNSH(VTYSH_REALLYALL
, vtysh_disable
, vtysh_disable_cmd
, "disable",
1483 "Turn off privileged mode command\n")
1485 if (vty
->node
== ENABLE_NODE
)
1486 vty
->node
= VIEW_NODE
;
1490 DEFUNSH(VTYSH_REALLYALL
, vtysh_config_terminal
, vtysh_config_terminal_cmd
,
1491 "configure terminal",
1492 "Configuration from vty interface\n"
1493 "Configuration terminal\n")
1495 vty
->node
= CONFIG_NODE
;
1499 static int vtysh_exit(struct vty
*vty
)
1501 switch (vty
->node
) {
1507 vty
->node
= ENABLE_NODE
;
1509 case INTERFACE_NODE
:
1522 case LDP_L2VPN_NODE
:
1528 vtysh_execute("end");
1529 vtysh_execute("configure terminal");
1530 vty
->node
= CONFIG_NODE
;
1532 case BGP_VPNV4_NODE
:
1533 case BGP_VPNV6_NODE
:
1535 case BGP_IPV4M_NODE
:
1536 case BGP_IPV4L_NODE
:
1538 case BGP_IPV6M_NODE
:
1539 case BGP_IPV6L_NODE
:
1540 case BGP_VRF_POLICY_NODE
:
1542 case BGP_VNC_DEFAULTS_NODE
:
1543 case BGP_VNC_NVE_GROUP_NODE
:
1544 case BGP_VNC_L2_GROUP_NODE
:
1545 vty
->node
= BGP_NODE
;
1547 case BGP_EVPN_VNI_NODE
:
1548 vty
->node
= BGP_EVPN_NODE
;
1552 vty
->node
= LDP_NODE
;
1554 case LDP_IPV4_IFACE_NODE
:
1555 vty
->node
= LDP_IPV4_NODE
;
1557 case LDP_IPV6_IFACE_NODE
:
1558 vty
->node
= LDP_IPV6_NODE
;
1560 case LDP_PSEUDOWIRE_NODE
:
1561 vty
->node
= LDP_L2VPN_NODE
;
1563 case KEYCHAIN_KEY_NODE
:
1564 vty
->node
= KEYCHAIN_NODE
;
1566 case LINK_PARAMS_NODE
:
1567 vty
->node
= INTERFACE_NODE
;
1575 DEFUNSH(VTYSH_REALLYALL
, vtysh_exit_all
, vtysh_exit_all_cmd
, "exit",
1576 "Exit current mode and down to previous mode\n")
1578 return vtysh_exit(vty
);
1581 DEFUNSH(VTYSH_ALL
, vtysh_quit_all
, vtysh_quit_all_cmd
, "quit",
1582 "Exit current mode and down to previous mode\n")
1584 return vtysh_exit_all(self
, vty
, argc
, argv
);
1587 DEFUNSH(VTYSH_BGPD
, exit_address_family
, exit_address_family_cmd
,
1588 "exit-address-family", "Exit from Address Family configuration mode\n")
1590 if (vty
->node
== BGP_IPV4_NODE
|| vty
->node
== BGP_IPV4M_NODE
1591 || vty
->node
== BGP_IPV4L_NODE
|| vty
->node
== BGP_VPNV4_NODE
1592 || vty
->node
== BGP_VPNV6_NODE
|| vty
->node
== BGP_IPV6_NODE
1593 || vty
->node
== BGP_IPV6L_NODE
|| vty
->node
== BGP_IPV6M_NODE
1594 || vty
->node
== BGP_EVPN_NODE
)
1595 vty
->node
= BGP_NODE
;
1599 DEFUNSH(VTYSH_BGPD
, exit_vni
, exit_vni_cmd
, "exit-vni", "Exit from VNI mode\n")
1601 if (vty
->node
== BGP_EVPN_VNI_NODE
)
1602 vty
->node
= BGP_EVPN_NODE
;
1606 DEFUNSH(VTYSH_BGPD
, exit_vnc_config
, exit_vnc_config_cmd
, "exit-vnc",
1607 "Exit from VNC configuration mode\n")
1609 if (vty
->node
== BGP_VNC_DEFAULTS_NODE
1610 || vty
->node
== BGP_VNC_NVE_GROUP_NODE
1611 || vty
->node
== BGP_VNC_L2_GROUP_NODE
)
1612 vty
->node
= BGP_NODE
;
1616 DEFUNSH(VTYSH_BGPD
, exit_vrf_policy
, exit_vrf_policy_cmd
, "exit-vrf-policy",
1617 "Exit from VRF configuration mode\n")
1619 if (vty
->node
== BGP_VRF_POLICY_NODE
)
1620 vty
->node
= BGP_NODE
;
1624 DEFUNSH(VTYSH_RIPD
, vtysh_exit_ripd
, vtysh_exit_ripd_cmd
, "exit",
1625 "Exit current mode and down to previous mode\n")
1627 return vtysh_exit(vty
);
1630 DEFUNSH(VTYSH_RIPD
, vtysh_quit_ripd
, vtysh_quit_ripd_cmd
, "quit",
1631 "Exit current mode and down to previous mode\n")
1633 return vtysh_exit_ripd(self
, vty
, argc
, argv
);
1636 DEFUNSH(VTYSH_RIPNGD
, vtysh_exit_ripngd
, vtysh_exit_ripngd_cmd
, "exit",
1637 "Exit current mode and down to previous mode\n")
1639 return vtysh_exit(vty
);
1642 DEFUNSH(VTYSH_RIPNGD
, vtysh_quit_ripngd
, vtysh_quit_ripngd_cmd
, "quit",
1643 "Exit current mode and down to previous mode\n")
1645 return vtysh_exit_ripngd(self
, vty
, argc
, argv
);
1648 DEFUNSH(VTYSH_RMAP
, vtysh_exit_rmap
, vtysh_exit_rmap_cmd
, "exit",
1649 "Exit current mode and down to previous mode\n")
1651 return vtysh_exit(vty
);
1654 DEFUNSH(VTYSH_RMAP
, vtysh_quit_rmap
, vtysh_quit_rmap_cmd
, "quit",
1655 "Exit current mode and down to previous mode\n")
1657 return vtysh_exit_rmap(self
, vty
, argc
, argv
);
1660 DEFUNSH(VTYSH_BGPD
, vtysh_exit_bgpd
, vtysh_exit_bgpd_cmd
, "exit",
1661 "Exit current mode and down to previous mode\n")
1663 return vtysh_exit(vty
);
1666 DEFUNSH(VTYSH_BGPD
, vtysh_quit_bgpd
, vtysh_quit_bgpd_cmd
, "quit",
1667 "Exit current mode and down to previous mode\n")
1669 return vtysh_exit_bgpd(self
, vty
, argc
, argv
);
1672 DEFUNSH(VTYSH_OSPFD
, vtysh_exit_ospfd
, vtysh_exit_ospfd_cmd
, "exit",
1673 "Exit current mode and down to previous mode\n")
1675 return vtysh_exit(vty
);
1678 DEFUNSH(VTYSH_OSPFD
, vtysh_quit_ospfd
, vtysh_quit_ospfd_cmd
, "quit",
1679 "Exit current mode and down to previous mode\n")
1681 return vtysh_exit_ospfd(self
, vty
, argc
, argv
);
1684 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_eigrpd
, vtysh_exit_eigrpd_cmd
, "exit",
1685 "Exit current mode and down to previous mode\n")
1687 return vtysh_exit(vty
);
1690 DEFUNSH(VTYSH_EIGRPD
, vtysh_quit_eigrpd
, vtysh_quit_eigrpd_cmd
, "quit",
1691 "Exit current mode and down to previous mode\n")
1693 return vtysh_exit(vty
);
1696 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_babeld
, vtysh_exit_babeld_cmd
, "exit",
1697 "Exit current mode and down to previous mode\n")
1699 return vtysh_exit(vty
);
1702 DEFUNSH(VTYSH_BABELD
, vtysh_quit_babeld
, vtysh_quit_babeld_cmd
, "quit",
1703 "Exit current mode and down to previous mode\n")
1705 return vtysh_exit(vty
);
1708 DEFUNSH(VTYSH_OSPF6D
, vtysh_exit_ospf6d
, vtysh_exit_ospf6d_cmd
, "exit",
1709 "Exit current mode and down to previous mode\n")
1711 return vtysh_exit(vty
);
1714 DEFUNSH(VTYSH_OSPF6D
, vtysh_quit_ospf6d
, vtysh_quit_ospf6d_cmd
, "quit",
1715 "Exit current mode and down to previous mode\n")
1717 return vtysh_exit_ospf6d(self
, vty
, argc
, argv
);
1720 #if defined(HAVE_LDPD)
1721 DEFUNSH(VTYSH_LDPD
, vtysh_exit_ldpd
, vtysh_exit_ldpd_cmd
, "exit",
1722 "Exit current mode and down to previous mode\n")
1724 return vtysh_exit(vty
);
1727 ALIAS(vtysh_exit_ldpd
, vtysh_quit_ldpd_cmd
, "quit",
1728 "Exit current mode and down to previous mode\n")
1731 DEFUNSH(VTYSH_ISISD
, vtysh_exit_isisd
, vtysh_exit_isisd_cmd
, "exit",
1732 "Exit current mode and down to previous mode\n")
1734 return vtysh_exit(vty
);
1737 DEFUNSH(VTYSH_ISISD
, vtysh_quit_isisd
, vtysh_quit_isisd_cmd
, "quit",
1738 "Exit current mode and down to previous mode\n")
1740 return vtysh_exit_isisd(self
, vty
, argc
, argv
);
1743 DEFUNSH(VTYSH_ALL
, vtysh_exit_line_vty
, vtysh_exit_line_vty_cmd
, "exit",
1744 "Exit current mode and down to previous mode\n")
1746 return vtysh_exit(vty
);
1749 DEFUNSH(VTYSH_ALL
, vtysh_quit_line_vty
, vtysh_quit_line_vty_cmd
, "quit",
1750 "Exit current mode and down to previous mode\n")
1752 return vtysh_exit_line_vty(self
, vty
, argc
, argv
);
1755 DEFUNSH(VTYSH_INTERFACE
, vtysh_interface
, vtysh_interface_cmd
,
1756 "interface IFNAME [vrf NAME]",
1757 "Select an interface to configure\n"
1758 "Interface's name\n" VRF_CMD_HELP_STR
)
1760 vty
->node
= INTERFACE_NODE
;
1764 DEFUNSH(VTYSH_ZEBRA
, vtysh_pseudowire
, vtysh_pseudowire_cmd
,
1765 "pseudowire IFNAME",
1766 "Static pseudowire configuration\n"
1767 "Pseudowire name\n")
1769 vty
->node
= PW_NODE
;
1773 /* TODO Implement "no interface command in isisd. */
1774 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_RIPNGD
| VTYSH_OSPFD
| VTYSH_OSPF6D
1776 vtysh_no_interface_cmd
, "no interface IFNAME", NO_STR
1777 "Delete a pseudo interface's configuration\n"
1778 "Interface's name\n")
1780 DEFSH(VTYSH_ZEBRA
, vtysh_no_interface_vrf_cmd
, "no interface IFNAME vrf NAME",
1782 "Delete a pseudo interface's configuration\n"
1783 "Interface's name\n" VRF_CMD_HELP_STR
)
1785 DEFUNSH(VTYSH_NS
, vtysh_ns
, vtysh_ns_cmd
, "logical-router (1-65535) ns NAME",
1786 "Enable a logical-router\n"
1787 "Specify the logical-router indentifier\n"
1789 "The file name in " NS_RUN_DIR
", or a full pathname\n")
1791 vty
->node
= NS_NODE
;
1795 DEFUNSH(VTYSH_VRF
, vtysh_vrf
, vtysh_vrf_cmd
, "vrf NAME",
1796 "Select a VRF to configure\n"
1799 vty
->node
= VRF_NODE
;
1803 DEFSH(VTYSH_ZEBRA
, vtysh_no_vrf_cmd
, "no vrf NAME", NO_STR
1804 "Delete a pseudo vrf's configuration\n"
1807 DEFUNSH(VTYSH_NS
, vtysh_exit_ns
, vtysh_exit_ns_cmd
, "exit",
1808 "Exit current mode and down to previous mode\n")
1810 return vtysh_exit(vty
);
1813 DEFUNSH(VTYSH_NS
, vtysh_quit_ns
, vtysh_quit_ns_cmd
, "quit",
1814 "Exit current mode and down to previous mode\n")
1816 return vtysh_exit_ns(self
, vty
, argc
, argv
);
1819 DEFUNSH(VTYSH_VRF
, vtysh_exit_vrf
, vtysh_exit_vrf_cmd
, "exit",
1820 "Exit current mode and down to previous mode\n")
1822 return vtysh_exit(vty
);
1825 DEFUNSH(VTYSH_VRF
, vtysh_quit_vrf
, vtysh_quit_vrf_cmd
, "quit",
1826 "Exit current mode and down to previous mode\n")
1828 return vtysh_exit_vrf(self
, vty
, argc
, argv
);
1831 /* TODO Implement interface description commands in ripngd, ospf6d
1833 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_OSPFD
| VTYSH_EIGRPD
,
1834 vtysh_interface_desc_cmd
, "description LINE...",
1835 "Interface specific description\n"
1836 "Characters describing this interface\n")
1838 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_OSPFD
| VTYSH_EIGRPD
,
1839 vtysh_no_interface_desc_cmd
, "no description",
1840 NO_STR
"Interface specific description\n")
1842 DEFUNSH(VTYSH_INTERFACE
, vtysh_exit_interface
, vtysh_exit_interface_cmd
, "exit",
1843 "Exit current mode and down to previous mode\n")
1845 return vtysh_exit(vty
);
1848 DEFUNSH(VTYSH_INTERFACE
, vtysh_quit_interface
, vtysh_quit_interface_cmd
, "quit",
1849 "Exit current mode and down to previous mode\n")
1851 return vtysh_exit_interface(self
, vty
, argc
, argv
);
1854 DEFUN (vtysh_show_thread
,
1855 vtysh_show_thread_cmd
,
1856 "show thread cpu [FILTER]",
1858 "Thread information\n"
1859 "Thread CPU usage\n"
1860 "Display filter (rwtexb)\n")
1864 int ret
= CMD_SUCCESS
;
1867 const char *filter
=
1868 argv_find(argv
, argc
, "FILTER", &idx
) ? argv
[idx
]->arg
: "";
1870 snprintf(line
, sizeof(line
), "do show thread cpu %s\n", filter
);
1871 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1872 if (vtysh_client
[i
].fd
>= 0) {
1873 fprintf(stdout
, "Thread statistics for %s:\n",
1874 vtysh_client
[i
].name
);
1875 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
1877 fprintf(stdout
, "\n");
1882 DEFUN (vtysh_show_work_queues
,
1883 vtysh_show_work_queues_cmd
,
1886 "Work Queue information\n")
1889 int ret
= CMD_SUCCESS
;
1890 char line
[] = "do show work-queues\n";
1892 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1893 if (vtysh_client
[i
].fd
>= 0) {
1894 fprintf(stdout
, "Work queue statistics for %s:\n",
1895 vtysh_client
[i
].name
);
1896 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
1898 fprintf(stdout
, "\n");
1904 DEFUN (vtysh_show_work_queues_daemon
,
1905 vtysh_show_work_queues_daemon_cmd
,
1906 "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd>",
1908 "Work Queue information\n"
1909 "For the zebra daemon\n"
1910 "For the rip daemon\n"
1911 "For the ripng daemon\n"
1912 "For the ospf daemon\n"
1913 "For the ospfv6 daemon\n"
1914 "For the bgp daemon\n"
1915 "For the isis daemon\n")
1917 int idx_protocol
= 2;
1919 int ret
= CMD_SUCCESS
;
1921 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
1922 if (strmatch(vtysh_client
[i
].name
, argv
[idx_protocol
]->text
))
1926 ret
= vtysh_client_execute(&vtysh_client
[i
], "show work-queues\n",
1932 DEFUNSH(VTYSH_ZEBRA
, vtysh_link_params
, vtysh_link_params_cmd
, "link-params",
1935 vty
->node
= LINK_PARAMS_NODE
;
1939 DEFUNSH(VTYSH_ZEBRA
, exit_link_params
, exit_link_params_cmd
, "exit-link-params",
1940 "Exit from Link Params configuration node\n")
1942 if (vty
->node
== LINK_PARAMS_NODE
)
1943 vty
->node
= INTERFACE_NODE
;
1947 static int show_per_daemon(const char *line
, const char *headline
)
1950 int ret
= CMD_SUCCESS
;
1952 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1953 if (vtysh_client
[i
].fd
>= 0) {
1954 fprintf(outputfile
, headline
, vtysh_client
[i
].name
);
1955 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
1957 fprintf(stdout
, "\n");
1963 DEFUN (vtysh_show_debugging
,
1964 vtysh_show_debugging_cmd
,
1969 return show_per_daemon("do show debugging\n",
1973 DEFUN (vtysh_show_debugging_hashtable
,
1974 vtysh_show_debugging_hashtable_cmd
,
1975 "show debugging hashtable [statistics]",
1978 "Statistics about hash tables\n"
1979 "Statistics about hash tables\n")
1981 fprintf(stdout
, "\n");
1983 "Load factor (LF) - average number of elements across all buckets\n");
1985 "Full load factor (FLF) - average number of elements across full buckets\n\n");
1987 "Standard deviation (SD) is calculated for both the LF and FLF\n");
1989 "and indicates the typical deviation of bucket chain length\n");
1990 fprintf(stdout
, "from the value in the corresponding load factor.\n\n");
1992 return show_per_daemon("do show debugging hashtable\n",
1993 "Hashtable statistics for %s:\n");
1997 DEFUN (vtysh_show_memory
,
1998 vtysh_show_memory_cmd
,
2001 "Memory statistics\n")
2003 return show_per_daemon("show memory\n",
2004 "Memory statistics for %s:\n");
2007 DEFUN (vtysh_show_modules
,
2008 vtysh_show_modules_cmd
,
2013 return show_per_daemon("show modules\n",
2014 "Module information for %s:\n");
2017 /* Logging commands. */
2018 DEFUN (vtysh_show_logging
,
2019 vtysh_show_logging_cmd
,
2022 "Show current logging configuration\n")
2024 return show_per_daemon("do show logging\n",
2025 "Logging configuration for %s:\n");
2028 DEFUNSH(VTYSH_ALL
, vtysh_log_stdout
, vtysh_log_stdout_cmd
, "log stdout",
2030 "Set stdout logging level\n")
2035 DEFUNSH(VTYSH_ALL
, vtysh_log_stdout_level
, vtysh_log_stdout_level_cmd
,
2036 "log stdout <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2038 "Set stdout logging level\n" LOG_LEVEL_DESC
)
2043 DEFUNSH(VTYSH_ALL
, no_vtysh_log_stdout
, no_vtysh_log_stdout_cmd
,
2044 "no log stdout [LEVEL]", NO_STR
2046 "Cancel logging to stdout\n"
2052 DEFUNSH(VTYSH_ALL
, vtysh_log_file
, vtysh_log_file_cmd
, "log file FILENAME",
2055 "Logging filename\n")
2060 DEFUNSH(VTYSH_ALL
, vtysh_log_file_level
, vtysh_log_file_level_cmd
,
2061 "log file FILENAME <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2064 "Logging filename\n" LOG_LEVEL_DESC
)
2069 DEFUNSH(VTYSH_ALL
, no_vtysh_log_file
, no_vtysh_log_file_cmd
,
2070 "no log file [FILENAME [LEVEL]]", NO_STR
2072 "Cancel logging to file\n"
2073 "Logging file name\n"
2079 DEFUNSH(VTYSH_ALL
, vtysh_log_monitor
, vtysh_log_monitor_cmd
,
2080 "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
2082 "Set terminal line (monitor) logging level\n" LOG_LEVEL_DESC
)
2087 DEFUNSH(VTYSH_ALL
, no_vtysh_log_monitor
, no_vtysh_log_monitor_cmd
,
2088 "no log monitor [LEVEL]", NO_STR
2090 "Disable terminal line (monitor) logging\n"
2096 DEFUNSH(VTYSH_ALL
, vtysh_log_syslog
, vtysh_log_syslog_cmd
,
2097 "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
2099 "Set syslog logging level\n" LOG_LEVEL_DESC
)
2104 DEFUNSH(VTYSH_ALL
, no_vtysh_log_syslog
, no_vtysh_log_syslog_cmd
,
2105 "no log syslog [LEVEL]", NO_STR
2107 "Cancel logging to syslog\n"
2113 DEFUNSH(VTYSH_ALL
, vtysh_log_facility
, vtysh_log_facility_cmd
,
2114 "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>",
2116 "Facility parameter for syslog messages\n" LOG_FACILITY_DESC
)
2122 DEFUNSH(VTYSH_ALL
, no_vtysh_log_facility
, no_vtysh_log_facility_cmd
,
2123 "no log facility [FACILITY]", NO_STR
2125 "Reset syslog facility to default (daemon)\n"
2126 "Syslog facility\n")
2133 VTYSH_ALL
, vtysh_log_trap
, vtysh_log_trap_cmd
,
2134 "log trap <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2136 "(Deprecated) Set logging level and default for all destinations\n" LOG_LEVEL_DESC
)
2142 DEFUNSH_DEPRECATED(VTYSH_ALL
, no_vtysh_log_trap
, no_vtysh_log_trap_cmd
,
2143 "no log trap [LEVEL]", NO_STR
2145 "Permit all logging information\n"
2151 DEFUNSH(VTYSH_ALL
, vtysh_log_record_priority
, vtysh_log_record_priority_cmd
,
2152 "log record-priority",
2154 "Log the priority of the message within the message\n")
2159 DEFUNSH(VTYSH_ALL
, no_vtysh_log_record_priority
,
2160 no_vtysh_log_record_priority_cmd
, "no log record-priority", NO_STR
2162 "Do not log the priority of the message within the message\n")
2167 DEFUNSH(VTYSH_ALL
, vtysh_log_timestamp_precision
,
2168 vtysh_log_timestamp_precision_cmd
, "log timestamp precision (0-6)",
2170 "Timestamp configuration\n"
2171 "Set the timestamp precision\n"
2172 "Number of subsecond digits\n")
2177 DEFUNSH(VTYSH_ALL
, no_vtysh_log_timestamp_precision
,
2178 no_vtysh_log_timestamp_precision_cmd
, "no log timestamp precision",
2181 "Timestamp configuration\n"
2182 "Reset the timestamp precision to the default value of 0\n")
2187 DEFUNSH(VTYSH_ALL
, vtysh_service_password_encrypt
,
2188 vtysh_service_password_encrypt_cmd
, "service password-encryption",
2189 "Set up miscellaneous service\n"
2190 "Enable encrypted passwords\n")
2195 DEFUNSH(VTYSH_ALL
, no_vtysh_service_password_encrypt
,
2196 no_vtysh_service_password_encrypt_cmd
, "no service password-encryption",
2198 "Set up miscellaneous service\n"
2199 "Enable encrypted passwords\n")
2204 DEFUNSH(VTYSH_ALL
, vtysh_config_password
, vtysh_password_cmd
,
2205 "password [(8-8)] LINE",
2206 "Assign the terminal connection password\n"
2207 "Specifies a HIDDEN password will follow\n"
2208 "The password string\n")
2213 DEFUNSH(VTYSH_ALL
, vtysh_config_enable_password
, vtysh_enable_password_cmd
,
2214 "enable password [(8-8)] LINE",
2215 "Modify enable password parameters\n"
2216 "Assign the privileged level password\n"
2217 "Specifies a HIDDEN password will follow\n"
2218 "The 'enable' password string\n")
2223 DEFUNSH(VTYSH_ALL
, no_vtysh_config_enable_password
,
2224 no_vtysh_enable_password_cmd
, "no enable password", NO_STR
2225 "Modify enable password parameters\n"
2226 "Assign the privileged level password\n")
2231 DEFUN (vtysh_write_terminal
,
2232 vtysh_write_terminal_cmd
,
2233 "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
2234 "Write running configuration to memory, network, or terminal\n"
2235 "Write to terminal\n"
2236 "For the zebra daemon\n"
2237 "For the rip daemon\n"
2238 "For the ripng daemon\n"
2239 "For the ospf daemon\n"
2240 "For the ospfv6 daemon\n"
2241 "For the ldpd daemon\n"
2242 "For the bgp daemon\n"
2243 "For the isis daemon\n"
2244 "For the pim daemon\n")
2247 char line
[] = "do write terminal\n";
2248 FILE *fp
= outputfile
;
2250 if (fp
== stdout
&& vtysh_pager_name
) {
2251 fp
= popen(vtysh_pager_name
, "w");
2258 fprintf(outputfile
, "Building configuration...\n");
2259 fprintf(outputfile
, "\nCurrent configuration:\n");
2260 fprintf(outputfile
, "!\n");
2262 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2264 || (strmatch(vtysh_client
[i
].name
, argv
[2]->text
)))
2265 vtysh_client_config(&vtysh_client
[i
], line
);
2267 /* Integrate vtysh specific configuration. */
2268 vtysh_config_write();
2270 vtysh_config_dump(fp
);
2272 if (vtysh_pager_name
&& fp
&& fp
!= outputfile
) {
2274 if (pclose(fp
) == -1) {
2281 fprintf(outputfile
, "end\n");
2285 DEFUN (vtysh_show_running_config
,
2286 vtysh_show_running_config_cmd
,
2287 "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
2289 "Current operating configuration\n"
2290 "For the zebra daemon\n"
2291 "For the rip daemon\n"
2292 "For the ripng daemon\n"
2293 "For the ospf daemon\n"
2294 "For the ospfv6 daemon\n"
2295 "For the ldp daemon\n"
2296 "For the bgp daemon\n"
2297 "For the isis daemon\n"
2298 "For the pim daemon\n")
2300 return vtysh_write_terminal(self
, vty
, argc
, argv
);
2303 DEFUN (vtysh_integrated_config
,
2304 vtysh_integrated_config_cmd
,
2305 "service integrated-vtysh-config",
2306 "Set up miscellaneous service\n"
2307 "Write configuration into integrated file\n")
2309 vtysh_write_integrated
= WRITE_INTEGRATED_YES
;
2313 DEFUN (no_vtysh_integrated_config
,
2314 no_vtysh_integrated_config_cmd
,
2315 "no service integrated-vtysh-config",
2317 "Set up miscellaneous service\n"
2318 "Write configuration into integrated file\n")
2320 vtysh_write_integrated
= WRITE_INTEGRATED_NO
;
2324 static void backup_config_file(const char *fbackup
)
2326 char *integrate_sav
= NULL
;
2328 integrate_sav
= malloc(strlen(fbackup
) + strlen(CONF_BACKUP_EXT
) + 1);
2329 strcpy(integrate_sav
, fbackup
);
2330 strcat(integrate_sav
, CONF_BACKUP_EXT
);
2332 /* Move current configuration file to backup config file. */
2333 unlink(integrate_sav
);
2334 rename(fbackup
, integrate_sav
);
2335 free(integrate_sav
);
2338 int vtysh_write_config_integrated(void)
2341 char line
[] = "do write terminal\n";
2344 struct passwd
*pwentry
;
2345 struct group
*grentry
;
2351 fprintf(stdout
, "Building Configuration...\n");
2353 backup_config_file(frr_config
);
2354 fp
= fopen(frr_config
, "w");
2357 "%% Error: failed to open configuration file %s: %s\n",
2358 frr_config
, safe_strerror(errno
));
2359 return CMD_WARNING_CONFIG_FAILED
;
2363 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2364 vtysh_client_config(&vtysh_client
[i
], line
);
2366 vtysh_config_write();
2367 vtysh_config_dump(fp
);
2369 if (fchmod(fd
, CONFIGFILE_MASK
) != 0) {
2370 printf("%% Warning: can't chmod configuration file %s: %s\n",
2371 frr_config
, safe_strerror(errno
));
2376 pwentry
= getpwnam(FRR_USER
);
2378 uid
= pwentry
->pw_uid
;
2380 printf("%% Warning: could not look up user \"%s\"\n", FRR_USER
);
2385 grentry
= getgrnam(FRR_GROUP
);
2387 gid
= grentry
->gr_gid
;
2389 printf("%% Warning: could not look up group \"%s\"\n",
2395 if (!fstat(fd
, &st
)) {
2396 if (st
.st_uid
== uid
)
2398 if (st
.st_gid
== gid
)
2400 if ((uid
!= (uid_t
)-1 || gid
!= (gid_t
)-1)
2401 && fchown(fd
, uid
, gid
)) {
2402 printf("%% Warning: can't chown configuration file %s: %s\n",
2403 frr_config
, safe_strerror(errno
));
2407 printf("%% Warning: stat() failed on %s: %s\n", frr_config
,
2408 safe_strerror(errno
));
2414 printf("Integrated configuration saved to %s\n", frr_config
);
2422 static bool want_config_integrated(void)
2426 switch (vtysh_write_integrated
) {
2427 case WRITE_INTEGRATED_UNSPECIFIED
:
2428 if (stat(frr_config
, &s
) && errno
== ENOENT
)
2431 case WRITE_INTEGRATED_NO
:
2433 case WRITE_INTEGRATED_YES
:
2439 DEFUN (vtysh_write_memory
,
2440 vtysh_write_memory_cmd
,
2441 "write [<memory|file>]",
2442 "Write running configuration to memory, network, or terminal\n"
2443 "Write configuration to the file (same as write file)\n"
2444 "Write configuration to the file (same as write memory)\n")
2446 int ret
= CMD_SUCCESS
;
2447 char line
[] = "do write memory\n";
2451 "Note: this version of vtysh never writes vtysh.conf\n");
2453 /* If integrated frr.conf explicitely set. */
2454 if (want_config_integrated()) {
2455 ret
= CMD_WARNING_CONFIG_FAILED
;
2456 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2457 if (vtysh_client
[i
].flag
== VTYSH_WATCHFRR
)
2459 if (i
< array_size(vtysh_client
) && vtysh_client
[i
].fd
!= -1)
2460 ret
= vtysh_client_execute(&vtysh_client
[i
],
2461 "do write integrated",
2464 if (ret
!= CMD_SUCCESS
) {
2465 printf("\nWarning: attempting direct configuration write without "
2466 "watchfrr.\nFile permissions and ownership may be "
2467 "incorrect, or write may fail.\n\n");
2468 ret
= vtysh_write_config_integrated();
2473 fprintf(outputfile
, "Building Configuration...\n");
2475 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2476 ret
= vtysh_client_execute(&vtysh_client
[i
], line
, outputfile
);
2481 DEFUN (vtysh_copy_running_config
,
2482 vtysh_copy_running_config_cmd
,
2483 "copy running-config startup-config",
2484 "Copy from one file to another\n"
2485 "Copy from current system configuration\n"
2486 "Copy to startup configuration\n")
2488 return vtysh_write_memory(self
, vty
, argc
, argv
);
2491 DEFUN (vtysh_terminal_length
,
2492 vtysh_terminal_length_cmd
,
2493 "terminal length (0-512)",
2494 "Set terminal line parameters\n"
2495 "Set number of lines on a screen\n"
2496 "Number of lines on screen (0 for no pausing)\n")
2500 char *endptr
= NULL
;
2501 char default_pager
[10];
2503 lines
= strtol(argv
[idx_number
]->arg
, &endptr
, 10);
2504 if (lines
< 0 || lines
> 512 || *endptr
!= '\0') {
2505 fprintf(outputfile
, "length is malformed\n");
2509 if (vtysh_pager_name
) {
2510 free(vtysh_pager_name
);
2511 vtysh_pager_name
= NULL
;
2515 snprintf(default_pager
, 10, "more -%i", lines
);
2516 vtysh_pager_name
= strdup(default_pager
);
2522 DEFUN (vtysh_terminal_no_length
,
2523 vtysh_terminal_no_length_cmd
,
2524 "terminal no length",
2525 "Set terminal line parameters\n"
2527 "Set number of lines on a screen\n")
2529 if (vtysh_pager_name
) {
2530 free(vtysh_pager_name
);
2531 vtysh_pager_name
= NULL
;
2538 DEFUN (vtysh_show_daemons
,
2539 vtysh_show_daemons_cmd
,
2542 "Show list of running daemons\n")
2546 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2547 if (vtysh_client
[i
].fd
>= 0)
2548 fprintf(outputfile
, " %s", vtysh_client
[i
].name
);
2549 fprintf(outputfile
, "\n");
2554 /* Execute command in child process. */
2555 static void execute_command(const char *command
, int argc
,
2556 const char *arg1
, const char *arg2
)
2565 /* Failure of fork(). */
2566 fprintf(stderr
, "Can't fork: %s\n", safe_strerror(errno
));
2568 } else if (pid
== 0) {
2569 /* This is child process. */
2572 execlp(command
, command
, (const char *)NULL
);
2575 execlp(command
, command
, arg1
, (const char *)NULL
);
2578 execlp(command
, command
, arg1
, arg2
,
2579 (const char *)NULL
);
2583 /* When execlp suceed, this part is not executed. */
2584 fprintf(stderr
, "Can't execute %s: %s\n", command
,
2585 safe_strerror(errno
));
2588 /* This is parent. */
2590 wait4(pid
, &status
, 0, NULL
);
2598 "Send echo messages\n"
2599 "Ping destination address or hostname\n")
2603 argv_find(argv
, argc
, "WORD", &idx
);
2604 execute_command("ping", 1, argv
[idx
]->arg
, NULL
);
2608 ALIAS(vtysh_ping
, vtysh_ping_ip_cmd
, "ping ip WORD",
2609 "Send echo messages\n"
2611 "Ping destination address or hostname\n")
2613 DEFUN (vtysh_traceroute
,
2614 vtysh_traceroute_cmd
,
2616 "Trace route to destination\n"
2617 "Trace route to destination address or hostname\n")
2621 argv_find(argv
, argc
, "WORD", &idx
);
2622 execute_command("traceroute", 1, argv
[idx
]->arg
, NULL
);
2626 ALIAS(vtysh_traceroute
, vtysh_traceroute_ip_cmd
, "traceroute ip WORD",
2627 "Trace route to destination\n"
2629 "Trace route to destination address or hostname\n")
2634 "Send echo messages\n"
2636 "Ping destination address or hostname\n")
2638 execute_command("ping6", 1, argv
[2]->arg
, NULL
);
2642 DEFUN (vtysh_traceroute6
,
2643 vtysh_traceroute6_cmd
,
2644 "traceroute ipv6 WORD",
2645 "Trace route to destination\n"
2647 "Trace route to destination address or hostname\n")
2649 execute_command("traceroute6", 1, argv
[2]->arg
, NULL
);
2653 #if defined(HAVE_SHELL_ACCESS)
2654 DEFUN (vtysh_telnet
,
2657 "Open a telnet connection\n"
2658 "IP address or hostname of a remote system\n")
2660 execute_command("telnet", 1, argv
[1]->arg
, NULL
);
2664 DEFUN (vtysh_telnet_port
,
2665 vtysh_telnet_port_cmd
,
2667 "Open a telnet connection\n"
2668 "IP address or hostname of a remote system\n"
2669 "TCP Port number\n")
2671 execute_command("telnet", 2, argv
[1]->arg
, argv
[2]->arg
);
2678 "Open an ssh connection\n"
2681 execute_command("ssh", 1, argv
[1]->arg
, NULL
);
2685 DEFUN (vtysh_start_shell
,
2686 vtysh_start_shell_cmd
,
2688 "Start UNIX shell\n")
2690 execute_command("sh", 0, NULL
, NULL
);
2694 DEFUN (vtysh_start_bash
,
2695 vtysh_start_bash_cmd
,
2697 "Start UNIX shell\n"
2700 execute_command("bash", 0, NULL
, NULL
);
2704 DEFUN (vtysh_start_zsh
,
2705 vtysh_start_zsh_cmd
,
2707 "Start UNIX shell\n"
2710 execute_command("zsh", 0, NULL
, NULL
);
2717 "list [permutations]",
2718 "Print command list\n"
2719 "Print all possible command permutations\n")
2721 return cmd_list_cmds(vty
, argc
== 2);
2724 DEFUN (vtysh_output_file
,
2725 vtysh_output_file_cmd
,
2727 "Direct vtysh output to file\n"
2728 "Direct vtysh output to file\n"
2729 "Path to dump output to\n")
2731 const char *path
= argv
[argc
- 1]->arg
;
2732 outputfile
= fopen(path
, "a");
2734 fprintf(stdout
, "Failed to open file '%s': %s\n", path
,
2735 safe_strerror(errno
));
2736 outputfile
= stdout
;
2741 DEFUN (no_vtysh_output_file
,
2742 no_vtysh_output_file_cmd
,
2743 "no output file [FILE]",
2745 "Direct vtysh output to file\n"
2746 "Direct vtysh output to file\n"
2747 "Path to dump output to\n")
2749 if (outputfile
!= stdout
) {
2751 outputfile
= stdout
;
2759 "Find CLI command containing text\n"
2760 "Text to search for\n")
2762 char *text
= argv_concat(argv
, argc
, 1);
2763 const struct cmd_node
*node
;
2764 const struct cmd_element
*cli
;
2767 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
2768 node
= vector_slot(cmdvec
, i
);
2771 clis
= node
->cmd_vector
;
2772 for (unsigned int j
= 0; j
< vector_active(clis
); j
++) {
2773 cli
= vector_slot(clis
, j
);
2774 if (strcasestr(cli
->string
, text
))
2775 fprintf(stdout
, " (%s) %s\n",
2776 node_names
[node
->node
], cli
->string
);
2780 XFREE(MTYPE_TMP
, text
);
2785 static void vtysh_install_default(enum node_type node
)
2787 install_element(node
, &config_list_cmd
);
2788 install_element(node
, &find_cmd
);
2789 install_element(node
, &vtysh_output_file_cmd
);
2790 install_element(node
, &no_vtysh_output_file_cmd
);
2793 /* Making connection to protocol daemon. */
2794 static int vtysh_connect(struct vtysh_client
*vclient
)
2798 struct sockaddr_un addr
;
2802 if (!vclient
->path
[0])
2803 snprintf(vclient
->path
, sizeof(vclient
->path
), "%s/%s.vty",
2804 vtydir
, vclient
->name
);
2805 path
= vclient
->path
;
2807 /* Stat socket to see if we have permission to access it. */
2808 ret
= stat(path
, &s_stat
);
2809 if (ret
< 0 && errno
!= ENOENT
) {
2810 fprintf(stderr
, "vtysh_connect(%s): stat = %s\n", path
,
2811 safe_strerror(errno
));
2816 if (!S_ISSOCK(s_stat
.st_mode
)) {
2817 fprintf(stderr
, "vtysh_connect(%s): Not a socket\n",
2823 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
2826 fprintf(stderr
, "vtysh_connect(%s): socket = %s\n", path
,
2827 safe_strerror(errno
));
2832 memset(&addr
, 0, sizeof(struct sockaddr_un
));
2833 addr
.sun_family
= AF_UNIX
;
2834 strlcpy(addr
.sun_path
, path
, sizeof(addr
.sun_path
));
2835 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
2836 len
= addr
.sun_len
= SUN_LEN(&addr
);
2838 len
= sizeof(addr
.sun_family
) + strlen(addr
.sun_path
);
2839 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
2841 ret
= connect(sock
, (struct sockaddr
*)&addr
, len
);
2844 fprintf(stderr
, "vtysh_connect(%s): connect = %s\n", path
,
2845 safe_strerror(errno
));
2855 /* Return true if str ends with suffix, else return false */
2856 static int ends_with(const char *str
, const char *suffix
)
2858 if (!str
|| !suffix
)
2860 size_t lenstr
= strlen(str
);
2861 size_t lensuffix
= strlen(suffix
);
2862 if (lensuffix
> lenstr
)
2864 return strncmp(str
+ lenstr
- lensuffix
, suffix
, lensuffix
) == 0;
2867 static void vtysh_client_sorted_insert(struct vtysh_client
*head_client
,
2868 struct vtysh_client
*client
)
2870 struct vtysh_client
*prev_node
, *current_node
;
2872 prev_node
= head_client
;
2873 current_node
= head_client
->next
;
2874 while (current_node
) {
2875 if (strcmp(current_node
->path
, client
->path
) > 0)
2878 prev_node
= current_node
;
2879 current_node
= current_node
->next
;
2881 client
->next
= current_node
;
2882 prev_node
->next
= client
;
2885 #define MAXIMUM_INSTANCES 10
2887 static void vtysh_update_all_insances(struct vtysh_client
*head_client
)
2889 struct vtysh_client
*client
;
2891 struct dirent
*file
;
2894 if (head_client
->flag
!= VTYSH_OSPFD
)
2897 /* ls vty_sock_dir and look for all files ending in .vty */
2898 dir
= opendir(vtydir
);
2900 while ((file
= readdir(dir
)) != NULL
) {
2901 if (begins_with(file
->d_name
, "ospfd-")
2902 && ends_with(file
->d_name
, ".vty")) {
2903 if (n
== MAXIMUM_INSTANCES
) {
2905 "Parsing %s, client limit(%d) reached!\n",
2909 client
= (struct vtysh_client
*)malloc(
2910 sizeof(struct vtysh_client
));
2912 client
->name
= "ospfd";
2913 client
->flag
= VTYSH_OSPFD
;
2914 snprintf(client
->path
, sizeof(client
->path
),
2915 "%s/%s", vtydir
, file
->d_name
);
2916 client
->next
= NULL
;
2917 vtysh_client_sorted_insert(head_client
, client
);
2925 static int vtysh_connect_all_instances(struct vtysh_client
*head_client
)
2927 struct vtysh_client
*client
;
2930 vtysh_update_all_insances(head_client
);
2932 client
= head_client
->next
;
2934 if (vtysh_connect(client
) == 0)
2936 client
= client
->next
;
2942 int vtysh_connect_all(const char *daemon_name
)
2948 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
2950 || !strcmp(daemon_name
, vtysh_client
[i
].name
)) {
2952 if (vtysh_connect(&vtysh_client
[i
]) == 0)
2955 rc
+= vtysh_connect_all_instances(&vtysh_client
[i
]);
2959 fprintf(stderr
, "Error: no daemons match name %s!\n",
2964 /* To disable readline's filename completion. */
2965 static char *vtysh_completion_entry_function(const char *ignore
,
2971 void vtysh_readline_init(void)
2973 /* readline related settings. */
2975 rl_bind_key('?', (rl_command_func_t
*)vtysh_rl_describe
);
2976 rl_completion_entry_function
= vtysh_completion_entry_function
;
2977 rl_attempted_completion_function
=
2978 (rl_completion_func_t
*)new_completion
;
2981 char *vtysh_prompt(void)
2983 static char buf
[100];
2985 snprintf(buf
, sizeof buf
, cmd_prompt(vty
->node
), cmd_hostname_get());
2989 static void vtysh_ac_line(void *arg
, const char *line
)
2993 for (i
= 0; i
< vector_active(comps
); i
++)
2994 if (!strcmp(line
, (char *)vector_slot(comps
, i
)))
2996 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, line
));
2999 static void vtysh_autocomplete(vector comps
, struct cmd_token
*token
)
3004 snprintf(accmd
, sizeof(accmd
), "autocomplete %d %s %s", token
->type
,
3005 token
->text
, token
->varname
? token
->varname
: "-");
3007 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3008 vtysh_client_run_all(&vtysh_client
[i
], accmd
, 1, NULL
,
3009 vtysh_ac_line
, comps
);
3012 static const struct cmd_variable_handler vtysh_var_handler
[] = {
3016 .completions
= vtysh_autocomplete
},
3017 {.completions
= NULL
}};
3021 if (outputfile
!= stdout
)
3025 void vtysh_init_vty(void)
3027 /* Make vty structure. */
3029 vty
->type
= VTY_SHELL
;
3030 vty
->node
= VIEW_NODE
;
3032 /* set default output */
3033 outputfile
= stdout
;
3035 /* Initialize commands. */
3037 cmd_variable_handler_register(vtysh_var_handler
);
3039 /* Install nodes. */
3040 install_node(&bgp_node
, NULL
);
3041 install_node(&rip_node
, NULL
);
3042 install_node(&interface_node
, NULL
);
3043 install_node(&pw_node
, NULL
);
3044 install_node(&link_params_node
, NULL
);
3045 install_node(&ns_node
, NULL
);
3046 install_node(&vrf_node
, NULL
);
3047 install_node(&rmap_node
, NULL
);
3048 install_node(&zebra_node
, NULL
);
3049 install_node(&bgp_vpnv4_node
, NULL
);
3050 install_node(&bgp_vpnv6_node
, NULL
);
3051 install_node(&bgp_ipv4_node
, NULL
);
3052 install_node(&bgp_ipv4m_node
, NULL
);
3053 install_node(&bgp_ipv4l_node
, NULL
);
3054 install_node(&bgp_ipv6_node
, NULL
);
3055 install_node(&bgp_ipv6m_node
, NULL
);
3056 install_node(&bgp_ipv6l_node
, NULL
);
3057 install_node(&bgp_vrf_policy_node
, NULL
);
3058 install_node(&bgp_evpn_node
, NULL
);
3059 install_node(&bgp_evpn_vni_node
, NULL
);
3060 install_node(&bgp_vnc_defaults_node
, NULL
);
3061 install_node(&bgp_vnc_nve_group_node
, NULL
);
3062 install_node(&bgp_vnc_l2_group_node
, NULL
);
3063 install_node(&ospf_node
, NULL
);
3064 install_node(&eigrp_node
, NULL
);
3065 install_node(&babel_node
, NULL
);
3066 install_node(&ripng_node
, NULL
);
3067 install_node(&ospf6_node
, NULL
);
3068 install_node(&ldp_node
, NULL
);
3069 install_node(&ldp_ipv4_node
, NULL
);
3070 install_node(&ldp_ipv6_node
, NULL
);
3071 install_node(&ldp_ipv4_iface_node
, NULL
);
3072 install_node(&ldp_ipv6_iface_node
, NULL
);
3073 install_node(&ldp_l2vpn_node
, NULL
);
3074 install_node(&ldp_pseudowire_node
, NULL
);
3075 install_node(&keychain_node
, NULL
);
3076 install_node(&keychain_key_node
, NULL
);
3077 install_node(&isis_node
, NULL
);
3078 install_node(&vty_node
, NULL
);
3079 #if defined(HAVE_RPKI)
3080 install_node(&rpki_node
, NULL
);
3083 struct cmd_node
*node
;
3084 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
3085 node
= vector_slot(cmdvec
, i
);
3086 if (!node
|| node
->node
== VIEW_NODE
)
3088 vtysh_install_default(node
->node
);
3091 install_element(VIEW_NODE
, &vtysh_enable_cmd
);
3092 install_element(ENABLE_NODE
, &vtysh_config_terminal_cmd
);
3093 install_element(ENABLE_NODE
, &vtysh_disable_cmd
);
3095 /* "exit" command. */
3096 install_element(VIEW_NODE
, &vtysh_exit_all_cmd
);
3097 install_element(CONFIG_NODE
, &vtysh_exit_all_cmd
);
3098 install_element(VIEW_NODE
, &vtysh_quit_all_cmd
);
3099 install_element(CONFIG_NODE
, &vtysh_quit_all_cmd
);
3100 install_element(RIP_NODE
, &vtysh_exit_ripd_cmd
);
3101 install_element(RIP_NODE
, &vtysh_quit_ripd_cmd
);
3102 install_element(RIPNG_NODE
, &vtysh_exit_ripngd_cmd
);
3103 install_element(RIPNG_NODE
, &vtysh_quit_ripngd_cmd
);
3104 install_element(OSPF_NODE
, &vtysh_exit_ospfd_cmd
);
3105 install_element(OSPF_NODE
, &vtysh_quit_ospfd_cmd
);
3106 install_element(EIGRP_NODE
, &vtysh_exit_eigrpd_cmd
);
3107 install_element(EIGRP_NODE
, &vtysh_quit_eigrpd_cmd
);
3108 install_element(BABEL_NODE
, &vtysh_exit_babeld_cmd
);
3109 install_element(BABEL_NODE
, &vtysh_quit_babeld_cmd
);
3110 install_element(OSPF6_NODE
, &vtysh_exit_ospf6d_cmd
);
3111 install_element(OSPF6_NODE
, &vtysh_quit_ospf6d_cmd
);
3112 #if defined(HAVE_LDPD)
3113 install_element(LDP_NODE
, &vtysh_exit_ldpd_cmd
);
3114 install_element(LDP_NODE
, &vtysh_quit_ldpd_cmd
);
3115 install_element(LDP_IPV4_NODE
, &vtysh_exit_ldpd_cmd
);
3116 install_element(LDP_IPV4_NODE
, &vtysh_quit_ldpd_cmd
);
3117 install_element(LDP_IPV4_NODE
, &ldp_exit_address_family_cmd
);
3118 install_element(LDP_IPV6_NODE
, &vtysh_exit_ldpd_cmd
);
3119 install_element(LDP_IPV6_NODE
, &vtysh_quit_ldpd_cmd
);
3120 install_element(LDP_IPV6_NODE
, &ldp_exit_address_family_cmd
);
3121 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
3122 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
3123 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
3124 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
3125 install_element(LDP_L2VPN_NODE
, &vtysh_exit_ldpd_cmd
);
3126 install_element(LDP_L2VPN_NODE
, &vtysh_quit_ldpd_cmd
);
3127 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_exit_ldpd_cmd
);
3128 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_quit_ldpd_cmd
);
3130 install_element(BGP_NODE
, &vtysh_exit_bgpd_cmd
);
3131 install_element(BGP_NODE
, &vtysh_quit_bgpd_cmd
);
3132 install_element(BGP_VPNV4_NODE
, &vtysh_exit_bgpd_cmd
);
3133 install_element(BGP_VPNV4_NODE
, &vtysh_quit_bgpd_cmd
);
3134 install_element(BGP_VPNV6_NODE
, &vtysh_exit_bgpd_cmd
);
3135 install_element(BGP_VPNV6_NODE
, &vtysh_quit_bgpd_cmd
);
3136 install_element(BGP_IPV4_NODE
, &vtysh_exit_bgpd_cmd
);
3137 install_element(BGP_IPV4_NODE
, &vtysh_quit_bgpd_cmd
);
3138 install_element(BGP_IPV4M_NODE
, &vtysh_exit_bgpd_cmd
);
3139 install_element(BGP_IPV4M_NODE
, &vtysh_quit_bgpd_cmd
);
3140 install_element(BGP_IPV4L_NODE
, &vtysh_exit_bgpd_cmd
);
3141 install_element(BGP_IPV4L_NODE
, &vtysh_quit_bgpd_cmd
);
3142 install_element(BGP_IPV6_NODE
, &vtysh_exit_bgpd_cmd
);
3143 install_element(BGP_IPV6_NODE
, &vtysh_quit_bgpd_cmd
);
3144 install_element(BGP_IPV6M_NODE
, &vtysh_exit_bgpd_cmd
);
3145 install_element(BGP_IPV6M_NODE
, &vtysh_quit_bgpd_cmd
);
3146 install_element(BGP_EVPN_NODE
, &vtysh_quit_bgpd_cmd
);
3147 install_element(BGP_EVPN_NODE
, &vtysh_exit_bgpd_cmd
);
3148 install_element(BGP_EVPN_VNI_NODE
, &vtysh_exit_bgpd_cmd
);
3149 install_element(BGP_EVPN_VNI_NODE
, &vtysh_quit_bgpd_cmd
);
3150 install_element(BGP_IPV6L_NODE
, &vtysh_exit_bgpd_cmd
);
3151 install_element(BGP_IPV6L_NODE
, &vtysh_quit_bgpd_cmd
);
3152 #if defined(ENABLE_BGP_VNC)
3153 install_element(BGP_VRF_POLICY_NODE
, &vtysh_exit_bgpd_cmd
);
3154 install_element(BGP_VRF_POLICY_NODE
, &vtysh_quit_bgpd_cmd
);
3155 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_exit_bgpd_cmd
);
3156 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_quit_bgpd_cmd
);
3157 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
3158 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
3159 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
3160 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
3162 install_element(ISIS_NODE
, &vtysh_exit_isisd_cmd
);
3163 install_element(ISIS_NODE
, &vtysh_quit_isisd_cmd
);
3164 install_element(KEYCHAIN_NODE
, &vtysh_exit_ripd_cmd
);
3165 install_element(KEYCHAIN_NODE
, &vtysh_quit_ripd_cmd
);
3166 install_element(KEYCHAIN_KEY_NODE
, &vtysh_exit_ripd_cmd
);
3167 install_element(KEYCHAIN_KEY_NODE
, &vtysh_quit_ripd_cmd
);
3168 install_element(RMAP_NODE
, &vtysh_exit_rmap_cmd
);
3169 install_element(RMAP_NODE
, &vtysh_quit_rmap_cmd
);
3170 install_element(VTY_NODE
, &vtysh_exit_line_vty_cmd
);
3171 install_element(VTY_NODE
, &vtysh_quit_line_vty_cmd
);
3173 /* "end" command. */
3174 install_element(CONFIG_NODE
, &vtysh_end_all_cmd
);
3175 install_element(ENABLE_NODE
, &vtysh_end_all_cmd
);
3176 install_element(RIP_NODE
, &vtysh_end_all_cmd
);
3177 install_element(RIPNG_NODE
, &vtysh_end_all_cmd
);
3178 install_element(OSPF_NODE
, &vtysh_end_all_cmd
);
3179 install_element(EIGRP_NODE
, &vtysh_end_all_cmd
);
3180 install_element(BABEL_NODE
, &vtysh_end_all_cmd
);
3181 install_element(OSPF6_NODE
, &vtysh_end_all_cmd
);
3182 install_element(LDP_NODE
, &vtysh_end_all_cmd
);
3183 install_element(LDP_IPV4_NODE
, &vtysh_end_all_cmd
);
3184 install_element(LDP_IPV6_NODE
, &vtysh_end_all_cmd
);
3185 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_end_all_cmd
);
3186 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_end_all_cmd
);
3187 install_element(LDP_L2VPN_NODE
, &vtysh_end_all_cmd
);
3188 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_end_all_cmd
);
3189 install_element(BGP_NODE
, &vtysh_end_all_cmd
);
3190 install_element(BGP_IPV4_NODE
, &vtysh_end_all_cmd
);
3191 install_element(BGP_IPV4M_NODE
, &vtysh_end_all_cmd
);
3192 install_element(BGP_IPV4L_NODE
, &vtysh_end_all_cmd
);
3193 install_element(BGP_VPNV4_NODE
, &vtysh_end_all_cmd
);
3194 install_element(BGP_VPNV6_NODE
, &vtysh_end_all_cmd
);
3195 install_element(BGP_IPV6_NODE
, &vtysh_end_all_cmd
);
3196 install_element(BGP_IPV6M_NODE
, &vtysh_end_all_cmd
);
3197 install_element(BGP_IPV6L_NODE
, &vtysh_end_all_cmd
);
3198 install_element(BGP_VRF_POLICY_NODE
, &vtysh_end_all_cmd
);
3199 install_element(BGP_EVPN_NODE
, &vtysh_end_all_cmd
);
3200 install_element(BGP_EVPN_VNI_NODE
, &vtysh_end_all_cmd
);
3201 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_end_all_cmd
);
3202 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_end_all_cmd
);
3203 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_end_all_cmd
);
3204 install_element(ISIS_NODE
, &vtysh_end_all_cmd
);
3205 install_element(KEYCHAIN_NODE
, &vtysh_end_all_cmd
);
3206 install_element(KEYCHAIN_KEY_NODE
, &vtysh_end_all_cmd
);
3207 install_element(RMAP_NODE
, &vtysh_end_all_cmd
);
3208 install_element(VTY_NODE
, &vtysh_end_all_cmd
);
3210 install_element(INTERFACE_NODE
, &vtysh_interface_desc_cmd
);
3211 install_element(INTERFACE_NODE
, &vtysh_no_interface_desc_cmd
);
3212 install_element(INTERFACE_NODE
, &vtysh_end_all_cmd
);
3213 install_element(INTERFACE_NODE
, &vtysh_exit_interface_cmd
);
3214 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);
3215 install_element(LINK_PARAMS_NODE
, &vtysh_end_all_cmd
);
3216 install_element(LINK_PARAMS_NODE
, &vtysh_exit_interface_cmd
);
3217 install_element(INTERFACE_NODE
, &vtysh_quit_interface_cmd
);
3219 install_element(PW_NODE
, &vtysh_end_all_cmd
);
3220 install_element(PW_NODE
, &vtysh_exit_interface_cmd
);
3221 install_element(PW_NODE
, &vtysh_quit_interface_cmd
);
3223 install_element(NS_NODE
, &vtysh_end_all_cmd
);
3225 install_element(CONFIG_NODE
, &vtysh_ns_cmd
);
3226 install_element(NS_NODE
, &vtysh_exit_ns_cmd
);
3227 install_element(NS_NODE
, &vtysh_quit_ns_cmd
);
3229 install_element(VRF_NODE
, &vtysh_end_all_cmd
);
3230 install_element(VRF_NODE
, &vtysh_exit_vrf_cmd
);
3231 install_element(VRF_NODE
, &vtysh_quit_vrf_cmd
);
3233 install_element(CONFIG_NODE
, &router_eigrp_cmd
);
3234 install_element(CONFIG_NODE
, &router_babel_cmd
);
3235 install_element(CONFIG_NODE
, &router_rip_cmd
);
3236 install_element(CONFIG_NODE
, &router_ripng_cmd
);
3237 install_element(CONFIG_NODE
, &router_ospf_cmd
);
3238 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
3239 #if defined(HAVE_LDPD)
3240 install_element(CONFIG_NODE
, &ldp_mpls_ldp_cmd
);
3241 install_element(LDP_NODE
, &ldp_address_family_ipv4_cmd
);
3242 install_element(LDP_NODE
, &ldp_address_family_ipv6_cmd
);
3243 install_element(LDP_IPV4_NODE
, &ldp_interface_ifname_cmd
);
3244 install_element(LDP_IPV6_NODE
, &ldp_interface_ifname_cmd
);
3245 install_element(CONFIG_NODE
, &ldp_l2vpn_word_type_vpls_cmd
);
3246 install_element(LDP_L2VPN_NODE
, &ldp_member_pseudowire_ifname_cmd
);
3248 install_element(CONFIG_NODE
, &router_isis_cmd
);
3249 install_element(CONFIG_NODE
, &router_bgp_cmd
);
3250 install_element(BGP_NODE
, &address_family_vpnv4_cmd
);
3251 install_element(BGP_NODE
, &address_family_vpnv6_cmd
);
3252 #if defined(ENABLE_BGP_VNC)
3253 install_element(BGP_NODE
, &vnc_vrf_policy_cmd
);
3254 install_element(BGP_NODE
, &vnc_defaults_cmd
);
3255 install_element(BGP_NODE
, &vnc_nve_group_cmd
);
3256 install_element(BGP_NODE
, &vnc_l2_group_cmd
);
3258 install_element(BGP_NODE
, &address_family_ipv4_cmd
);
3259 install_element(BGP_NODE
, &address_family_ipv4_multicast_cmd
);
3260 install_element(BGP_NODE
, &address_family_ipv4_vpn_cmd
);
3261 install_element(BGP_NODE
, &address_family_ipv4_labeled_unicast_cmd
);
3262 install_element(BGP_NODE
, &address_family_ipv6_cmd
);
3263 install_element(BGP_NODE
, &address_family_ipv6_multicast_cmd
);
3264 install_element(BGP_NODE
, &address_family_ipv6_vpn_cmd
);
3265 install_element(BGP_NODE
, &address_family_ipv6_labeled_unicast_cmd
);
3266 install_element(BGP_NODE
, &address_family_evpn_cmd
);
3267 #if defined(HAVE_CUMULUS)
3268 install_element(BGP_NODE
, &address_family_evpn2_cmd
);
3270 install_element(BGP_VPNV4_NODE
, &exit_address_family_cmd
);
3271 install_element(BGP_VPNV6_NODE
, &exit_address_family_cmd
);
3272 install_element(BGP_IPV4_NODE
, &exit_address_family_cmd
);
3273 install_element(BGP_IPV4M_NODE
, &exit_address_family_cmd
);
3274 install_element(BGP_IPV4L_NODE
, &exit_address_family_cmd
);
3275 install_element(BGP_IPV6_NODE
, &exit_address_family_cmd
);
3276 install_element(BGP_IPV6M_NODE
, &exit_address_family_cmd
);
3277 install_element(BGP_EVPN_NODE
, &exit_address_family_cmd
);
3278 install_element(BGP_IPV6L_NODE
, &exit_address_family_cmd
);
3280 #if defined(HAVE_RPKI)
3281 install_element(CONFIG_NODE
, &rpki_cmd
);
3282 install_element(RPKI_NODE
, &rpki_exit_cmd
);
3283 install_element(RPKI_NODE
, &rpki_quit_cmd
);
3284 install_element(RPKI_NODE
, &vtysh_end_all_cmd
);
3288 install_element(BGP_EVPN_NODE
, &bgp_evpn_vni_cmd
);
3289 install_element(BGP_EVPN_VNI_NODE
, &exit_vni_cmd
);
3291 install_element(BGP_VRF_POLICY_NODE
, &exit_vrf_policy_cmd
);
3292 install_element(BGP_VNC_DEFAULTS_NODE
, &exit_vnc_config_cmd
);
3293 install_element(BGP_VNC_NVE_GROUP_NODE
, &exit_vnc_config_cmd
);
3294 install_element(BGP_VNC_L2_GROUP_NODE
, &exit_vnc_config_cmd
);
3296 install_element(CONFIG_NODE
, &key_chain_cmd
);
3297 install_element(CONFIG_NODE
, &vtysh_route_map_cmd
);
3298 install_element(CONFIG_NODE
, &vtysh_line_vty_cmd
);
3299 install_element(KEYCHAIN_NODE
, &key_cmd
);
3300 install_element(KEYCHAIN_NODE
, &key_chain_cmd
);
3301 install_element(KEYCHAIN_KEY_NODE
, &key_chain_cmd
);
3302 install_element(CONFIG_NODE
, &vtysh_interface_cmd
);
3303 install_element(CONFIG_NODE
, &vtysh_no_interface_cmd
);
3304 install_element(CONFIG_NODE
, &vtysh_no_interface_vrf_cmd
);
3305 install_element(CONFIG_NODE
, &vtysh_pseudowire_cmd
);
3306 install_element(INTERFACE_NODE
, &vtysh_link_params_cmd
);
3307 install_element(ENABLE_NODE
, &vtysh_show_running_config_cmd
);
3308 install_element(ENABLE_NODE
, &vtysh_copy_running_config_cmd
);
3310 install_element(CONFIG_NODE
, &vtysh_vrf_cmd
);
3311 install_element(CONFIG_NODE
, &vtysh_no_vrf_cmd
);
3313 /* "write terminal" command. */
3314 install_element(ENABLE_NODE
, &vtysh_write_terminal_cmd
);
3316 install_element(CONFIG_NODE
, &vtysh_integrated_config_cmd
);
3317 install_element(CONFIG_NODE
, &no_vtysh_integrated_config_cmd
);
3319 /* "write memory" command. */
3320 install_element(ENABLE_NODE
, &vtysh_write_memory_cmd
);
3322 install_element(VIEW_NODE
, &vtysh_terminal_length_cmd
);
3323 install_element(VIEW_NODE
, &vtysh_terminal_no_length_cmd
);
3324 install_element(VIEW_NODE
, &vtysh_show_daemons_cmd
);
3326 install_element(VIEW_NODE
, &vtysh_ping_cmd
);
3327 install_element(VIEW_NODE
, &vtysh_ping_ip_cmd
);
3328 install_element(VIEW_NODE
, &vtysh_traceroute_cmd
);
3329 install_element(VIEW_NODE
, &vtysh_traceroute_ip_cmd
);
3330 install_element(VIEW_NODE
, &vtysh_ping6_cmd
);
3331 install_element(VIEW_NODE
, &vtysh_traceroute6_cmd
);
3332 #if defined(HAVE_SHELL_ACCESS)
3333 install_element(VIEW_NODE
, &vtysh_telnet_cmd
);
3334 install_element(VIEW_NODE
, &vtysh_telnet_port_cmd
);
3335 install_element(VIEW_NODE
, &vtysh_ssh_cmd
);
3337 #if defined(HAVE_SHELL_ACCESS)
3338 install_element(ENABLE_NODE
, &vtysh_start_shell_cmd
);
3339 install_element(ENABLE_NODE
, &vtysh_start_bash_cmd
);
3340 install_element(ENABLE_NODE
, &vtysh_start_zsh_cmd
);
3343 install_element(VIEW_NODE
, &vtysh_show_debugging_cmd
);
3344 install_element(VIEW_NODE
, &vtysh_show_debugging_hashtable_cmd
);
3345 install_element(VIEW_NODE
, &vtysh_show_memory_cmd
);
3346 install_element(VIEW_NODE
, &vtysh_show_modules_cmd
);
3348 install_element(VIEW_NODE
, &vtysh_show_work_queues_cmd
);
3349 install_element(VIEW_NODE
, &vtysh_show_work_queues_daemon_cmd
);
3351 install_element(VIEW_NODE
, &vtysh_show_thread_cmd
);
3354 install_element(VIEW_NODE
, &vtysh_show_logging_cmd
);
3355 install_element(CONFIG_NODE
, &vtysh_log_stdout_cmd
);
3356 install_element(CONFIG_NODE
, &vtysh_log_stdout_level_cmd
);
3357 install_element(CONFIG_NODE
, &no_vtysh_log_stdout_cmd
);
3358 install_element(CONFIG_NODE
, &vtysh_log_file_cmd
);
3359 install_element(CONFIG_NODE
, &vtysh_log_file_level_cmd
);
3360 install_element(CONFIG_NODE
, &no_vtysh_log_file_cmd
);
3361 install_element(CONFIG_NODE
, &vtysh_log_monitor_cmd
);
3362 install_element(CONFIG_NODE
, &no_vtysh_log_monitor_cmd
);
3363 install_element(CONFIG_NODE
, &vtysh_log_syslog_cmd
);
3364 install_element(CONFIG_NODE
, &no_vtysh_log_syslog_cmd
);
3365 install_element(CONFIG_NODE
, &vtysh_log_trap_cmd
);
3366 install_element(CONFIG_NODE
, &no_vtysh_log_trap_cmd
);
3367 install_element(CONFIG_NODE
, &vtysh_log_facility_cmd
);
3368 install_element(CONFIG_NODE
, &no_vtysh_log_facility_cmd
);
3369 install_element(CONFIG_NODE
, &vtysh_log_record_priority_cmd
);
3370 install_element(CONFIG_NODE
, &no_vtysh_log_record_priority_cmd
);
3371 install_element(CONFIG_NODE
, &vtysh_log_timestamp_precision_cmd
);
3372 install_element(CONFIG_NODE
, &no_vtysh_log_timestamp_precision_cmd
);
3374 install_element(CONFIG_NODE
, &vtysh_service_password_encrypt_cmd
);
3375 install_element(CONFIG_NODE
, &no_vtysh_service_password_encrypt_cmd
);
3377 install_element(CONFIG_NODE
, &vtysh_password_cmd
);
3378 install_element(CONFIG_NODE
, &vtysh_enable_password_cmd
);
3379 install_element(CONFIG_NODE
, &no_vtysh_enable_password_cmd
);