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
);
316 if (strncmp("en", vector_slot(vline
, 0), 2) == 0) {
317 fprintf(stdout
, "%% Command not allowed: enable\n");
322 saved_ret
= ret
= cmd_execute_command(vline
, vty
, &cmd
, 1);
323 saved_node
= vty
->node
;
325 /* If command doesn't succeeded in current node, try to walk up in node
327 * Changing vty->node is enough to try it just out without actual walkup
330 while (ret
!= CMD_SUCCESS
&& ret
!= CMD_SUCCESS_DAEMON
331 && ret
!= CMD_WARNING
&& ret
!= CMD_WARNING_CONFIG_FAILED
332 && vty
->node
> CONFIG_NODE
) {
333 vty
->node
= node_parent(vty
->node
);
334 ret
= cmd_execute_command(vline
, vty
, &cmd
, 1);
338 vty
->node
= saved_node
;
340 /* If command succeeded in any other node than current (tried > 0) we
342 * to move into node in the vtysh where it succeeded. */
343 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
344 || ret
== CMD_WARNING
) {
345 if ((saved_node
== BGP_VPNV4_NODE
346 || saved_node
== BGP_VPNV6_NODE
347 || saved_node
== BGP_IPV4_NODE
348 || saved_node
== BGP_IPV6_NODE
349 || saved_node
== BGP_FLOWSPECV4_NODE
350 || saved_node
== BGP_FLOWSPECV6_NODE
351 || saved_node
== BGP_IPV4M_NODE
352 || saved_node
== BGP_IPV4L_NODE
353 || saved_node
== BGP_IPV6L_NODE
354 || saved_node
== BGP_IPV6M_NODE
355 || saved_node
== BGP_EVPN_NODE
356 || saved_node
== LDP_IPV4_NODE
357 || saved_node
== LDP_IPV6_NODE
)
359 vtysh_execute("exit-address-family");
360 } else if ((saved_node
== BGP_EVPN_VNI_NODE
) && (tried
== 1)) {
361 vtysh_execute("exit-vni");
362 } else if (saved_node
== BGP_VRF_POLICY_NODE
&& (tried
== 1)) {
363 vtysh_execute("exit-vrf-policy");
364 } else if ((saved_node
== BGP_VNC_DEFAULTS_NODE
365 || saved_node
== BGP_VNC_NVE_GROUP_NODE
366 || saved_node
== BGP_VNC_L2_GROUP_NODE
)
368 vtysh_execute("exit-vnc");
369 } else if ((saved_node
== KEYCHAIN_KEY_NODE
370 || saved_node
== LDP_PSEUDOWIRE_NODE
371 || saved_node
== LDP_IPV4_IFACE_NODE
372 || saved_node
== LDP_IPV6_IFACE_NODE
)
374 vtysh_execute("exit");
376 vtysh_execute("end");
377 vtysh_execute("configure terminal");
380 /* If command didn't succeed in any node, continue with return value
387 cmd_free_strvec(vline
);
392 case CMD_WARNING_CONFIG_FAILED
:
393 if (vty
->type
== VTY_FILE
)
394 fprintf(stdout
, "Warning...\n");
396 case CMD_ERR_AMBIGUOUS
:
397 fprintf(stdout
, "%% Ambiguous command: %s\n", line
);
399 case CMD_ERR_NO_MATCH
:
400 fprintf(stdout
, "%% Unknown command: %s\n", line
);
402 case CMD_ERR_INCOMPLETE
:
403 fprintf(stdout
, "%% Command incomplete: %s\n", line
);
405 case CMD_SUCCESS_DAEMON
: {
407 * FIXME: Don't open pager for exit commands. popen() causes
408 * problems if exited from vtysh at all. This hack shouldn't
409 * cause any problem but is really ugly.
412 if (pager
&& vtysh_pager_name
&& outputfile
== stdout
413 && (strncmp(line
, "exit", 4) != 0)) {
414 fp
= popen(vtysh_pager_name
, "w");
416 perror("popen failed for pager");
422 if (!strcmp(cmd
->string
, "configure terminal")) {
423 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
424 cmd_stat
= vtysh_client_execute(
425 &vtysh_client
[i
], line
, fp
);
426 if (cmd_stat
== CMD_WARNING
)
432 vline
= cmd_make_strvec(line
);
435 if (pager
&& vtysh_pager_name
&& fp
436 && fp
!= outputfile
&& closepager
) {
437 if (pclose(fp
) == -1) {
438 perror("pclose failed for pager");
445 ret
= cmd_execute_command(vline
, vty
, &cmd
, 1);
446 cmd_free_strvec(vline
);
447 if (ret
!= CMD_SUCCESS_DAEMON
)
449 } else if (cmd
->func
) {
450 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
455 cmd_stat
= CMD_SUCCESS
;
456 struct vtysh_client
*vc
;
457 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
458 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
459 if (vtysh_client
[i
].fd
< 0
460 && (cmd
->daemon
== vtysh_client
[i
].flag
)) {
461 bool any_inst
= false;
462 for (vc
= &vtysh_client
[i
]; vc
;
468 "%s is not running\n",
469 vtysh_client
[i
].name
);
473 cmd_stat
= vtysh_client_execute(
474 &vtysh_client
[i
], line
, fp
);
475 if (cmd_stat
!= CMD_SUCCESS
)
479 if (cmd_stat
!= CMD_SUCCESS
)
483 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
486 if (pager
&& vtysh_pager_name
&& fp
&& closepager
&& fp
!= outputfile
) {
487 if (pclose(fp
) == -1) {
488 perror("pclose failed for pager");
495 int vtysh_execute_no_pager(const char *line
)
497 return vtysh_execute_func(line
, 0);
500 int vtysh_execute(const char *line
)
502 return vtysh_execute_func(line
, 1);
505 static char *trim(char *s
)
516 while (end
>= s
&& isspace((int)*end
))
520 while (*s
&& isspace((int)*s
))
526 int vtysh_mark_file(const char *filename
)
533 const struct cmd_element
*cmd
;
534 int saved_ret
, prev_node
;
536 char *vty_buf_copy
= NULL
;
537 char *vty_buf_trimmed
= NULL
;
539 if (strncmp("-", filename
, 1) == 0)
542 confp
= fopen(filename
, "r");
545 fprintf(stderr
, "%% Can't open config file %s due to '%s'.\n",
546 filename
, safe_strerror(errno
));
547 return (CMD_ERR_NO_FILE
);
551 vty
->wfd
= STDERR_FILENO
;
552 vty
->type
= VTY_TERM
;
553 vty
->node
= CONFIG_NODE
;
555 vtysh_execute_no_pager("enable");
556 vtysh_execute_no_pager("configure terminal");
557 vty_buf_copy
= XCALLOC(MTYPE_VTYSH_CMD
, VTY_BUFSIZ
);
559 while (fgets(vty
->buf
, VTY_BUFSIZ
, confp
)) {
562 strcpy(vty_buf_copy
, vty
->buf
);
563 vty_buf_trimmed
= trim(vty_buf_copy
);
566 case LDP_IPV4_IFACE_NODE
:
567 if (strncmp(vty_buf_copy
, " ", 3)) {
568 fprintf(outputfile
, " end\n");
569 vty
->node
= LDP_IPV4_NODE
;
572 case LDP_IPV6_IFACE_NODE
:
573 if (strncmp(vty_buf_copy
, " ", 3)) {
574 fprintf(outputfile
, " end\n");
575 vty
->node
= LDP_IPV6_NODE
;
578 case LDP_PSEUDOWIRE_NODE
:
579 if (strncmp(vty_buf_copy
, " ", 2)) {
580 fprintf(outputfile
, " end\n");
581 vty
->node
= LDP_L2VPN_NODE
;
588 if (vty_buf_trimmed
[0] == '!' || vty_buf_trimmed
[0] == '#') {
589 fprintf(outputfile
, "%s", vty
->buf
);
593 /* Split readline string up into the vector. */
594 vline
= cmd_make_strvec(vty
->buf
);
597 fprintf(outputfile
, "%s", vty
->buf
);
601 /* Ignore the "end" lines, we will generate these where
603 if (strlen(vty_buf_trimmed
) == 3
604 && strncmp("end", vty_buf_trimmed
, 3) == 0) {
605 cmd_free_strvec(vline
);
609 prev_node
= vty
->node
;
610 saved_ret
= ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
612 /* If command doesn't succeeded in current node, try to walk up
614 * Changing vty->node is enough to try it just out without
617 while (ret
!= CMD_SUCCESS
&& ret
!= CMD_SUCCESS_DAEMON
618 && ret
!= CMD_WARNING
&& ret
!= CMD_WARNING_CONFIG_FAILED
619 && vty
->node
> CONFIG_NODE
) {
620 vty
->node
= node_parent(vty
->node
);
621 ret
= cmd_execute_command_strict(vline
, vty
, &cmd
);
625 /* If command succeeded in any other node than current (tried >
627 * to move into node in the vtysh where it succeeded. */
628 if (ret
== CMD_SUCCESS
|| ret
== CMD_SUCCESS_DAEMON
629 || ret
== CMD_WARNING
) {
630 if ((prev_node
== BGP_VPNV4_NODE
631 || prev_node
== BGP_VPNV6_NODE
632 || prev_node
== BGP_IPV4_NODE
633 || prev_node
== BGP_IPV6_NODE
634 || prev_node
== BGP_FLOWSPECV4_NODE
635 || prev_node
== BGP_FLOWSPECV6_NODE
636 || prev_node
== BGP_IPV4L_NODE
637 || prev_node
== BGP_IPV6L_NODE
638 || prev_node
== BGP_IPV4M_NODE
639 || prev_node
== BGP_IPV6M_NODE
640 || prev_node
== BGP_EVPN_NODE
)
642 fprintf(outputfile
, "exit-address-family\n");
643 } else if ((prev_node
== BGP_EVPN_VNI_NODE
)
645 fprintf(outputfile
, "exit-vni\n");
646 } else if ((prev_node
== KEYCHAIN_KEY_NODE
)
648 fprintf(outputfile
, "exit\n");
650 fprintf(outputfile
, "end\n");
653 /* If command didn't succeed in any node, continue with return
658 vty
->node
= prev_node
;
661 cmd_free_strvec(vline
);
664 case CMD_WARNING_CONFIG_FAILED
:
665 if (vty
->type
== VTY_FILE
)
666 fprintf(stderr
, "line %d: Warning...: %s\n",
670 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
672 case CMD_ERR_AMBIGUOUS
:
673 fprintf(stderr
, "line %d: %% Ambiguous command: %s\n",
677 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
678 return CMD_ERR_AMBIGUOUS
;
679 case CMD_ERR_NO_MATCH
:
680 fprintf(stderr
, "line %d: %% Unknown command: %s\n",
684 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
685 return CMD_ERR_NO_MATCH
;
686 case CMD_ERR_INCOMPLETE
:
687 fprintf(stderr
, "line %d: %% Command incomplete: %s\n",
691 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
692 return CMD_ERR_INCOMPLETE
;
694 fprintf(stdout
, "%s", vty
->buf
);
696 case CMD_SUCCESS_DAEMON
: {
698 int cmd_stat
= CMD_SUCCESS
;
700 fprintf(outputfile
, "%s", vty
->buf
);
701 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
702 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
703 cmd_stat
= vtysh_client_execute(
704 &vtysh_client
[i
], vty
->buf
,
706 if (cmd_stat
!= CMD_SUCCESS
)
710 if (cmd_stat
!= CMD_SUCCESS
)
714 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
718 /* This is the end */
719 fprintf(outputfile
, "\nend\n");
721 XFREE(MTYPE_VTYSH_CMD
, vty_buf_copy
);
729 /* Configration make from file. */
730 int vtysh_config_from_file(struct vty
*vty
, FILE *fp
)
733 const struct cmd_element
*cmd
;
735 int retcode
= CMD_SUCCESS
;
737 while (fgets(vty
->buf
, VTY_BUFSIZ
, fp
)) {
740 ret
= command_config_read_one_line(vty
, &cmd
, 1);
744 case CMD_WARNING_CONFIG_FAILED
:
745 if (vty
->type
== VTY_FILE
)
746 fprintf(stderr
, "line %d: Warning[%d]...: %s\n",
747 lineno
, vty
->node
, vty
->buf
);
748 retcode
= ret
; /* once we have an error, we remember &
751 case CMD_ERR_AMBIGUOUS
:
753 "line %d: %% Ambiguous command[%d]: %s\n",
754 lineno
, vty
->node
, vty
->buf
);
755 retcode
= CMD_ERR_AMBIGUOUS
; /* once we have an error,
759 case CMD_ERR_NO_MATCH
:
760 fprintf(stderr
, "line %d: %% Unknown command[%d]: %s",
761 lineno
, vty
->node
, vty
->buf
);
762 retcode
= CMD_ERR_NO_MATCH
; /* once we have an error, we
763 remember & return that */
765 case CMD_ERR_INCOMPLETE
:
767 "line %d: %% Command incomplete[%d]: %s\n",
768 lineno
, vty
->node
, vty
->buf
);
769 retcode
= CMD_ERR_INCOMPLETE
; /* once we have an error,
773 case CMD_SUCCESS_DAEMON
: {
775 int cmd_stat
= CMD_SUCCESS
;
777 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
778 if (cmd
->daemon
& vtysh_client
[i
].flag
) {
779 cmd_stat
= vtysh_client_execute(
780 &vtysh_client
[i
], vty
->buf
,
783 * CMD_WARNING - Can mean that the
785 * parsed successfully but it was
787 * in a few spots. As such if we
789 * CMD_WARNING from a daemon we
791 * talking to the other daemons for the
795 if (cmd_stat
!= CMD_SUCCESS
796 && cmd_stat
!= CMD_WARNING
) {
798 "line %d: Failure to communicate[%d] to %s, line: %s\n",
800 vtysh_client
[i
].name
,
807 if (cmd_stat
!= CMD_SUCCESS
)
811 (*cmd
->func
)(cmd
, vty
, 0, NULL
);
819 /* We don't care about the point of the cursor when '?' is typed. */
820 static int vtysh_rl_describe(void)
827 struct cmd_token
*token
;
829 vline
= cmd_make_strvec(rl_line_buffer
);
831 /* In case of '> ?'. */
833 vline
= vector_init(1);
834 vector_set(vline
, NULL
);
835 } else if (rl_end
&& isspace((int)rl_line_buffer
[rl_end
- 1]))
836 vector_set(vline
, NULL
);
838 fprintf(stdout
, "\n");
840 describe
= cmd_describe_command(vline
, vty
, &ret
);
842 /* Ambiguous and no match error. */
844 case CMD_ERR_AMBIGUOUS
:
845 cmd_free_strvec(vline
);
846 vector_free(describe
);
847 fprintf(stdout
, "%% Ambiguous command.\n");
851 case CMD_ERR_NO_MATCH
:
852 cmd_free_strvec(vline
);
854 vector_free(describe
);
855 fprintf(stdout
, "%% There is no matched command.\n");
861 /* Get width of command string. */
863 for (i
= 0; i
< vector_active(describe
); i
++)
864 if ((token
= vector_slot(describe
, i
)) != NULL
) {
865 if (token
->text
[0] == '\0')
868 int len
= strlen(token
->text
);
874 for (i
= 0; i
< vector_active(describe
); i
++)
875 if ((token
= vector_slot(describe
, i
)) != NULL
) {
877 fprintf(stdout
, " %-s\n", token
->text
);
879 fprintf(stdout
, " %-*s %s\n", width
,
880 token
->text
, token
->desc
);
882 if (IS_VARYING_TOKEN(token
->type
)) {
883 const char *ref
= vector_slot(
884 vline
, vector_active(vline
) - 1);
886 vector varcomps
= vector_init(VECTOR_MIN_SIZE
);
887 cmd_variable_complete(token
, ref
, varcomps
);
889 if (vector_active(varcomps
) > 0) {
891 rl_get_screen_size(&rows
, &cols
);
893 char *ac
= cmd_variable_comp2str(
895 fprintf(stdout
, "%s\n", ac
);
896 XFREE(MTYPE_TMP
, ac
);
899 vector_free(varcomps
);
903 cmd_free_strvec(vline
);
904 vector_free(describe
);
911 /* Result of cmd_complete_command() call will be stored here
912 * and used in new_completion() in order to put the space in
913 * correct places only. */
916 static char *command_generator(const char *text
, int state
)
919 static char **matched
= NULL
;
920 static int index
= 0;
926 if (vty
->node
== AUTH_NODE
|| vty
->node
== AUTH_ENABLE_NODE
)
929 vline
= cmd_make_strvec(rl_line_buffer
);
933 if (rl_end
&& isspace((int)rl_line_buffer
[rl_end
- 1]))
934 vector_set(vline
, NULL
);
936 matched
= cmd_complete_command(vline
, vty
, &complete_status
);
937 cmd_free_strvec(vline
);
940 if (matched
&& matched
[index
])
941 /* this is free()'d by readline, but we leak 1 count of
942 * MTYPE_COMPLETION */
943 return matched
[index
++];
945 XFREE(MTYPE_TMP
, matched
);
951 static char **new_completion(char *text
, int start
, int end
)
955 matches
= rl_completion_matches(text
, command_generator
);
959 if (complete_status
!= CMD_COMPLETE_FULL_MATCH
)
960 /* only append a space on full match */
961 rl_completion_append_character
= '\0';
967 /* Vty node structures. */
968 static struct cmd_node bgp_node
= {
969 BGP_NODE
, "%s(config-router)# ",
972 static struct cmd_node rip_node
= {
973 RIP_NODE
, "%s(config-router)# ",
976 static struct cmd_node isis_node
= {
977 ISIS_NODE
, "%s(config-router)# ",
980 static struct cmd_node interface_node
= {
981 INTERFACE_NODE
, "%s(config-if)# ",
984 static struct cmd_node pw_node
= {
985 PW_NODE
, "%s(config-pw)# ",
988 static struct cmd_node logicalrouter_node
= {
989 LOGICALROUTER_NODE
, "%s(config-logical-router)# ",
992 static struct cmd_node vrf_node
= {
993 VRF_NODE
, "%s(config-vrf)# ",
996 static struct cmd_node rmap_node
= {RMAP_NODE
, "%s(config-route-map)# "};
998 static struct cmd_node zebra_node
= {ZEBRA_NODE
, "%s(config-router)# "};
1000 static struct cmd_node bgp_vpnv4_node
= {BGP_VPNV4_NODE
,
1001 "%s(config-router-af)# "};
1003 static struct cmd_node bgp_vpnv6_node
= {BGP_VPNV6_NODE
,
1004 "%s(config-router-af)# "};
1006 static struct cmd_node bgp_flowspecv4_node
= {BGP_FLOWSPECV4_NODE
,
1007 "%s(config-router-af)# "};
1009 static struct cmd_node bgp_flowspecv6_node
= {BGP_FLOWSPECV6_NODE
,
1010 "%s(config-router-af)# "};
1012 static struct cmd_node bgp_ipv4_node
= {BGP_IPV4_NODE
,
1013 "%s(config-router-af)# "};
1015 static struct cmd_node bgp_ipv4m_node
= {BGP_IPV4M_NODE
,
1016 "%s(config-router-af)# "};
1018 static struct cmd_node bgp_ipv4l_node
= {BGP_IPV4L_NODE
,
1019 "%s(config-router-af)# "};
1021 static struct cmd_node bgp_ipv6_node
= {BGP_IPV6_NODE
,
1022 "%s(config-router-af)# "};
1024 static struct cmd_node bgp_ipv6m_node
= {BGP_IPV6M_NODE
,
1025 "%s(config-router-af)# "};
1027 static struct cmd_node bgp_evpn_node
= {BGP_EVPN_NODE
,
1028 "%s(config-router-af)# "};
1030 static struct cmd_node bgp_evpn_vni_node
= {BGP_EVPN_VNI_NODE
,
1031 "%s(config-router-af-vni)# "};
1033 static struct cmd_node bgp_ipv6l_node
= {BGP_IPV6L_NODE
,
1034 "%s(config-router-af)# "};
1036 static struct cmd_node bgp_vnc_defaults_node
= {
1037 BGP_VNC_DEFAULTS_NODE
, "%s(config-router-vnc-defaults)# "};
1039 static struct cmd_node bgp_vnc_nve_group_node
= {
1040 BGP_VNC_NVE_GROUP_NODE
, "%s(config-router-vnc-nve-group)# "};
1042 static struct cmd_node bgp_vrf_policy_node
= {BGP_VRF_POLICY_NODE
,
1043 "%s(config-router-vrf-policy)# "};
1045 static struct cmd_node bgp_vnc_l2_group_node
= {
1046 BGP_VNC_L2_GROUP_NODE
, "%s(config-router-vnc-l2-group)# "};
1048 static struct cmd_node ospf_node
= {OSPF_NODE
, "%s(config-router)# "};
1050 static struct cmd_node eigrp_node
= {EIGRP_NODE
, "%s(config-router)# "};
1052 static struct cmd_node babel_node
= {BABEL_NODE
, "%s(config-router)# "};
1054 static struct cmd_node ripng_node
= {RIPNG_NODE
, "%s(config-router)# "};
1056 static struct cmd_node ospf6_node
= {OSPF6_NODE
, "%s(config-ospf6)# "};
1058 static struct cmd_node ldp_node
= {LDP_NODE
, "%s(config-ldp)# "};
1060 static struct cmd_node ldp_ipv4_node
= {LDP_IPV4_NODE
, "%s(config-ldp-af)# "};
1062 static struct cmd_node ldp_ipv6_node
= {LDP_IPV6_NODE
, "%s(config-ldp-af)# "};
1064 static struct cmd_node ldp_ipv4_iface_node
= {LDP_IPV4_IFACE_NODE
,
1065 "%s(config-ldp-af-if)# "};
1067 static struct cmd_node ldp_ipv6_iface_node
= {LDP_IPV6_IFACE_NODE
,
1068 "%s(config-ldp-af-if)# "};
1070 static struct cmd_node ldp_l2vpn_node
= {LDP_L2VPN_NODE
, "%s(config-l2vpn)# "};
1072 static struct cmd_node ldp_pseudowire_node
= {LDP_PSEUDOWIRE_NODE
,
1073 "%s(config-l2vpn-pw)# "};
1075 static struct cmd_node keychain_node
= {KEYCHAIN_NODE
, "%s(config-keychain)# "};
1077 static struct cmd_node keychain_key_node
= {KEYCHAIN_KEY_NODE
,
1078 "%s(config-keychain-key)# "};
1080 struct cmd_node link_params_node
= {
1081 LINK_PARAMS_NODE
, "%s(config-link-params)# ",
1084 #if defined(HAVE_RPKI)
1085 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
1088 /* Defined in lib/vty.c */
1089 extern struct cmd_node vty_node
;
1091 /* When '^Z' is received from vty, move down to the enable mode. */
1092 static int vtysh_end(void)
1094 switch (vty
->node
) {
1097 /* Nothing to do. */
1100 vty
->node
= ENABLE_NODE
;
1106 DEFUNSH(VTYSH_REALLYALL
, vtysh_end_all
, vtysh_end_all_cmd
, "end",
1107 "End current mode and change to enable mode\n")
1112 DEFUNSH(VTYSH_BGPD
, router_bgp
, router_bgp_cmd
,
1113 "router bgp [(1-4294967295) [<view|vrf> WORD]]",
1114 ROUTER_STR BGP_STR AS_STR
1115 "BGP view\nBGP VRF\n"
1118 vty
->node
= BGP_NODE
;
1122 DEFUNSH(VTYSH_BGPD
, address_family_vpnv4
, address_family_vpnv4_cmd
,
1123 "address-family vpnv4 [unicast]",
1124 "Enter Address Family command mode\n"
1126 "Address Family modifier\n")
1128 vty
->node
= BGP_VPNV4_NODE
;
1132 DEFUNSH(VTYSH_BGPD
, address_family_vpnv6
, address_family_vpnv6_cmd
,
1133 "address-family vpnv6 [unicast]",
1134 "Enter Address Family command mode\n"
1136 "Address Family modifier\n")
1138 vty
->node
= BGP_VPNV6_NODE
;
1142 DEFUNSH(VTYSH_BGPD
, address_family_ipv4
, address_family_ipv4_cmd
,
1143 "address-family ipv4 [unicast]",
1144 "Enter Address Family command mode\n"
1146 "Address Family Modifier\n")
1148 vty
->node
= BGP_IPV4_NODE
;
1152 DEFUNSH(VTYSH_BGPD
, address_family_flowspecv4
, address_family_flowspecv4_cmd
,
1153 "address-family ipv4 flowspec",
1154 "Enter Address Family command mode\n"
1156 "Address Family Modifier\n")
1158 vty
->node
= BGP_FLOWSPECV4_NODE
;
1162 DEFUNSH(VTYSH_BGPD
, address_family_flowspecv6
, address_family_flowspecv6_cmd
,
1163 "address-family ipv6 flowspec",
1164 "Enter Address Family command mode\n"
1166 "Address Family Modifier\n")
1168 vty
->node
= BGP_FLOWSPECV6_NODE
;
1172 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_multicast
,
1173 address_family_ipv4_multicast_cmd
, "address-family ipv4 multicast",
1174 "Enter Address Family command mode\n"
1176 "Address Family modifier\n")
1178 vty
->node
= BGP_IPV4M_NODE
;
1182 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_vpn
, address_family_ipv4_vpn_cmd
,
1183 "address-family ipv4 vpn",
1184 "Enter Address Family command mode\n"
1186 "Address Family modifier\n")
1188 vty
->node
= BGP_VPNV4_NODE
;
1192 DEFUNSH(VTYSH_BGPD
, address_family_ipv4_labeled_unicast
,
1193 address_family_ipv4_labeled_unicast_cmd
,
1194 "address-family ipv4 labeled-unicast",
1195 "Enter Address Family command mode\n"
1197 "Address Family modifier\n")
1199 vty
->node
= BGP_IPV4L_NODE
;
1203 DEFUNSH(VTYSH_BGPD
, address_family_ipv6
, address_family_ipv6_cmd
,
1204 "address-family ipv6 [unicast]",
1205 "Enter Address Family command mode\n"
1207 "Address Family modifier\n")
1209 vty
->node
= BGP_IPV6_NODE
;
1213 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_multicast
,
1214 address_family_ipv6_multicast_cmd
, "address-family ipv6 multicast",
1215 "Enter Address Family command mode\n"
1217 "Address Family modifier\n")
1219 vty
->node
= BGP_IPV6M_NODE
;
1223 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_vpn
, address_family_ipv6_vpn_cmd
,
1224 "address-family ipv6 vpn",
1225 "Enter Address Family command mode\n"
1227 "Address Family modifier\n")
1229 vty
->node
= BGP_VPNV6_NODE
;
1233 DEFUNSH(VTYSH_BGPD
, address_family_ipv6_labeled_unicast
,
1234 address_family_ipv6_labeled_unicast_cmd
,
1235 "address-family ipv6 labeled-unicast",
1236 "Enter Address Family command mode\n"
1238 "Address Family modifier\n")
1240 vty
->node
= BGP_IPV6L_NODE
;
1244 #if defined(HAVE_RPKI)
1249 "Enable rpki and enter rpki configuration mode\n")
1251 vty
->node
= RPKI_NODE
;
1259 "Exit current mode and down to previous mode\n")
1261 vty
->node
= CONFIG_NODE
;
1269 "Exit current mode and down to previous mode\n")
1271 return rpki_exit(self
, vty
, argc
, argv
);
1275 DEFUNSH(VTYSH_BGPD
, address_family_evpn
, address_family_evpn_cmd
,
1276 "address-family <l2vpn evpn>",
1277 "Enter Address Family command mode\n"
1279 "Address Family modifier\n")
1281 vty
->node
= BGP_EVPN_NODE
;
1285 #if defined(HAVE_CUMULUS)
1286 DEFUNSH_HIDDEN(VTYSH_BGPD
, address_family_evpn2
, address_family_evpn2_cmd
,
1287 "address-family evpn",
1288 "Enter Address Family command mode\n"
1289 "EVPN Address family\n")
1291 vty
->node
= BGP_EVPN_NODE
;
1296 DEFUNSH(VTYSH_BGPD
, bgp_evpn_vni
, bgp_evpn_vni_cmd
, "vni (1-16777215)",
1297 "VXLAN Network Identifier\n"
1300 vty
->node
= BGP_EVPN_VNI_NODE
;
1304 #if defined(ENABLE_BGP_VNC)
1305 DEFUNSH(VTYSH_BGPD
, vnc_defaults
, vnc_defaults_cmd
, "vnc defaults",
1306 "VNC/RFP related configuration\n"
1307 "Configure default NVE group\n")
1309 vty
->node
= BGP_VNC_DEFAULTS_NODE
;
1313 DEFUNSH(VTYSH_BGPD
, vnc_nve_group
, vnc_nve_group_cmd
, "vnc nve-group NAME",
1314 "VNC/RFP related configuration\n"
1315 "Configure a NVE group\n"
1318 vty
->node
= BGP_VNC_NVE_GROUP_NODE
;
1322 DEFUNSH(VTYSH_BGPD
, vnc_vrf_policy
, vnc_vrf_policy_cmd
, "vrf-policy NAME",
1323 "Configure a VRF policy group\n"
1326 vty
->node
= BGP_VRF_POLICY_NODE
;
1330 DEFUNSH(VTYSH_BGPD
, vnc_l2_group
, vnc_l2_group_cmd
, "vnc l2-group NAME",
1331 "VNC/RFP related configuration\n"
1332 "Configure a L2 group\n"
1335 vty
->node
= BGP_VNC_L2_GROUP_NODE
;
1340 DEFUNSH(VTYSH_RIPD
, key_chain
, key_chain_cmd
, "key chain WORD",
1341 "Authentication key management\n"
1342 "Key-chain management\n"
1345 vty
->node
= KEYCHAIN_NODE
;
1349 DEFUNSH(VTYSH_RIPD
, key
, key_cmd
, "key (0-2147483647)",
1351 "Key identifier number\n")
1353 vty
->node
= KEYCHAIN_KEY_NODE
;
1357 DEFUNSH(VTYSH_RIPD
, router_rip
, router_rip_cmd
, "router rip",
1360 vty
->node
= RIP_NODE
;
1364 DEFUNSH(VTYSH_RIPNGD
, router_ripng
, router_ripng_cmd
, "router ripng",
1365 ROUTER_STR
"RIPng\n")
1367 vty
->node
= RIPNG_NODE
;
1371 DEFUNSH(VTYSH_OSPFD
, router_ospf
, router_ospf_cmd
,
1372 "router ospf [(1-65535)] [vrf NAME]",
1373 "Enable a routing process\n"
1374 "Start OSPF configuration\n"
1378 vty
->node
= OSPF_NODE
;
1382 DEFUNSH(VTYSH_EIGRPD
, router_eigrp
, router_eigrp_cmd
, "router eigrp (1-65535)",
1383 "Enable a routing process\n"
1384 "Start EIGRP configuration\n"
1385 "AS number to use\n")
1387 vty
->node
= EIGRP_NODE
;
1391 DEFUNSH(VTYSH_BABELD
, router_babel
, router_babel_cmd
, "router babel",
1392 "Enable a routing process\n"
1393 "Make Babel instance command\n")
1395 vty
->node
= BABEL_NODE
;
1399 DEFUNSH(VTYSH_OSPF6D
, router_ospf6
, router_ospf6_cmd
, "router ospf6",
1400 ROUTER_STR OSPF6_STR
)
1402 vty
->node
= OSPF6_NODE
;
1406 #if defined(HAVE_LDPD)
1407 DEFUNSH(VTYSH_LDPD
, ldp_mpls_ldp
, ldp_mpls_ldp_cmd
, "mpls ldp",
1408 "Global MPLS configuration subcommands\n"
1409 "Label Distribution Protocol\n")
1411 vty
->node
= LDP_NODE
;
1415 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv4
, ldp_address_family_ipv4_cmd
,
1416 "address-family ipv4",
1417 "Configure Address Family and its parameters\n"
1420 vty
->node
= LDP_IPV4_NODE
;
1424 DEFUNSH(VTYSH_LDPD
, ldp_address_family_ipv6
, ldp_address_family_ipv6_cmd
,
1425 "address-family ipv6",
1426 "Configure Address Family and its parameters\n"
1429 vty
->node
= LDP_IPV6_NODE
;
1433 DEFUNSH(VTYSH_LDPD
, ldp_exit_address_family
, ldp_exit_address_family_cmd
,
1434 "exit-address-family", "Exit from Address Family configuration mode\n")
1436 if (vty
->node
== LDP_IPV4_NODE
|| vty
->node
== LDP_IPV6_NODE
)
1437 vty
->node
= LDP_NODE
;
1441 DEFUNSH(VTYSH_LDPD
, ldp_interface_ifname
, ldp_interface_ifname_cmd
,
1443 "Enable LDP on an interface and enter interface submode\n"
1444 "Interface's name\n")
1446 switch (vty
->node
) {
1448 vty
->node
= LDP_IPV4_IFACE_NODE
;
1451 vty
->node
= LDP_IPV6_IFACE_NODE
;
1460 DEFUNSH(VTYSH_LDPD
, ldp_l2vpn_word_type_vpls
, ldp_l2vpn_word_type_vpls_cmd
,
1461 "l2vpn WORD type vpls",
1462 "Configure l2vpn commands\n"
1465 "Virtual Private LAN Service\n")
1467 vty
->node
= LDP_L2VPN_NODE
;
1471 DEFUNSH(VTYSH_LDPD
, ldp_member_pseudowire_ifname
,
1472 ldp_member_pseudowire_ifname_cmd
, "member pseudowire IFNAME",
1473 "L2VPN member configuration\n"
1474 "Pseudowire interface\n"
1475 "Interface's name\n")
1477 vty
->node
= LDP_PSEUDOWIRE_NODE
;
1482 DEFUNSH(VTYSH_ISISD
, router_isis
, router_isis_cmd
, "router isis WORD",
1485 "ISO Routing area tag\n")
1487 vty
->node
= ISIS_NODE
;
1491 DEFUNSH(VTYSH_RMAP
, vtysh_route_map
, vtysh_route_map_cmd
,
1492 "route-map WORD <deny|permit> (1-65535)",
1493 "Create route-map or enter route-map command mode\n"
1495 "Route map denies set operations\n"
1496 "Route map permits set operations\n"
1497 "Sequence to insert to/delete from existing route-map entry\n")
1499 vty
->node
= RMAP_NODE
;
1503 DEFUNSH(VTYSH_ALL
, vtysh_line_vty
, vtysh_line_vty_cmd
, "line vty",
1504 "Configure a terminal line\n"
1505 "Virtual terminal\n")
1507 vty
->node
= VTY_NODE
;
1511 DEFUNSH(VTYSH_REALLYALL
, vtysh_enable
, vtysh_enable_cmd
, "enable",
1512 "Turn on privileged mode command\n")
1514 vty
->node
= ENABLE_NODE
;
1518 DEFUNSH(VTYSH_REALLYALL
, vtysh_disable
, vtysh_disable_cmd
, "disable",
1519 "Turn off privileged mode command\n")
1521 if (vty
->node
== ENABLE_NODE
)
1522 vty
->node
= VIEW_NODE
;
1526 DEFUNSH(VTYSH_REALLYALL
, vtysh_config_terminal
, vtysh_config_terminal_cmd
,
1527 "configure terminal",
1528 "Configuration from vty interface\n"
1529 "Configuration terminal\n")
1531 vty
->node
= CONFIG_NODE
;
1535 static int vtysh_exit(struct vty
*vty
)
1537 switch (vty
->node
) {
1543 vty
->node
= ENABLE_NODE
;
1545 case INTERFACE_NODE
:
1547 case LOGICALROUTER_NODE
:
1559 case LDP_L2VPN_NODE
:
1564 vtysh_execute("end");
1565 vtysh_execute("configure terminal");
1566 vty
->node
= CONFIG_NODE
;
1568 case BGP_VPNV4_NODE
:
1569 case BGP_VPNV6_NODE
:
1571 case BGP_IPV4M_NODE
:
1572 case BGP_IPV4L_NODE
:
1574 case BGP_IPV6M_NODE
:
1575 case BGP_IPV6L_NODE
:
1576 case BGP_FLOWSPECV4_NODE
:
1577 case BGP_FLOWSPECV6_NODE
:
1578 case BGP_VRF_POLICY_NODE
:
1580 case BGP_VNC_DEFAULTS_NODE
:
1581 case BGP_VNC_NVE_GROUP_NODE
:
1582 case BGP_VNC_L2_GROUP_NODE
:
1583 vty
->node
= BGP_NODE
;
1585 case BGP_EVPN_VNI_NODE
:
1586 vty
->node
= BGP_EVPN_NODE
;
1590 vty
->node
= LDP_NODE
;
1592 case LDP_IPV4_IFACE_NODE
:
1593 vty
->node
= LDP_IPV4_NODE
;
1595 case LDP_IPV6_IFACE_NODE
:
1596 vty
->node
= LDP_IPV6_NODE
;
1598 case LDP_PSEUDOWIRE_NODE
:
1599 vty
->node
= LDP_L2VPN_NODE
;
1601 case KEYCHAIN_KEY_NODE
:
1602 vty
->node
= KEYCHAIN_NODE
;
1604 case LINK_PARAMS_NODE
:
1605 vty
->node
= INTERFACE_NODE
;
1613 DEFUNSH(VTYSH_REALLYALL
, vtysh_exit_all
, vtysh_exit_all_cmd
, "exit",
1614 "Exit current mode and down to previous mode\n")
1616 return vtysh_exit(vty
);
1619 DEFUNSH(VTYSH_ALL
, vtysh_quit_all
, vtysh_quit_all_cmd
, "quit",
1620 "Exit current mode and down to previous mode\n")
1622 return vtysh_exit_all(self
, vty
, argc
, argv
);
1625 DEFUNSH(VTYSH_BGPD
, exit_address_family
, exit_address_family_cmd
,
1626 "exit-address-family", "Exit from Address Family configuration mode\n")
1628 if (vty
->node
== BGP_IPV4_NODE
|| vty
->node
== BGP_IPV4M_NODE
1629 || vty
->node
== BGP_IPV4L_NODE
|| vty
->node
== BGP_VPNV4_NODE
1630 || vty
->node
== BGP_VPNV6_NODE
|| vty
->node
== BGP_IPV6_NODE
1631 || vty
->node
== BGP_IPV6L_NODE
|| vty
->node
== BGP_IPV6M_NODE
1632 || vty
->node
== BGP_EVPN_NODE
1633 || vty
->node
== BGP_FLOWSPECV4_NODE
1634 || vty
->node
== BGP_FLOWSPECV6_NODE
)
1635 vty
->node
= BGP_NODE
;
1639 DEFUNSH(VTYSH_BGPD
, exit_vni
, exit_vni_cmd
, "exit-vni", "Exit from VNI mode\n")
1641 if (vty
->node
== BGP_EVPN_VNI_NODE
)
1642 vty
->node
= BGP_EVPN_NODE
;
1646 DEFUNSH(VTYSH_BGPD
, exit_vnc_config
, exit_vnc_config_cmd
, "exit-vnc",
1647 "Exit from VNC configuration mode\n")
1649 if (vty
->node
== BGP_VNC_DEFAULTS_NODE
1650 || vty
->node
== BGP_VNC_NVE_GROUP_NODE
1651 || vty
->node
== BGP_VNC_L2_GROUP_NODE
)
1652 vty
->node
= BGP_NODE
;
1656 DEFUNSH(VTYSH_BGPD
, exit_vrf_policy
, exit_vrf_policy_cmd
, "exit-vrf-policy",
1657 "Exit from VRF configuration mode\n")
1659 if (vty
->node
== BGP_VRF_POLICY_NODE
)
1660 vty
->node
= BGP_NODE
;
1664 DEFUNSH(VTYSH_RIPD
, vtysh_exit_ripd
, vtysh_exit_ripd_cmd
, "exit",
1665 "Exit current mode and down to previous mode\n")
1667 return vtysh_exit(vty
);
1670 DEFUNSH(VTYSH_RIPD
, vtysh_quit_ripd
, vtysh_quit_ripd_cmd
, "quit",
1671 "Exit current mode and down to previous mode\n")
1673 return vtysh_exit_ripd(self
, vty
, argc
, argv
);
1676 DEFUNSH(VTYSH_RIPNGD
, vtysh_exit_ripngd
, vtysh_exit_ripngd_cmd
, "exit",
1677 "Exit current mode and down to previous mode\n")
1679 return vtysh_exit(vty
);
1682 DEFUNSH(VTYSH_RIPNGD
, vtysh_quit_ripngd
, vtysh_quit_ripngd_cmd
, "quit",
1683 "Exit current mode and down to previous mode\n")
1685 return vtysh_exit_ripngd(self
, vty
, argc
, argv
);
1688 DEFUNSH(VTYSH_RMAP
, vtysh_exit_rmap
, vtysh_exit_rmap_cmd
, "exit",
1689 "Exit current mode and down to previous mode\n")
1691 return vtysh_exit(vty
);
1694 DEFUNSH(VTYSH_RMAP
, vtysh_quit_rmap
, vtysh_quit_rmap_cmd
, "quit",
1695 "Exit current mode and down to previous mode\n")
1697 return vtysh_exit_rmap(self
, vty
, argc
, argv
);
1700 DEFUNSH(VTYSH_BGPD
, vtysh_exit_bgpd
, vtysh_exit_bgpd_cmd
, "exit",
1701 "Exit current mode and down to previous mode\n")
1703 return vtysh_exit(vty
);
1706 DEFUNSH(VTYSH_BGPD
, vtysh_quit_bgpd
, vtysh_quit_bgpd_cmd
, "quit",
1707 "Exit current mode and down to previous mode\n")
1709 return vtysh_exit_bgpd(self
, vty
, argc
, argv
);
1712 DEFUNSH(VTYSH_OSPFD
, vtysh_exit_ospfd
, vtysh_exit_ospfd_cmd
, "exit",
1713 "Exit current mode and down to previous mode\n")
1715 return vtysh_exit(vty
);
1718 DEFUNSH(VTYSH_OSPFD
, vtysh_quit_ospfd
, vtysh_quit_ospfd_cmd
, "quit",
1719 "Exit current mode and down to previous mode\n")
1721 return vtysh_exit_ospfd(self
, vty
, argc
, argv
);
1724 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_eigrpd
, vtysh_exit_eigrpd_cmd
, "exit",
1725 "Exit current mode and down to previous mode\n")
1727 return vtysh_exit(vty
);
1730 DEFUNSH(VTYSH_EIGRPD
, vtysh_quit_eigrpd
, vtysh_quit_eigrpd_cmd
, "quit",
1731 "Exit current mode and down to previous mode\n")
1733 return vtysh_exit(vty
);
1736 DEFUNSH(VTYSH_EIGRPD
, vtysh_exit_babeld
, vtysh_exit_babeld_cmd
, "exit",
1737 "Exit current mode and down to previous mode\n")
1739 return vtysh_exit(vty
);
1742 DEFUNSH(VTYSH_BABELD
, vtysh_quit_babeld
, vtysh_quit_babeld_cmd
, "quit",
1743 "Exit current mode and down to previous mode\n")
1745 return vtysh_exit(vty
);
1748 DEFUNSH(VTYSH_OSPF6D
, vtysh_exit_ospf6d
, vtysh_exit_ospf6d_cmd
, "exit",
1749 "Exit current mode and down to previous mode\n")
1751 return vtysh_exit(vty
);
1754 DEFUNSH(VTYSH_OSPF6D
, vtysh_quit_ospf6d
, vtysh_quit_ospf6d_cmd
, "quit",
1755 "Exit current mode and down to previous mode\n")
1757 return vtysh_exit_ospf6d(self
, vty
, argc
, argv
);
1760 #if defined(HAVE_LDPD)
1761 DEFUNSH(VTYSH_LDPD
, vtysh_exit_ldpd
, vtysh_exit_ldpd_cmd
, "exit",
1762 "Exit current mode and down to previous mode\n")
1764 return vtysh_exit(vty
);
1767 ALIAS(vtysh_exit_ldpd
, vtysh_quit_ldpd_cmd
, "quit",
1768 "Exit current mode and down to previous mode\n")
1771 DEFUNSH(VTYSH_ISISD
, vtysh_exit_isisd
, vtysh_exit_isisd_cmd
, "exit",
1772 "Exit current mode and down to previous mode\n")
1774 return vtysh_exit(vty
);
1777 DEFUNSH(VTYSH_ISISD
, vtysh_quit_isisd
, vtysh_quit_isisd_cmd
, "quit",
1778 "Exit current mode and down to previous mode\n")
1780 return vtysh_exit_isisd(self
, vty
, argc
, argv
);
1783 DEFUNSH(VTYSH_ALL
, vtysh_exit_line_vty
, vtysh_exit_line_vty_cmd
, "exit",
1784 "Exit current mode and down to previous mode\n")
1786 return vtysh_exit(vty
);
1789 DEFUNSH(VTYSH_ALL
, vtysh_quit_line_vty
, vtysh_quit_line_vty_cmd
, "quit",
1790 "Exit current mode and down to previous mode\n")
1792 return vtysh_exit_line_vty(self
, vty
, argc
, argv
);
1795 DEFUNSH(VTYSH_INTERFACE
, vtysh_interface
, vtysh_interface_cmd
,
1796 "interface IFNAME [vrf NAME]",
1797 "Select an interface to configure\n"
1798 "Interface's name\n" VRF_CMD_HELP_STR
)
1800 vty
->node
= INTERFACE_NODE
;
1804 DEFUNSH(VTYSH_ZEBRA
, vtysh_pseudowire
, vtysh_pseudowire_cmd
,
1805 "pseudowire IFNAME",
1806 "Static pseudowire configuration\n"
1807 "Pseudowire name\n")
1809 vty
->node
= PW_NODE
;
1813 /* TODO Implement "no interface command in isisd. */
1814 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_RIPNGD
| VTYSH_OSPFD
| VTYSH_OSPF6D
1816 vtysh_no_interface_cmd
, "no interface IFNAME", NO_STR
1817 "Delete a pseudo interface's configuration\n"
1818 "Interface's name\n")
1820 DEFSH(VTYSH_ZEBRA
, vtysh_no_interface_vrf_cmd
, "no interface IFNAME vrf NAME",
1822 "Delete a pseudo interface's configuration\n"
1823 "Interface's name\n" VRF_CMD_HELP_STR
)
1825 DEFUNSH(VTYSH_ZEBRA
, vtysh_logicalrouter
, vtysh_logicalrouter_cmd
,
1826 "logical-router (1-65535) ns NAME",
1827 "Enable a logical-router\n"
1828 "Specify the logical-router indentifier\n"
1830 "The file name in " NS_RUN_DIR
", or a full pathname\n")
1832 vty
->node
= LOGICALROUTER_NODE
;
1836 DEFSH(VTYSH_ZEBRA
, vtysh_no_logicalrouter_cmd
,
1837 "no logical-router (1-65535) ns NAME", NO_STR
1838 "Enable a Logical-Router\n"
1839 "Specify the Logical-Router identifier\n"
1841 "The file name in " NS_RUN_DIR
", or a full pathname\n")
1843 DEFUNSH(VTYSH_VRF
, vtysh_vrf
, vtysh_vrf_cmd
, "vrf NAME",
1844 "Select a VRF to configure\n"
1847 vty
->node
= VRF_NODE
;
1851 DEFSH(VTYSH_ZEBRA
, vtysh_no_vrf_cmd
, "no vrf NAME", NO_STR
1852 "Delete a pseudo vrf's configuration\n"
1855 DEFUNSH(VTYSH_NS
, vtysh_exit_logicalrouter
,
1856 vtysh_exit_logicalrouter_cmd
, "exit",
1857 "Exit current mode and down to previous mode\n")
1859 return vtysh_exit(vty
);
1862 DEFUNSH(VTYSH_NS
, vtysh_quit_logicalrouter
,
1863 vtysh_quit_logicalrouter_cmd
, "quit",
1864 "Exit current mode and down to previous mode\n")
1866 return vtysh_exit_logicalrouter(self
, vty
, argc
, argv
);
1869 DEFUNSH(VTYSH_VRF
, vtysh_exit_vrf
, vtysh_exit_vrf_cmd
, "exit",
1870 "Exit current mode and down to previous mode\n")
1872 return vtysh_exit(vty
);
1875 DEFUNSH(VTYSH_VRF
, vtysh_quit_vrf
, vtysh_quit_vrf_cmd
, "quit",
1876 "Exit current mode and down to previous mode\n")
1878 return vtysh_exit_vrf(self
, vty
, argc
, argv
);
1881 /* TODO Implement interface description commands in ripngd, ospf6d
1883 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_OSPFD
| VTYSH_EIGRPD
,
1884 vtysh_interface_desc_cmd
, "description LINE...",
1885 "Interface specific description\n"
1886 "Characters describing this interface\n")
1888 DEFSH(VTYSH_ZEBRA
| VTYSH_RIPD
| VTYSH_OSPFD
| VTYSH_EIGRPD
,
1889 vtysh_no_interface_desc_cmd
, "no description",
1890 NO_STR
"Interface specific description\n")
1892 DEFUNSH(VTYSH_INTERFACE
, vtysh_exit_interface
, vtysh_exit_interface_cmd
, "exit",
1893 "Exit current mode and down to previous mode\n")
1895 return vtysh_exit(vty
);
1898 DEFUNSH(VTYSH_INTERFACE
, vtysh_quit_interface
, vtysh_quit_interface_cmd
, "quit",
1899 "Exit current mode and down to previous mode\n")
1901 return vtysh_exit_interface(self
, vty
, argc
, argv
);
1904 DEFUN (vtysh_show_thread
,
1905 vtysh_show_thread_cmd
,
1906 "show thread cpu [FILTER]",
1908 "Thread information\n"
1909 "Thread CPU usage\n"
1910 "Display filter (rwtexb)\n")
1914 int ret
= CMD_SUCCESS
;
1917 const char *filter
=
1918 argv_find(argv
, argc
, "FILTER", &idx
) ? argv
[idx
]->arg
: "";
1920 snprintf(line
, sizeof(line
), "do show thread cpu %s\n", filter
);
1921 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1922 if (vtysh_client
[i
].fd
>= 0) {
1923 fprintf(stdout
, "Thread statistics for %s:\n",
1924 vtysh_client
[i
].name
);
1925 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
1927 fprintf(stdout
, "\n");
1932 DEFUN (vtysh_show_work_queues
,
1933 vtysh_show_work_queues_cmd
,
1936 "Work Queue information\n")
1939 int ret
= CMD_SUCCESS
;
1940 char line
[] = "do show work-queues\n";
1942 for (i
= 0; i
< array_size(vtysh_client
); i
++)
1943 if (vtysh_client
[i
].fd
>= 0) {
1944 fprintf(stdout
, "Work queue statistics for %s:\n",
1945 vtysh_client
[i
].name
);
1946 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
1948 fprintf(stdout
, "\n");
1954 DEFUN (vtysh_show_work_queues_daemon
,
1955 vtysh_show_work_queues_daemon_cmd
,
1956 "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd>",
1958 "Work Queue information\n"
1959 "For the zebra daemon\n"
1960 "For the rip daemon\n"
1961 "For the ripng daemon\n"
1962 "For the ospf daemon\n"
1963 "For the ospfv6 daemon\n"
1964 "For the bgp daemon\n"
1965 "For the isis daemon\n")
1967 int idx_protocol
= 2;
1969 int ret
= CMD_SUCCESS
;
1971 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
1972 if (strmatch(vtysh_client
[i
].name
, argv
[idx_protocol
]->text
))
1976 ret
= vtysh_client_execute(&vtysh_client
[i
], "show work-queues\n",
1982 DEFUNSH(VTYSH_ZEBRA
, vtysh_link_params
, vtysh_link_params_cmd
, "link-params",
1985 vty
->node
= LINK_PARAMS_NODE
;
1989 DEFUNSH(VTYSH_ZEBRA
, exit_link_params
, exit_link_params_cmd
, "exit-link-params",
1990 "Exit from Link Params configuration node\n")
1992 if (vty
->node
== LINK_PARAMS_NODE
)
1993 vty
->node
= INTERFACE_NODE
;
1997 static int show_per_daemon(const char *line
, const char *headline
)
2000 int ret
= CMD_SUCCESS
;
2002 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2003 if (vtysh_client
[i
].fd
>= 0) {
2004 fprintf(outputfile
, headline
, vtysh_client
[i
].name
);
2005 ret
= vtysh_client_execute(&vtysh_client
[i
], line
,
2007 fprintf(stdout
, "\n");
2013 DEFUNSH_HIDDEN (0x00,
2015 vtysh_debug_all_cmd
,
2019 "Toggle all debugs on or off\n")
2024 DEFUN (vtysh_show_debugging
,
2025 vtysh_show_debugging_cmd
,
2030 return show_per_daemon("do show debugging\n", "");
2033 DEFUN (vtysh_show_debugging_hashtable
,
2034 vtysh_show_debugging_hashtable_cmd
,
2035 "show debugging hashtable [statistics]",
2038 "Statistics about hash tables\n"
2039 "Statistics about hash tables\n")
2041 fprintf(stdout
, "\n");
2043 "Load factor (LF) - average number of elements across all buckets\n");
2045 "Full load factor (FLF) - average number of elements across full buckets\n\n");
2047 "Standard deviation (SD) is calculated for both the LF and FLF\n");
2049 "and indicates the typical deviation of bucket chain length\n");
2050 fprintf(stdout
, "from the value in the corresponding load factor.\n\n");
2052 return show_per_daemon("do show debugging hashtable\n",
2053 "Hashtable statistics for %s:\n");
2057 DEFUN (vtysh_show_memory
,
2058 vtysh_show_memory_cmd
,
2061 "Memory statistics\n")
2063 return show_per_daemon("show memory\n", "Memory statistics for %s:\n");
2066 DEFUN (vtysh_show_modules
,
2067 vtysh_show_modules_cmd
,
2072 return show_per_daemon("show modules\n",
2073 "Module information for %s:\n");
2076 /* Logging commands. */
2077 DEFUN (vtysh_show_logging
,
2078 vtysh_show_logging_cmd
,
2081 "Show current logging configuration\n")
2083 return show_per_daemon("do show logging\n",
2084 "Logging configuration for %s:\n");
2087 DEFUNSH(VTYSH_ALL
, vtysh_log_stdout
, vtysh_log_stdout_cmd
, "log stdout",
2089 "Set stdout logging level\n")
2094 DEFUNSH(VTYSH_ALL
, vtysh_log_stdout_level
, vtysh_log_stdout_level_cmd
,
2095 "log stdout <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2097 "Set stdout logging level\n" LOG_LEVEL_DESC
)
2102 DEFUNSH(VTYSH_ALL
, no_vtysh_log_stdout
, no_vtysh_log_stdout_cmd
,
2103 "no log stdout [LEVEL]", NO_STR
2105 "Cancel logging to stdout\n"
2111 DEFUNSH(VTYSH_ALL
, vtysh_log_file
, vtysh_log_file_cmd
, "log file FILENAME",
2114 "Logging filename\n")
2119 DEFUNSH(VTYSH_ALL
, vtysh_log_file_level
, vtysh_log_file_level_cmd
,
2120 "log file FILENAME <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2123 "Logging filename\n" LOG_LEVEL_DESC
)
2128 DEFUNSH(VTYSH_ALL
, no_vtysh_log_file
, no_vtysh_log_file_cmd
,
2129 "no log file [FILENAME [LEVEL]]", NO_STR
2131 "Cancel logging to file\n"
2132 "Logging file name\n"
2138 DEFUNSH(VTYSH_ALL
, vtysh_log_monitor
, vtysh_log_monitor_cmd
,
2139 "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
2141 "Set terminal line (monitor) logging level\n" LOG_LEVEL_DESC
)
2146 DEFUNSH(VTYSH_ALL
, no_vtysh_log_monitor
, no_vtysh_log_monitor_cmd
,
2147 "no log monitor [LEVEL]", NO_STR
2149 "Disable terminal line (monitor) logging\n"
2155 DEFUNSH(VTYSH_ALL
, vtysh_log_syslog
, vtysh_log_syslog_cmd
,
2156 "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
2158 "Set syslog logging level\n" LOG_LEVEL_DESC
)
2163 DEFUNSH(VTYSH_ALL
, no_vtysh_log_syslog
, no_vtysh_log_syslog_cmd
,
2164 "no log syslog [LEVEL]", NO_STR
2166 "Cancel logging to syslog\n"
2172 DEFUNSH(VTYSH_ALL
, vtysh_log_facility
, vtysh_log_facility_cmd
,
2173 "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>",
2175 "Facility parameter for syslog messages\n" LOG_FACILITY_DESC
)
2180 DEFUNSH(VTYSH_ALL
, no_vtysh_log_facility
, no_vtysh_log_facility_cmd
,
2181 "no log facility [FACILITY]", NO_STR
2183 "Reset syslog facility to default (daemon)\n"
2184 "Syslog facility\n")
2190 VTYSH_ALL
, vtysh_log_trap
, vtysh_log_trap_cmd
,
2191 "log trap <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
2193 "(Deprecated) Set logging level and default for all destinations\n" LOG_LEVEL_DESC
)
2198 DEFUNSH_DEPRECATED(VTYSH_ALL
, no_vtysh_log_trap
, no_vtysh_log_trap_cmd
,
2199 "no log trap [LEVEL]", NO_STR
2201 "Permit all logging information\n"
2207 DEFUNSH(VTYSH_ALL
, vtysh_log_record_priority
, vtysh_log_record_priority_cmd
,
2208 "log record-priority",
2210 "Log the priority of the message within the message\n")
2215 DEFUNSH(VTYSH_ALL
, no_vtysh_log_record_priority
,
2216 no_vtysh_log_record_priority_cmd
, "no log record-priority", NO_STR
2218 "Do not log the priority of the message within the message\n")
2223 DEFUNSH(VTYSH_ALL
, vtysh_log_timestamp_precision
,
2224 vtysh_log_timestamp_precision_cmd
, "log timestamp precision (0-6)",
2226 "Timestamp configuration\n"
2227 "Set the timestamp precision\n"
2228 "Number of subsecond digits\n")
2233 DEFUNSH(VTYSH_ALL
, no_vtysh_log_timestamp_precision
,
2234 no_vtysh_log_timestamp_precision_cmd
, "no log timestamp precision",
2237 "Timestamp configuration\n"
2238 "Reset the timestamp precision to the default value of 0\n")
2243 DEFUNSH(VTYSH_ALL
, vtysh_service_password_encrypt
,
2244 vtysh_service_password_encrypt_cmd
, "service password-encryption",
2245 "Set up miscellaneous service\n"
2246 "Enable encrypted passwords\n")
2251 DEFUNSH(VTYSH_ALL
, no_vtysh_service_password_encrypt
,
2252 no_vtysh_service_password_encrypt_cmd
, "no service password-encryption",
2254 "Set up miscellaneous service\n"
2255 "Enable encrypted passwords\n")
2260 DEFUNSH(VTYSH_ALL
, vtysh_config_password
, vtysh_password_cmd
,
2261 "password [(8-8)] LINE",
2262 "Assign the terminal connection password\n"
2263 "Specifies a HIDDEN password will follow\n"
2264 "The password string\n")
2269 DEFUNSH(VTYSH_ALL
, vtysh_config_enable_password
, vtysh_enable_password_cmd
,
2270 "enable password [(8-8)] LINE",
2271 "Modify enable password parameters\n"
2272 "Assign the privileged level password\n"
2273 "Specifies a HIDDEN password will follow\n"
2274 "The 'enable' password string\n")
2279 DEFUNSH(VTYSH_ALL
, no_vtysh_config_enable_password
,
2280 no_vtysh_enable_password_cmd
, "no enable password", NO_STR
2281 "Modify enable password parameters\n"
2282 "Assign the privileged level password\n")
2287 DEFUN (vtysh_write_terminal
,
2288 vtysh_write_terminal_cmd
,
2289 "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
2290 "Write running configuration to memory, network, or terminal\n"
2291 "Write to terminal\n"
2292 "For the zebra daemon\n"
2293 "For the rip daemon\n"
2294 "For the ripng daemon\n"
2295 "For the ospf daemon\n"
2296 "For the ospfv6 daemon\n"
2297 "For the ldpd daemon\n"
2298 "For the bgp daemon\n"
2299 "For the isis daemon\n"
2300 "For the pim daemon\n")
2303 char line
[] = "do write terminal\n";
2304 FILE *fp
= outputfile
;
2306 if (fp
== stdout
&& vtysh_pager_name
) {
2307 fp
= popen(vtysh_pager_name
, "w");
2314 fprintf(outputfile
, "Building configuration...\n");
2315 fprintf(outputfile
, "\nCurrent configuration:\n");
2316 fprintf(outputfile
, "!\n");
2318 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2320 || (strmatch(vtysh_client
[i
].name
, argv
[2]->text
)))
2321 vtysh_client_config(&vtysh_client
[i
], line
);
2323 /* Integrate vtysh specific configuration. */
2324 vtysh_config_write();
2326 vtysh_config_dump(fp
);
2328 if (vtysh_pager_name
&& fp
&& fp
!= outputfile
) {
2330 if (pclose(fp
) == -1) {
2337 fprintf(outputfile
, "end\n");
2341 DEFUN (vtysh_show_running_config
,
2342 vtysh_show_running_config_cmd
,
2343 "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
2345 "Current operating configuration\n"
2346 "For the zebra daemon\n"
2347 "For the rip daemon\n"
2348 "For the ripng daemon\n"
2349 "For the ospf daemon\n"
2350 "For the ospfv6 daemon\n"
2351 "For the ldp daemon\n"
2352 "For the bgp daemon\n"
2353 "For the isis daemon\n"
2354 "For the pim daemon\n")
2356 return vtysh_write_terminal(self
, vty
, argc
, argv
);
2359 DEFUN (vtysh_integrated_config
,
2360 vtysh_integrated_config_cmd
,
2361 "service integrated-vtysh-config",
2362 "Set up miscellaneous service\n"
2363 "Write configuration into integrated file\n")
2365 vtysh_write_integrated
= WRITE_INTEGRATED_YES
;
2369 DEFUN (no_vtysh_integrated_config
,
2370 no_vtysh_integrated_config_cmd
,
2371 "no service integrated-vtysh-config",
2373 "Set up miscellaneous service\n"
2374 "Write configuration into integrated file\n")
2376 vtysh_write_integrated
= WRITE_INTEGRATED_NO
;
2380 static void backup_config_file(const char *fbackup
)
2382 char *integrate_sav
= NULL
;
2384 integrate_sav
= malloc(strlen(fbackup
) + strlen(CONF_BACKUP_EXT
) + 1);
2385 strcpy(integrate_sav
, fbackup
);
2386 strcat(integrate_sav
, CONF_BACKUP_EXT
);
2388 /* Move current configuration file to backup config file. */
2389 unlink(integrate_sav
);
2390 rename(fbackup
, integrate_sav
);
2391 free(integrate_sav
);
2394 int vtysh_write_config_integrated(void)
2397 char line
[] = "do write terminal\n";
2400 struct passwd
*pwentry
;
2401 struct group
*grentry
;
2407 fprintf(stdout
, "Building Configuration...\n");
2409 backup_config_file(frr_config
);
2410 fp
= fopen(frr_config
, "w");
2413 "%% Error: failed to open configuration file %s: %s\n",
2414 frr_config
, safe_strerror(errno
));
2415 return CMD_WARNING_CONFIG_FAILED
;
2419 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2420 vtysh_client_config(&vtysh_client
[i
], line
);
2422 vtysh_config_write();
2423 vtysh_config_dump(fp
);
2425 if (fchmod(fd
, CONFIGFILE_MASK
) != 0) {
2426 printf("%% Warning: can't chmod configuration file %s: %s\n",
2427 frr_config
, safe_strerror(errno
));
2432 pwentry
= getpwnam(FRR_USER
);
2434 uid
= pwentry
->pw_uid
;
2436 printf("%% Warning: could not look up user \"%s\"\n", FRR_USER
);
2441 grentry
= getgrnam(FRR_GROUP
);
2443 gid
= grentry
->gr_gid
;
2445 printf("%% Warning: could not look up group \"%s\"\n",
2451 if (!fstat(fd
, &st
)) {
2452 if (st
.st_uid
== uid
)
2454 if (st
.st_gid
== gid
)
2456 if ((uid
!= (uid_t
)-1 || gid
!= (gid_t
)-1)
2457 && fchown(fd
, uid
, gid
)) {
2458 printf("%% Warning: can't chown configuration file %s: %s\n",
2459 frr_config
, safe_strerror(errno
));
2463 printf("%% Warning: stat() failed on %s: %s\n", frr_config
,
2464 safe_strerror(errno
));
2470 printf("Integrated configuration saved to %s\n", frr_config
);
2478 static bool want_config_integrated(void)
2482 switch (vtysh_write_integrated
) {
2483 case WRITE_INTEGRATED_UNSPECIFIED
:
2484 if (stat(frr_config
, &s
) && errno
== ENOENT
)
2487 case WRITE_INTEGRATED_NO
:
2489 case WRITE_INTEGRATED_YES
:
2495 DEFUN (vtysh_write_memory
,
2496 vtysh_write_memory_cmd
,
2497 "write [<memory|file>]",
2498 "Write running configuration to memory, network, or terminal\n"
2499 "Write configuration to the file (same as write file)\n"
2500 "Write configuration to the file (same as write memory)\n")
2502 int ret
= CMD_SUCCESS
;
2503 char line
[] = "do write memory\n";
2507 "Note: this version of vtysh never writes vtysh.conf\n");
2509 /* If integrated frr.conf explicitely set. */
2510 if (want_config_integrated()) {
2511 ret
= CMD_WARNING_CONFIG_FAILED
;
2512 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2513 if (vtysh_client
[i
].flag
== VTYSH_WATCHFRR
)
2515 if (i
< array_size(vtysh_client
) && vtysh_client
[i
].fd
!= -1)
2516 ret
= vtysh_client_execute(&vtysh_client
[i
],
2517 "do write integrated",
2521 * If watchfrr returns CMD_WARNING_CONFIG_FAILED this means
2522 * that it could not write the config, but additionally
2523 * indicates that we should not try either
2525 if (ret
!= CMD_SUCCESS
&& ret
!= CMD_WARNING_CONFIG_FAILED
) {
2526 printf("\nWarning: attempting direct configuration write without "
2527 "watchfrr.\nFile permissions and ownership may be "
2528 "incorrect, or write may fail.\n\n");
2529 ret
= vtysh_write_config_integrated();
2534 fprintf(outputfile
, "Building Configuration...\n");
2536 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2537 ret
= vtysh_client_execute(&vtysh_client
[i
], line
, outputfile
);
2542 DEFUN (vtysh_copy_running_config
,
2543 vtysh_copy_running_config_cmd
,
2544 "copy running-config startup-config",
2545 "Copy from one file to another\n"
2546 "Copy from current system configuration\n"
2547 "Copy to startup configuration\n")
2549 return vtysh_write_memory(self
, vty
, argc
, argv
);
2552 DEFUN (vtysh_terminal_length
,
2553 vtysh_terminal_length_cmd
,
2554 "terminal length (0-512)",
2555 "Set terminal line parameters\n"
2556 "Set number of lines on a screen\n"
2557 "Number of lines on screen (0 for no pausing)\n")
2561 char *endptr
= NULL
;
2562 char default_pager
[10];
2564 lines
= strtol(argv
[idx_number
]->arg
, &endptr
, 10);
2565 if (lines
< 0 || lines
> 512 || *endptr
!= '\0') {
2566 fprintf(outputfile
, "length is malformed\n");
2570 if (vtysh_pager_name
) {
2571 free(vtysh_pager_name
);
2572 vtysh_pager_name
= NULL
;
2576 snprintf(default_pager
, 10, "more -%i", lines
);
2577 vtysh_pager_name
= strdup(default_pager
);
2583 DEFUN (vtysh_terminal_no_length
,
2584 vtysh_terminal_no_length_cmd
,
2585 "terminal no length",
2586 "Set terminal line parameters\n"
2588 "Set number of lines on a screen\n")
2590 if (vtysh_pager_name
) {
2591 free(vtysh_pager_name
);
2592 vtysh_pager_name
= NULL
;
2599 DEFUN (vtysh_show_daemons
,
2600 vtysh_show_daemons_cmd
,
2603 "Show list of running daemons\n")
2607 for (i
= 0; i
< array_size(vtysh_client
); i
++)
2608 if (vtysh_client
[i
].fd
>= 0)
2609 fprintf(outputfile
, " %s", vtysh_client
[i
].name
);
2610 fprintf(outputfile
, "\n");
2615 /* Execute command in child process. */
2616 static void execute_command(const char *command
, int argc
, const char *arg1
,
2626 /* Failure of fork(). */
2627 fprintf(stderr
, "Can't fork: %s\n", safe_strerror(errno
));
2629 } else if (pid
== 0) {
2630 /* This is child process. */
2633 execlp(command
, command
, (const char *)NULL
);
2636 execlp(command
, command
, arg1
, (const char *)NULL
);
2639 execlp(command
, command
, arg1
, arg2
,
2640 (const char *)NULL
);
2644 /* When execlp suceed, this part is not executed. */
2645 fprintf(stderr
, "Can't execute %s: %s\n", command
,
2646 safe_strerror(errno
));
2649 /* This is parent. */
2651 wait4(pid
, &status
, 0, NULL
);
2659 "Send echo messages\n"
2660 "Ping destination address or hostname\n")
2664 argv_find(argv
, argc
, "WORD", &idx
);
2665 execute_command("ping", 1, argv
[idx
]->arg
, NULL
);
2669 ALIAS(vtysh_ping
, vtysh_ping_ip_cmd
, "ping ip WORD",
2670 "Send echo messages\n"
2672 "Ping destination address or hostname\n")
2674 DEFUN (vtysh_traceroute
,
2675 vtysh_traceroute_cmd
,
2677 "Trace route to destination\n"
2678 "Trace route to destination address or hostname\n")
2682 argv_find(argv
, argc
, "WORD", &idx
);
2683 execute_command("traceroute", 1, argv
[idx
]->arg
, NULL
);
2687 ALIAS(vtysh_traceroute
, vtysh_traceroute_ip_cmd
, "traceroute ip WORD",
2688 "Trace route to destination\n"
2690 "Trace route to destination address or hostname\n")
2692 DEFUN (vtysh_mtrace
,
2695 "Multicast trace route to multicast source\n"
2696 "Multicast trace route to multicast source address\n")
2700 argv_find(argv
, argc
, "WORD", &idx
);
2701 execute_command("mtracebis", 1, argv
[idx
]->arg
, NULL
);
2708 "Send echo messages\n"
2710 "Ping destination address or hostname\n")
2712 execute_command("ping6", 1, argv
[2]->arg
, NULL
);
2716 DEFUN (vtysh_traceroute6
,
2717 vtysh_traceroute6_cmd
,
2718 "traceroute ipv6 WORD",
2719 "Trace route to destination\n"
2721 "Trace route to destination address or hostname\n")
2723 execute_command("traceroute6", 1, argv
[2]->arg
, NULL
);
2727 #if defined(HAVE_SHELL_ACCESS)
2728 DEFUN (vtysh_telnet
,
2731 "Open a telnet connection\n"
2732 "IP address or hostname of a remote system\n")
2734 execute_command("telnet", 1, argv
[1]->arg
, NULL
);
2738 DEFUN (vtysh_telnet_port
,
2739 vtysh_telnet_port_cmd
,
2741 "Open a telnet connection\n"
2742 "IP address or hostname of a remote system\n"
2743 "TCP Port number\n")
2745 execute_command("telnet", 2, argv
[1]->arg
, argv
[2]->arg
);
2752 "Open an ssh connection\n"
2755 execute_command("ssh", 1, argv
[1]->arg
, NULL
);
2759 DEFUN (vtysh_start_shell
,
2760 vtysh_start_shell_cmd
,
2762 "Start UNIX shell\n")
2764 execute_command("sh", 0, NULL
, NULL
);
2768 DEFUN (vtysh_start_bash
,
2769 vtysh_start_bash_cmd
,
2771 "Start UNIX shell\n"
2774 execute_command("bash", 0, NULL
, NULL
);
2778 DEFUN (vtysh_start_zsh
,
2779 vtysh_start_zsh_cmd
,
2781 "Start UNIX shell\n"
2784 execute_command("zsh", 0, NULL
, NULL
);
2791 "list [permutations]",
2792 "Print command list\n"
2793 "Print all possible command permutations\n")
2795 return cmd_list_cmds(vty
, argc
== 2);
2798 DEFUN (vtysh_output_file
,
2799 vtysh_output_file_cmd
,
2801 "Direct vtysh output to file\n"
2802 "Direct vtysh output to file\n"
2803 "Path to dump output to\n")
2805 const char *path
= argv
[argc
- 1]->arg
;
2806 outputfile
= fopen(path
, "a");
2808 fprintf(stdout
, "Failed to open file '%s': %s\n", path
,
2809 safe_strerror(errno
));
2810 outputfile
= stdout
;
2815 DEFUN (no_vtysh_output_file
,
2816 no_vtysh_output_file_cmd
,
2817 "no output file [FILE]",
2819 "Direct vtysh output to file\n"
2820 "Direct vtysh output to file\n"
2821 "Path to dump output to\n")
2823 if (outputfile
!= stdout
) {
2825 outputfile
= stdout
;
2833 "Find CLI command containing text\n"
2834 "Text to search for\n")
2836 char *text
= argv_concat(argv
, argc
, 1);
2837 const struct cmd_node
*node
;
2838 const struct cmd_element
*cli
;
2841 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
2842 node
= vector_slot(cmdvec
, i
);
2845 clis
= node
->cmd_vector
;
2846 for (unsigned int j
= 0; j
< vector_active(clis
); j
++) {
2847 cli
= vector_slot(clis
, j
);
2848 if (strcasestr(cli
->string
, text
))
2849 fprintf(stdout
, " (%s) %s\n",
2850 node_names
[node
->node
], cli
->string
);
2854 XFREE(MTYPE_TMP
, text
);
2859 static void vtysh_install_default(enum node_type node
)
2861 install_element(node
, &config_list_cmd
);
2862 install_element(node
, &find_cmd
);
2863 install_element(node
, &vtysh_output_file_cmd
);
2864 install_element(node
, &no_vtysh_output_file_cmd
);
2867 /* Making connection to protocol daemon. */
2868 static int vtysh_connect(struct vtysh_client
*vclient
)
2872 struct sockaddr_un addr
;
2876 if (!vclient
->path
[0])
2877 snprintf(vclient
->path
, sizeof(vclient
->path
), "%s/%s.vty",
2878 vtydir
, vclient
->name
);
2879 path
= vclient
->path
;
2881 /* Stat socket to see if we have permission to access it. */
2882 ret
= stat(path
, &s_stat
);
2883 if (ret
< 0 && errno
!= ENOENT
) {
2884 fprintf(stderr
, "vtysh_connect(%s): stat = %s\n", path
,
2885 safe_strerror(errno
));
2890 if (!S_ISSOCK(s_stat
.st_mode
)) {
2891 fprintf(stderr
, "vtysh_connect(%s): Not a socket\n",
2897 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
2900 fprintf(stderr
, "vtysh_connect(%s): socket = %s\n", path
,
2901 safe_strerror(errno
));
2906 memset(&addr
, 0, sizeof(struct sockaddr_un
));
2907 addr
.sun_family
= AF_UNIX
;
2908 strlcpy(addr
.sun_path
, path
, sizeof(addr
.sun_path
));
2909 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
2910 len
= addr
.sun_len
= SUN_LEN(&addr
);
2912 len
= sizeof(addr
.sun_family
) + strlen(addr
.sun_path
);
2913 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
2915 ret
= connect(sock
, (struct sockaddr
*)&addr
, len
);
2918 fprintf(stderr
, "vtysh_connect(%s): connect = %s\n", path
,
2919 safe_strerror(errno
));
2929 /* Return true if str ends with suffix, else return false */
2930 static int ends_with(const char *str
, const char *suffix
)
2932 if (!str
|| !suffix
)
2934 size_t lenstr
= strlen(str
);
2935 size_t lensuffix
= strlen(suffix
);
2936 if (lensuffix
> lenstr
)
2938 return strncmp(str
+ lenstr
- lensuffix
, suffix
, lensuffix
) == 0;
2941 static void vtysh_client_sorted_insert(struct vtysh_client
*head_client
,
2942 struct vtysh_client
*client
)
2944 struct vtysh_client
*prev_node
, *current_node
;
2946 prev_node
= head_client
;
2947 current_node
= head_client
->next
;
2948 while (current_node
) {
2949 if (strcmp(current_node
->path
, client
->path
) > 0)
2952 prev_node
= current_node
;
2953 current_node
= current_node
->next
;
2955 client
->next
= current_node
;
2956 prev_node
->next
= client
;
2959 #define MAXIMUM_INSTANCES 10
2961 static void vtysh_update_all_insances(struct vtysh_client
*head_client
)
2963 struct vtysh_client
*client
;
2965 struct dirent
*file
;
2968 if (head_client
->flag
!= VTYSH_OSPFD
)
2971 /* ls vty_sock_dir and look for all files ending in .vty */
2972 dir
= opendir(vtydir
);
2974 while ((file
= readdir(dir
)) != NULL
) {
2975 if (begins_with(file
->d_name
, "ospfd-")
2976 && ends_with(file
->d_name
, ".vty")) {
2977 if (n
== MAXIMUM_INSTANCES
) {
2979 "Parsing %s, client limit(%d) reached!\n",
2983 client
= (struct vtysh_client
*)malloc(
2984 sizeof(struct vtysh_client
));
2986 client
->name
= "ospfd";
2987 client
->flag
= VTYSH_OSPFD
;
2988 snprintf(client
->path
, sizeof(client
->path
),
2989 "%s/%s", vtydir
, file
->d_name
);
2990 client
->next
= NULL
;
2991 vtysh_client_sorted_insert(head_client
, client
);
2999 static int vtysh_connect_all_instances(struct vtysh_client
*head_client
)
3001 struct vtysh_client
*client
;
3004 vtysh_update_all_insances(head_client
);
3006 client
= head_client
->next
;
3008 if (vtysh_connect(client
) == 0)
3010 client
= client
->next
;
3016 int vtysh_connect_all(const char *daemon_name
)
3022 for (i
= 0; i
< array_size(vtysh_client
); i
++) {
3024 || !strcmp(daemon_name
, vtysh_client
[i
].name
)) {
3026 if (vtysh_connect(&vtysh_client
[i
]) == 0)
3029 rc
+= vtysh_connect_all_instances(&vtysh_client
[i
]);
3033 fprintf(stderr
, "Error: no daemons match name %s!\n",
3038 /* To disable readline's filename completion. */
3039 static char *vtysh_completion_entry_function(const char *ignore
,
3045 void vtysh_readline_init(void)
3047 /* readline related settings. */
3049 rl_bind_key('?', (rl_command_func_t
*)vtysh_rl_describe
);
3050 rl_completion_entry_function
= vtysh_completion_entry_function
;
3051 rl_attempted_completion_function
=
3052 (rl_completion_func_t
*)new_completion
;
3055 char *vtysh_prompt(void)
3057 static char buf
[100];
3059 snprintf(buf
, sizeof buf
, cmd_prompt(vty
->node
), cmd_hostname_get());
3063 static void vtysh_ac_line(void *arg
, const char *line
)
3067 for (i
= 0; i
< vector_active(comps
); i
++)
3068 if (!strcmp(line
, (char *)vector_slot(comps
, i
)))
3070 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, line
));
3073 static void vtysh_autocomplete(vector comps
, struct cmd_token
*token
)
3078 snprintf(accmd
, sizeof(accmd
), "autocomplete %d %s %s", token
->type
,
3079 token
->text
, token
->varname
? token
->varname
: "-");
3081 for (i
= 0; i
< array_size(vtysh_client
); i
++)
3082 vtysh_client_run_all(&vtysh_client
[i
], accmd
, 1, NULL
,
3083 vtysh_ac_line
, comps
);
3086 static const struct cmd_variable_handler vtysh_var_handler
[] = {
3090 .completions
= vtysh_autocomplete
},
3091 {.completions
= NULL
}};
3095 if (outputfile
!= stdout
)
3099 void vtysh_init_vty(void)
3101 /* Make vty structure. */
3103 vty
->type
= VTY_SHELL
;
3104 vty
->node
= VIEW_NODE
;
3106 /* set default output */
3107 outputfile
= stdout
;
3109 /* Initialize commands. */
3111 cmd_variable_handler_register(vtysh_var_handler
);
3113 /* Install nodes. */
3114 install_node(&bgp_node
, NULL
);
3115 install_node(&rip_node
, NULL
);
3116 install_node(&interface_node
, NULL
);
3117 install_node(&pw_node
, NULL
);
3118 install_node(&link_params_node
, NULL
);
3119 install_node(&logicalrouter_node
, NULL
);
3120 install_node(&vrf_node
, NULL
);
3121 install_node(&rmap_node
, NULL
);
3122 install_node(&zebra_node
, NULL
);
3123 install_node(&bgp_vpnv4_node
, NULL
);
3124 install_node(&bgp_vpnv6_node
, NULL
);
3125 install_node(&bgp_flowspecv4_node
, NULL
);
3126 install_node(&bgp_flowspecv6_node
, NULL
);
3127 install_node(&bgp_ipv4_node
, NULL
);
3128 install_node(&bgp_ipv4m_node
, NULL
);
3129 install_node(&bgp_ipv4l_node
, NULL
);
3130 install_node(&bgp_ipv6_node
, NULL
);
3131 install_node(&bgp_ipv6m_node
, NULL
);
3132 install_node(&bgp_ipv6l_node
, NULL
);
3133 install_node(&bgp_vrf_policy_node
, NULL
);
3134 install_node(&bgp_evpn_node
, NULL
);
3135 install_node(&bgp_evpn_vni_node
, NULL
);
3136 install_node(&bgp_vnc_defaults_node
, NULL
);
3137 install_node(&bgp_vnc_nve_group_node
, NULL
);
3138 install_node(&bgp_vnc_l2_group_node
, NULL
);
3139 install_node(&ospf_node
, NULL
);
3140 install_node(&eigrp_node
, NULL
);
3141 install_node(&babel_node
, NULL
);
3142 install_node(&ripng_node
, NULL
);
3143 install_node(&ospf6_node
, NULL
);
3144 install_node(&ldp_node
, NULL
);
3145 install_node(&ldp_ipv4_node
, NULL
);
3146 install_node(&ldp_ipv6_node
, NULL
);
3147 install_node(&ldp_ipv4_iface_node
, NULL
);
3148 install_node(&ldp_ipv6_iface_node
, NULL
);
3149 install_node(&ldp_l2vpn_node
, NULL
);
3150 install_node(&ldp_pseudowire_node
, NULL
);
3151 install_node(&keychain_node
, NULL
);
3152 install_node(&keychain_key_node
, NULL
);
3153 install_node(&isis_node
, NULL
);
3154 install_node(&vty_node
, NULL
);
3155 #if defined(HAVE_RPKI)
3156 install_node(&rpki_node
, NULL
);
3159 struct cmd_node
*node
;
3160 for (unsigned int i
= 0; i
< vector_active(cmdvec
); i
++) {
3161 node
= vector_slot(cmdvec
, i
);
3162 if (!node
|| node
->node
== VIEW_NODE
)
3164 vtysh_install_default(node
->node
);
3167 install_element(VIEW_NODE
, &vtysh_enable_cmd
);
3168 install_element(ENABLE_NODE
, &vtysh_config_terminal_cmd
);
3169 install_element(ENABLE_NODE
, &vtysh_disable_cmd
);
3171 /* "exit" command. */
3172 install_element(VIEW_NODE
, &vtysh_exit_all_cmd
);
3173 install_element(CONFIG_NODE
, &vtysh_exit_all_cmd
);
3174 install_element(VIEW_NODE
, &vtysh_quit_all_cmd
);
3175 install_element(CONFIG_NODE
, &vtysh_quit_all_cmd
);
3176 install_element(RIP_NODE
, &vtysh_exit_ripd_cmd
);
3177 install_element(RIP_NODE
, &vtysh_quit_ripd_cmd
);
3178 install_element(RIPNG_NODE
, &vtysh_exit_ripngd_cmd
);
3179 install_element(RIPNG_NODE
, &vtysh_quit_ripngd_cmd
);
3180 install_element(OSPF_NODE
, &vtysh_exit_ospfd_cmd
);
3181 install_element(OSPF_NODE
, &vtysh_quit_ospfd_cmd
);
3182 install_element(EIGRP_NODE
, &vtysh_exit_eigrpd_cmd
);
3183 install_element(EIGRP_NODE
, &vtysh_quit_eigrpd_cmd
);
3184 install_element(BABEL_NODE
, &vtysh_exit_babeld_cmd
);
3185 install_element(BABEL_NODE
, &vtysh_quit_babeld_cmd
);
3186 install_element(OSPF6_NODE
, &vtysh_exit_ospf6d_cmd
);
3187 install_element(OSPF6_NODE
, &vtysh_quit_ospf6d_cmd
);
3188 #if defined(HAVE_LDPD)
3189 install_element(LDP_NODE
, &vtysh_exit_ldpd_cmd
);
3190 install_element(LDP_NODE
, &vtysh_quit_ldpd_cmd
);
3191 install_element(LDP_IPV4_NODE
, &vtysh_exit_ldpd_cmd
);
3192 install_element(LDP_IPV4_NODE
, &vtysh_quit_ldpd_cmd
);
3193 install_element(LDP_IPV4_NODE
, &ldp_exit_address_family_cmd
);
3194 install_element(LDP_IPV6_NODE
, &vtysh_exit_ldpd_cmd
);
3195 install_element(LDP_IPV6_NODE
, &vtysh_quit_ldpd_cmd
);
3196 install_element(LDP_IPV6_NODE
, &ldp_exit_address_family_cmd
);
3197 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
3198 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
3199 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_exit_ldpd_cmd
);
3200 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_quit_ldpd_cmd
);
3201 install_element(LDP_L2VPN_NODE
, &vtysh_exit_ldpd_cmd
);
3202 install_element(LDP_L2VPN_NODE
, &vtysh_quit_ldpd_cmd
);
3203 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_exit_ldpd_cmd
);
3204 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_quit_ldpd_cmd
);
3206 install_element(BGP_NODE
, &vtysh_exit_bgpd_cmd
);
3207 install_element(BGP_NODE
, &vtysh_quit_bgpd_cmd
);
3208 install_element(BGP_VPNV4_NODE
, &vtysh_exit_bgpd_cmd
);
3209 install_element(BGP_VPNV4_NODE
, &vtysh_quit_bgpd_cmd
);
3210 install_element(BGP_VPNV6_NODE
, &vtysh_exit_bgpd_cmd
);
3211 install_element(BGP_VPNV6_NODE
, &vtysh_quit_bgpd_cmd
);
3212 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_exit_bgpd_cmd
);
3213 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_quit_bgpd_cmd
);
3214 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_exit_bgpd_cmd
);
3215 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_quit_bgpd_cmd
);
3216 install_element(BGP_IPV4_NODE
, &vtysh_exit_bgpd_cmd
);
3217 install_element(BGP_IPV4_NODE
, &vtysh_quit_bgpd_cmd
);
3218 install_element(BGP_IPV4M_NODE
, &vtysh_exit_bgpd_cmd
);
3219 install_element(BGP_IPV4M_NODE
, &vtysh_quit_bgpd_cmd
);
3220 install_element(BGP_IPV4L_NODE
, &vtysh_exit_bgpd_cmd
);
3221 install_element(BGP_IPV4L_NODE
, &vtysh_quit_bgpd_cmd
);
3222 install_element(BGP_IPV6_NODE
, &vtysh_exit_bgpd_cmd
);
3223 install_element(BGP_IPV6_NODE
, &vtysh_quit_bgpd_cmd
);
3224 install_element(BGP_IPV6M_NODE
, &vtysh_exit_bgpd_cmd
);
3225 install_element(BGP_IPV6M_NODE
, &vtysh_quit_bgpd_cmd
);
3226 install_element(BGP_EVPN_NODE
, &vtysh_quit_bgpd_cmd
);
3227 install_element(BGP_EVPN_NODE
, &vtysh_exit_bgpd_cmd
);
3228 install_element(BGP_EVPN_VNI_NODE
, &vtysh_exit_bgpd_cmd
);
3229 install_element(BGP_EVPN_VNI_NODE
, &vtysh_quit_bgpd_cmd
);
3230 install_element(BGP_IPV6L_NODE
, &vtysh_exit_bgpd_cmd
);
3231 install_element(BGP_IPV6L_NODE
, &vtysh_quit_bgpd_cmd
);
3232 #if defined(ENABLE_BGP_VNC)
3233 install_element(BGP_VRF_POLICY_NODE
, &vtysh_exit_bgpd_cmd
);
3234 install_element(BGP_VRF_POLICY_NODE
, &vtysh_quit_bgpd_cmd
);
3235 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_exit_bgpd_cmd
);
3236 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_quit_bgpd_cmd
);
3237 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
3238 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
3239 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_exit_bgpd_cmd
);
3240 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_quit_bgpd_cmd
);
3242 install_element(ISIS_NODE
, &vtysh_exit_isisd_cmd
);
3243 install_element(ISIS_NODE
, &vtysh_quit_isisd_cmd
);
3244 install_element(KEYCHAIN_NODE
, &vtysh_exit_ripd_cmd
);
3245 install_element(KEYCHAIN_NODE
, &vtysh_quit_ripd_cmd
);
3246 install_element(KEYCHAIN_KEY_NODE
, &vtysh_exit_ripd_cmd
);
3247 install_element(KEYCHAIN_KEY_NODE
, &vtysh_quit_ripd_cmd
);
3248 install_element(RMAP_NODE
, &vtysh_exit_rmap_cmd
);
3249 install_element(RMAP_NODE
, &vtysh_quit_rmap_cmd
);
3250 install_element(VTY_NODE
, &vtysh_exit_line_vty_cmd
);
3251 install_element(VTY_NODE
, &vtysh_quit_line_vty_cmd
);
3253 /* "end" command. */
3254 install_element(CONFIG_NODE
, &vtysh_end_all_cmd
);
3255 install_element(ENABLE_NODE
, &vtysh_end_all_cmd
);
3256 install_element(RIP_NODE
, &vtysh_end_all_cmd
);
3257 install_element(RIPNG_NODE
, &vtysh_end_all_cmd
);
3258 install_element(OSPF_NODE
, &vtysh_end_all_cmd
);
3259 install_element(EIGRP_NODE
, &vtysh_end_all_cmd
);
3260 install_element(BABEL_NODE
, &vtysh_end_all_cmd
);
3261 install_element(OSPF6_NODE
, &vtysh_end_all_cmd
);
3262 install_element(LDP_NODE
, &vtysh_end_all_cmd
);
3263 install_element(LDP_IPV4_NODE
, &vtysh_end_all_cmd
);
3264 install_element(LDP_IPV6_NODE
, &vtysh_end_all_cmd
);
3265 install_element(LDP_IPV4_IFACE_NODE
, &vtysh_end_all_cmd
);
3266 install_element(LDP_IPV6_IFACE_NODE
, &vtysh_end_all_cmd
);
3267 install_element(LDP_L2VPN_NODE
, &vtysh_end_all_cmd
);
3268 install_element(LDP_PSEUDOWIRE_NODE
, &vtysh_end_all_cmd
);
3269 install_element(BGP_NODE
, &vtysh_end_all_cmd
);
3270 install_element(BGP_IPV4_NODE
, &vtysh_end_all_cmd
);
3271 install_element(BGP_IPV4M_NODE
, &vtysh_end_all_cmd
);
3272 install_element(BGP_IPV4L_NODE
, &vtysh_end_all_cmd
);
3273 install_element(BGP_VPNV4_NODE
, &vtysh_end_all_cmd
);
3274 install_element(BGP_VPNV6_NODE
, &vtysh_end_all_cmd
);
3275 install_element(BGP_FLOWSPECV4_NODE
, &vtysh_end_all_cmd
);
3276 install_element(BGP_FLOWSPECV6_NODE
, &vtysh_end_all_cmd
);
3277 install_element(BGP_IPV6_NODE
, &vtysh_end_all_cmd
);
3278 install_element(BGP_IPV6M_NODE
, &vtysh_end_all_cmd
);
3279 install_element(BGP_IPV6L_NODE
, &vtysh_end_all_cmd
);
3280 install_element(BGP_VRF_POLICY_NODE
, &vtysh_end_all_cmd
);
3281 install_element(BGP_EVPN_NODE
, &vtysh_end_all_cmd
);
3282 install_element(BGP_EVPN_VNI_NODE
, &vtysh_end_all_cmd
);
3283 install_element(BGP_VNC_DEFAULTS_NODE
, &vtysh_end_all_cmd
);
3284 install_element(BGP_VNC_NVE_GROUP_NODE
, &vtysh_end_all_cmd
);
3285 install_element(BGP_VNC_L2_GROUP_NODE
, &vtysh_end_all_cmd
);
3286 install_element(ISIS_NODE
, &vtysh_end_all_cmd
);
3287 install_element(KEYCHAIN_NODE
, &vtysh_end_all_cmd
);
3288 install_element(KEYCHAIN_KEY_NODE
, &vtysh_end_all_cmd
);
3289 install_element(RMAP_NODE
, &vtysh_end_all_cmd
);
3290 install_element(VTY_NODE
, &vtysh_end_all_cmd
);
3292 install_element(INTERFACE_NODE
, &vtysh_interface_desc_cmd
);
3293 install_element(INTERFACE_NODE
, &vtysh_no_interface_desc_cmd
);
3294 install_element(INTERFACE_NODE
, &vtysh_end_all_cmd
);
3295 install_element(INTERFACE_NODE
, &vtysh_exit_interface_cmd
);
3296 install_element(LINK_PARAMS_NODE
, &exit_link_params_cmd
);
3297 install_element(LINK_PARAMS_NODE
, &vtysh_end_all_cmd
);
3298 install_element(LINK_PARAMS_NODE
, &vtysh_exit_interface_cmd
);
3299 install_element(INTERFACE_NODE
, &vtysh_quit_interface_cmd
);
3301 install_element(PW_NODE
, &vtysh_end_all_cmd
);
3302 install_element(PW_NODE
, &vtysh_exit_interface_cmd
);
3303 install_element(PW_NODE
, &vtysh_quit_interface_cmd
);
3305 install_element(LOGICALROUTER_NODE
, &vtysh_end_all_cmd
);
3307 install_element(CONFIG_NODE
, &vtysh_logicalrouter_cmd
);
3308 install_element(CONFIG_NODE
, &vtysh_no_logicalrouter_cmd
);
3309 install_element(LOGICALROUTER_NODE
, &vtysh_exit_logicalrouter_cmd
);
3310 install_element(LOGICALROUTER_NODE
, &vtysh_quit_logicalrouter_cmd
);
3312 install_element(VRF_NODE
, &vtysh_end_all_cmd
);
3313 install_element(VRF_NODE
, &vtysh_exit_vrf_cmd
);
3314 install_element(VRF_NODE
, &vtysh_quit_vrf_cmd
);
3316 install_element(CONFIG_NODE
, &router_eigrp_cmd
);
3317 install_element(CONFIG_NODE
, &router_babel_cmd
);
3318 install_element(CONFIG_NODE
, &router_rip_cmd
);
3319 install_element(CONFIG_NODE
, &router_ripng_cmd
);
3320 install_element(CONFIG_NODE
, &router_ospf_cmd
);
3321 install_element(CONFIG_NODE
, &router_ospf6_cmd
);
3322 #if defined(HAVE_LDPD)
3323 install_element(CONFIG_NODE
, &ldp_mpls_ldp_cmd
);
3324 install_element(LDP_NODE
, &ldp_address_family_ipv4_cmd
);
3325 install_element(LDP_NODE
, &ldp_address_family_ipv6_cmd
);
3326 install_element(LDP_IPV4_NODE
, &ldp_interface_ifname_cmd
);
3327 install_element(LDP_IPV6_NODE
, &ldp_interface_ifname_cmd
);
3328 install_element(CONFIG_NODE
, &ldp_l2vpn_word_type_vpls_cmd
);
3329 install_element(LDP_L2VPN_NODE
, &ldp_member_pseudowire_ifname_cmd
);
3331 install_element(CONFIG_NODE
, &router_isis_cmd
);
3332 install_element(CONFIG_NODE
, &router_bgp_cmd
);
3333 install_element(BGP_NODE
, &address_family_vpnv4_cmd
);
3334 install_element(BGP_NODE
, &address_family_vpnv6_cmd
);
3335 #if defined(ENABLE_BGP_VNC)
3336 install_element(BGP_NODE
, &vnc_vrf_policy_cmd
);
3337 install_element(BGP_NODE
, &vnc_defaults_cmd
);
3338 install_element(BGP_NODE
, &vnc_nve_group_cmd
);
3339 install_element(BGP_NODE
, &vnc_l2_group_cmd
);
3341 install_element(BGP_NODE
, &address_family_ipv4_cmd
);
3342 install_element(BGP_NODE
, &address_family_ipv4_multicast_cmd
);
3343 install_element(BGP_NODE
, &address_family_ipv4_vpn_cmd
);
3344 install_element(BGP_NODE
, &address_family_ipv4_labeled_unicast_cmd
);
3345 install_element(BGP_NODE
, &address_family_ipv6_cmd
);
3346 install_element(BGP_NODE
, &address_family_ipv6_multicast_cmd
);
3347 install_element(BGP_NODE
, &address_family_ipv6_vpn_cmd
);
3348 install_element(BGP_NODE
, &address_family_ipv6_labeled_unicast_cmd
);
3349 install_element(BGP_NODE
, &address_family_evpn_cmd
);
3350 install_element(BGP_NODE
, &address_family_flowspecv4_cmd
);
3351 install_element(BGP_NODE
, &address_family_flowspecv6_cmd
);
3352 #if defined(HAVE_CUMULUS)
3353 install_element(BGP_NODE
, &address_family_evpn2_cmd
);
3355 install_element(BGP_VPNV4_NODE
, &exit_address_family_cmd
);
3356 install_element(BGP_VPNV6_NODE
, &exit_address_family_cmd
);
3357 install_element(BGP_IPV4_NODE
, &exit_address_family_cmd
);
3358 install_element(BGP_IPV4M_NODE
, &exit_address_family_cmd
);
3359 install_element(BGP_IPV4L_NODE
, &exit_address_family_cmd
);
3360 install_element(BGP_IPV6_NODE
, &exit_address_family_cmd
);
3361 install_element(BGP_IPV6M_NODE
, &exit_address_family_cmd
);
3362 install_element(BGP_EVPN_NODE
, &exit_address_family_cmd
);
3363 install_element(BGP_IPV6L_NODE
, &exit_address_family_cmd
);
3364 install_element(BGP_FLOWSPECV4_NODE
, &exit_address_family_cmd
);
3365 install_element(BGP_FLOWSPECV6_NODE
, &exit_address_family_cmd
);
3367 #if defined(HAVE_RPKI)
3368 install_element(CONFIG_NODE
, &rpki_cmd
);
3369 install_element(RPKI_NODE
, &rpki_exit_cmd
);
3370 install_element(RPKI_NODE
, &rpki_quit_cmd
);
3371 install_element(RPKI_NODE
, &vtysh_end_all_cmd
);
3375 install_element(BGP_EVPN_NODE
, &bgp_evpn_vni_cmd
);
3376 install_element(BGP_EVPN_VNI_NODE
, &exit_vni_cmd
);
3378 install_element(BGP_VRF_POLICY_NODE
, &exit_vrf_policy_cmd
);
3379 install_element(BGP_VNC_DEFAULTS_NODE
, &exit_vnc_config_cmd
);
3380 install_element(BGP_VNC_NVE_GROUP_NODE
, &exit_vnc_config_cmd
);
3381 install_element(BGP_VNC_L2_GROUP_NODE
, &exit_vnc_config_cmd
);
3383 install_element(CONFIG_NODE
, &key_chain_cmd
);
3384 install_element(CONFIG_NODE
, &vtysh_route_map_cmd
);
3385 install_element(CONFIG_NODE
, &vtysh_line_vty_cmd
);
3386 install_element(KEYCHAIN_NODE
, &key_cmd
);
3387 install_element(KEYCHAIN_NODE
, &key_chain_cmd
);
3388 install_element(KEYCHAIN_KEY_NODE
, &key_chain_cmd
);
3389 install_element(CONFIG_NODE
, &vtysh_interface_cmd
);
3390 install_element(CONFIG_NODE
, &vtysh_no_interface_cmd
);
3391 install_element(CONFIG_NODE
, &vtysh_no_interface_vrf_cmd
);
3392 install_element(CONFIG_NODE
, &vtysh_pseudowire_cmd
);
3393 install_element(INTERFACE_NODE
, &vtysh_link_params_cmd
);
3394 install_element(ENABLE_NODE
, &vtysh_show_running_config_cmd
);
3395 install_element(ENABLE_NODE
, &vtysh_copy_running_config_cmd
);
3397 install_element(CONFIG_NODE
, &vtysh_vrf_cmd
);
3398 install_element(CONFIG_NODE
, &vtysh_no_vrf_cmd
);
3400 /* "write terminal" command. */
3401 install_element(ENABLE_NODE
, &vtysh_write_terminal_cmd
);
3403 install_element(CONFIG_NODE
, &vtysh_integrated_config_cmd
);
3404 install_element(CONFIG_NODE
, &no_vtysh_integrated_config_cmd
);
3406 /* "write memory" command. */
3407 install_element(ENABLE_NODE
, &vtysh_write_memory_cmd
);
3409 install_element(VIEW_NODE
, &vtysh_terminal_length_cmd
);
3410 install_element(VIEW_NODE
, &vtysh_terminal_no_length_cmd
);
3411 install_element(VIEW_NODE
, &vtysh_show_daemons_cmd
);
3413 install_element(VIEW_NODE
, &vtysh_ping_cmd
);
3414 install_element(VIEW_NODE
, &vtysh_ping_ip_cmd
);
3415 install_element(VIEW_NODE
, &vtysh_traceroute_cmd
);
3416 install_element(VIEW_NODE
, &vtysh_traceroute_ip_cmd
);
3417 install_element(VIEW_NODE
, &vtysh_mtrace_cmd
);
3418 install_element(VIEW_NODE
, &vtysh_ping6_cmd
);
3419 install_element(VIEW_NODE
, &vtysh_traceroute6_cmd
);
3420 #if defined(HAVE_SHELL_ACCESS)
3421 install_element(VIEW_NODE
, &vtysh_telnet_cmd
);
3422 install_element(VIEW_NODE
, &vtysh_telnet_port_cmd
);
3423 install_element(VIEW_NODE
, &vtysh_ssh_cmd
);
3425 #if defined(HAVE_SHELL_ACCESS)
3426 install_element(ENABLE_NODE
, &vtysh_start_shell_cmd
);
3427 install_element(ENABLE_NODE
, &vtysh_start_bash_cmd
);
3428 install_element(ENABLE_NODE
, &vtysh_start_zsh_cmd
);
3432 install_element(VIEW_NODE
, &vtysh_show_debugging_cmd
);
3433 install_element(VIEW_NODE
, &vtysh_show_debugging_hashtable_cmd
);
3434 install_element(ENABLE_NODE
, &vtysh_debug_all_cmd
);
3435 install_element(CONFIG_NODE
, &vtysh_debug_all_cmd
);
3437 /* misc lib show commands */
3438 install_element(VIEW_NODE
, &vtysh_show_memory_cmd
);
3439 install_element(VIEW_NODE
, &vtysh_show_modules_cmd
);
3440 install_element(VIEW_NODE
, &vtysh_show_work_queues_cmd
);
3441 install_element(VIEW_NODE
, &vtysh_show_work_queues_daemon_cmd
);
3442 install_element(VIEW_NODE
, &vtysh_show_thread_cmd
);
3445 install_element(VIEW_NODE
, &vtysh_show_logging_cmd
);
3446 install_element(CONFIG_NODE
, &vtysh_log_stdout_cmd
);
3447 install_element(CONFIG_NODE
, &vtysh_log_stdout_level_cmd
);
3448 install_element(CONFIG_NODE
, &no_vtysh_log_stdout_cmd
);
3449 install_element(CONFIG_NODE
, &vtysh_log_file_cmd
);
3450 install_element(CONFIG_NODE
, &vtysh_log_file_level_cmd
);
3451 install_element(CONFIG_NODE
, &no_vtysh_log_file_cmd
);
3452 install_element(CONFIG_NODE
, &vtysh_log_monitor_cmd
);
3453 install_element(CONFIG_NODE
, &no_vtysh_log_monitor_cmd
);
3454 install_element(CONFIG_NODE
, &vtysh_log_syslog_cmd
);
3455 install_element(CONFIG_NODE
, &no_vtysh_log_syslog_cmd
);
3456 install_element(CONFIG_NODE
, &vtysh_log_trap_cmd
);
3457 install_element(CONFIG_NODE
, &no_vtysh_log_trap_cmd
);
3458 install_element(CONFIG_NODE
, &vtysh_log_facility_cmd
);
3459 install_element(CONFIG_NODE
, &no_vtysh_log_facility_cmd
);
3460 install_element(CONFIG_NODE
, &vtysh_log_record_priority_cmd
);
3461 install_element(CONFIG_NODE
, &no_vtysh_log_record_priority_cmd
);
3462 install_element(CONFIG_NODE
, &vtysh_log_timestamp_precision_cmd
);
3463 install_element(CONFIG_NODE
, &no_vtysh_log_timestamp_precision_cmd
);
3465 install_element(CONFIG_NODE
, &vtysh_service_password_encrypt_cmd
);
3466 install_element(CONFIG_NODE
, &no_vtysh_service_password_encrypt_cmd
);
3468 install_element(CONFIG_NODE
, &vtysh_password_cmd
);
3469 install_element(CONFIG_NODE
, &vtysh_enable_password_cmd
);
3470 install_element(CONFIG_NODE
, &no_vtysh_enable_password_cmd
);