]> git.proxmox.com Git - mirror_frr.git/blame - vtysh/vtysh.c
lib: allow 'do' commands in ENABLE_NODE
[mirror_frr.git] / vtysh / vtysh.c
CommitLineData
718e3744 1/* Virtual terminal interface shell.
2 * Copyright (C) 2000 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
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
9 * later version.
10 *
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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
ac4d0be5 19 * 02111-1307, USA.
718e3744 20 */
21
22#include <zebra.h>
23
24#include <sys/un.h>
25#include <setjmp.h>
26#include <sys/wait.h>
27#include <sys/resource.h>
28#include <sys/stat.h>
29
30#include <readline/readline.h>
31#include <readline/history.h>
32
7c8ff89e
DS
33#include <dirent.h>
34#include <stdio.h>
35#include <string.h>
36
4201dd11 37#include "linklist.h"
718e3744 38#include "command.h"
39#include "memory.h"
039f3a34 40#include "filter.h"
718e3744 41#include "vtysh/vtysh.h"
6099b3b5 42#include "log.h"
320da874 43#include "bgpd/bgp_vty.h"
13460c44 44#include "ns.h"
cd2a8a42 45#include "vrf.h"
eb05883f 46#include "libfrr.h"
718e3744 47
4a1ab8e4
DL
48DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CMD, "Vtysh cmd copy")
49
718e3744 50/* Struct VTY. */
51struct vty *vty;
52
53/* VTY shell pager name. */
54char *vtysh_pager_name = NULL;
55
56/* VTY shell client structure. */
ac4d0be5 57struct vtysh_client {
58 int fd;
59 const char *name;
60 int flag;
61 char path[MAXPATHLEN];
62 struct vtysh_client *next;
7c8ff89e
DS
63};
64
ac4d0be5 65struct vtysh_client vtysh_client[] = {
66 {.fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .next = NULL},
67 {.fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .next = NULL},
68 {.fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .next = NULL},
69 {.fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .next = NULL},
70 {.fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .next = NULL},
71 {.fd = -1, .name = "ldpd", .flag = VTYSH_LDPD, .next = NULL},
72 {.fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .next = NULL},
73 {.fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .next = NULL},
74 {.fd = -1, .name = "pimd", .flag = VTYSH_PIMD, .next = NULL},
75 {.fd = -1, .name = "nhrpd", .flag = VTYSH_NHRPD, .next = NULL},
76 {.fd = -1, .name = "watchfrr", .flag = VTYSH_WATCHFRR, .next = NULL},
b1aa147d 77};
78
ac4d0be5 79enum vtysh_write_integrated vtysh_write_integrated =
80 WRITE_INTEGRATED_UNSPECIFIED;
e7168df4 81
ac4d0be5 82static void vclient_close(struct vtysh_client *vclient)
718e3744 83{
ac4d0be5 84 if (vclient->fd >= 0) {
85 fprintf(stderr,
86 "Warning: closing connection to %s because of an I/O error!\n",
87 vclient->name);
88 close(vclient->fd);
89 vclient->fd = -1;
90 }
718e3744 91}
92
f35a5350 93/* Return true if str begins with prefix, else return false */
ac4d0be5 94static int begins_with(const char *str, const char *prefix)
f35a5350 95{
ac4d0be5 96 if (!str || !prefix)
97 return 0;
98 size_t lenstr = strlen(str);
99 size_t lenprefix = strlen(prefix);
100 if (lenprefix > lenstr)
101 return 0;
102 return strncmp(str, prefix, lenprefix) == 0;
f35a5350
DW
103}
104
7526a182
DL
105/* NB: multiplexed function:
106 * if fp == NULL, this calls vtysh_config_parse_line
107 * if fp != NULL, this prints lines to fp
108 */
ac4d0be5 109static int vtysh_client_run(struct vtysh_client *vclient, const char *line,
110 FILE *fp)
111{
112 int ret;
113 char stackbuf[4096];
114 char *buf = stackbuf;
115 size_t bufsz = sizeof(stackbuf);
116 char *bufvalid, *end = NULL;
117 char terminator[3] = {0, 0, 0};
118
119 if (vclient->fd < 0)
120 return CMD_SUCCESS;
121
122 ret = write(vclient->fd, line, strlen(line) + 1);
123 if (ret <= 0)
124 goto out_err;
125
126 bufvalid = buf;
127 do {
128 ssize_t nread =
129 read(vclient->fd, bufvalid, buf + bufsz - bufvalid);
130
131 if (nread < 0 && (errno == EINTR || errno == EAGAIN))
132 continue;
133
134 if (nread <= 0) {
135 fprintf(stderr, "vtysh: error reading from %s: %s (%d)",
136 vclient->name, safe_strerror(errno), errno);
137 goto out_err;
138 }
139
140 bufvalid += nread;
141
142 end = memmem(buf, bufvalid - buf, terminator,
143 sizeof(terminator));
144 if (end + sizeof(terminator) + 1 > bufvalid)
145 /* found \0\0\0 but return code hasn't been read yet */
146 end = NULL;
147 if (end)
148 ret = end[sizeof(terminator)];
149
150 while (bufvalid > buf && (end > buf || !end)) {
151 size_t textlen = (end ? end : bufvalid) - buf;
152 char *eol = memchr(buf, '\n', textlen);
153 if (eol)
154 /* line break */
155 *eol++ = '\0';
156 else if (end == buf)
157 /* no line break, end of input, no text left
158 * before end
159 * => don't insert an empty line at the end */
160 break;
161 else if (end)
162 /* no line break, end of input, but some text
163 * left */
164 eol = end;
165 else
166 /* continue reading */
167 break;
168
169 /* eol is at a line end now, either \n => \0 or \0\0\0
170 */
171 assert(eol && eol <= bufvalid);
172
173 if (fp) {
174 fputs(buf, fp);
175 fputc('\n', fp);
176 } else
177 vtysh_config_parse_line(buf);
178
179 if (eol == end)
180 /* \n\0\0\0 */
181 break;
182
183 memmove(buf, eol, bufvalid - eol);
184 bufvalid -= eol - buf;
185 if (end)
186 end -= eol - buf;
187 }
188
189 if (bufvalid == buf + bufsz) {
190 char *new;
191 bufsz *= 2;
192 if (buf == stackbuf) {
193 new = XMALLOC(MTYPE_TMP, bufsz);
194 memcpy(new, stackbuf, sizeof(stackbuf));
195 } else
196 new = XREALLOC(MTYPE_TMP, buf, bufsz);
197
198 bufvalid = bufvalid - buf + new;
199 buf = new;
200 /* if end != NULL, we won't be reading more data... */
201 assert(end == NULL);
202 }
203 } while (!end);
204 goto out;
7526a182
DL
205
206out_err:
ac4d0be5 207 vclient_close(vclient);
208 ret = CMD_SUCCESS;
7526a182 209out:
ac4d0be5 210 if (buf != stackbuf)
211 XFREE(MTYPE_TMP, buf);
212 return ret;
718e3744 213}
214
ac4d0be5 215static int vtysh_client_run_all(struct vtysh_client *head_client,
216 const char *line, int continue_on_err, FILE *fp)
7c8ff89e 217{
ac4d0be5 218 struct vtysh_client *client;
219 int rc, rc_all = CMD_SUCCESS;
7c8ff89e 220
ac4d0be5 221 for (client = head_client; client; client = client->next) {
222 rc = vtysh_client_run(client, line, fp);
223 if (rc != CMD_SUCCESS) {
224 if (!continue_on_err)
225 return rc;
226 rc_all = rc;
227 }
228 }
229 return rc_all;
7526a182
DL
230}
231
ac4d0be5 232static int vtysh_client_execute(struct vtysh_client *head_client,
233 const char *line, FILE *fp)
7526a182 234{
ac4d0be5 235 return vtysh_client_run_all(head_client, line, 0, fp);
7526a182
DL
236}
237
ac4d0be5 238static void vtysh_client_config(struct vtysh_client *head_client, char *line)
7526a182 239{
ac4d0be5 240 vtysh_client_run_all(head_client, line, 1, NULL);
7c8ff89e
DS
241}
242
ac4d0be5 243void vtysh_pager_init(void)
718e3744 244{
ac4d0be5 245 char *pager_defined;
5a9c53de 246
ac4d0be5 247 pager_defined = getenv("VTYSH_PAGER");
5a9c53de 248
ac4d0be5 249 if (pager_defined)
250 vtysh_pager_name = strdup(pager_defined);
251 else
252 vtysh_pager_name = strdup("more");
718e3744 253}
254
255/* Command execution over the vty interface. */
ac4d0be5 256static int vtysh_execute_func(const char *line, int pager)
257{
258 int ret, cmd_stat;
259 u_int i;
260 vector vline;
261 const struct cmd_element *cmd;
262 FILE *fp = NULL;
263 int closepager = 0;
264 int tried = 0;
265 int saved_ret, saved_node;
266
267 /* Split readline string up into the vector. */
268 vline = cmd_make_strvec(line);
269
270 if (vline == NULL)
271 return CMD_SUCCESS;
272
273 saved_ret = ret = cmd_execute_command(vline, vty, &cmd, 1);
274 saved_node = vty->node;
275
276 /* If command doesn't succeeded in current node, try to walk up in node
277 * tree.
278 * Changing vty->node is enough to try it just out without actual walkup
279 * in
280 * the vtysh. */
281 while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON
282 && ret != CMD_WARNING && vty->node > CONFIG_NODE) {
283 vty->node = node_parent(vty->node);
284 ret = cmd_execute_command(vline, vty, &cmd, 1);
285 tried++;
65efcfce 286 }
ac4d0be5 287
288 vty->node = saved_node;
289
290 /* If command succeeded in any other node than current (tried > 0) we
291 * have
292 * to move into node in the vtysh where it succeeded. */
293 if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON
294 || ret == CMD_WARNING) {
295 if ((saved_node == BGP_VPNV4_NODE
296 || saved_node == BGP_VPNV6_NODE
297 || saved_node == BGP_IPV4_NODE
298 || saved_node == BGP_IPV6_NODE
299 || saved_node == BGP_IPV4M_NODE
300 || saved_node == BGP_IPV6M_NODE
301 || saved_node == BGP_EVPN_NODE)
302 && (tried == 1)) {
303 vtysh_execute("exit-address-family");
304 } else if (saved_node == BGP_VRF_POLICY_NODE && (tried == 1)) {
305 vtysh_execute("exit-vrf-policy");
306 } else if ((saved_node == BGP_VNC_DEFAULTS_NODE
307 || saved_node == BGP_VNC_NVE_GROUP_NODE
308 || saved_node == BGP_VNC_L2_GROUP_NODE)
309 && (tried == 1)) {
310 vtysh_execute("exit-vnc");
311 } else if ((saved_node == KEYCHAIN_KEY_NODE
312 || saved_node == LDP_PSEUDOWIRE_NODE
313 || saved_node == LDP_IPV4_IFACE_NODE
314 || saved_node == LDP_IPV6_IFACE_NODE)
315 && (tried == 1)) {
316 vtysh_execute("exit");
317 } else if (tried) {
318 vtysh_execute("end");
319 vtysh_execute("configure terminal");
320 }
13bfca7a 321 }
ac4d0be5 322 /* If command didn't succeed in any node, continue with return value
323 * from
324 * first try. */
325 else if (tried) {
326 ret = saved_ret;
13bfca7a 327 }
718e3744 328
ac4d0be5 329 cmd_free_strvec(vline);
330
331 cmd_stat = ret;
332 switch (ret) {
333 case CMD_WARNING:
334 if (vty->type == VTY_FILE)
335 fprintf(stdout, "Warning...\n");
336 break;
337 case CMD_ERR_AMBIGUOUS:
338 fprintf(stdout, "%% Ambiguous command.\n");
339 break;
340 case CMD_ERR_NO_MATCH:
341 fprintf(stdout, "%% Unknown command.\n");
342 break;
343 case CMD_ERR_INCOMPLETE:
344 fprintf(stdout, "%% Command incomplete.\n");
345 break;
346 case CMD_SUCCESS_DAEMON: {
347 /* FIXME: Don't open pager for exit commands. popen() causes
348 * problems
349 * if exited from vtysh at all. This hack shouldn't cause any
350 * problem
351 * but is really ugly. */
352 if (pager && vtysh_pager_name
353 && (strncmp(line, "exit", 4) != 0)) {
354 fp = popen(vtysh_pager_name, "w");
355 if (fp == NULL) {
356 perror("popen failed for pager");
357 fp = stdout;
358 } else
359 closepager = 1;
360 } else
361 fp = stdout;
362
363 if (!strcmp(cmd->string, "configure terminal")) {
364 for (i = 0; i < array_size(vtysh_client); i++) {
365 cmd_stat = vtysh_client_execute(
366 &vtysh_client[i], line, fp);
367 if (cmd_stat == CMD_WARNING)
368 break;
369 }
370
371 if (cmd_stat) {
372 line = "end";
373 vline = cmd_make_strvec(line);
374
375 if (vline == NULL) {
376 if (pager && vtysh_pager_name && fp
377 && closepager) {
378 if (pclose(fp) == -1) {
379 perror("pclose failed for pager");
380 }
381 fp = NULL;
382 }
383 return CMD_SUCCESS;
384 }
385
386 ret = cmd_execute_command(vline, vty, &cmd, 1);
387 cmd_free_strvec(vline);
388 if (ret != CMD_SUCCESS_DAEMON)
389 break;
390 } else if (cmd->func) {
391 (*cmd->func)(cmd, vty, 0, NULL);
392 break;
393 }
b094d260 394 }
718e3744 395
ac4d0be5 396 cmd_stat = CMD_SUCCESS;
397 for (i = 0; i < array_size(vtysh_client); i++) {
398 if (cmd->daemon & vtysh_client[i].flag) {
399 cmd_stat = vtysh_client_execute(
400 &vtysh_client[i], line, fp);
401 if (cmd_stat != CMD_SUCCESS)
402 break;
403 }
404 }
b1aa147d 405 if (cmd_stat != CMD_SUCCESS)
ac4d0be5 406 break;
407
408 if (cmd->func)
409 (*cmd->func)(cmd, vty, 0, NULL);
718e3744 410 }
ac4d0be5 411 }
412 if (pager && vtysh_pager_name && fp && closepager) {
413 if (pclose(fp) == -1) {
414 perror("pclose failed for pager");
415 }
416 fp = NULL;
417 }
418 return cmd_stat;
718e3744 419}
420
ac4d0be5 421int vtysh_execute_no_pager(const char *line)
718e3744 422{
ac4d0be5 423 return vtysh_execute_func(line, 0);
718e3744 424}
425
ac4d0be5 426int vtysh_execute(const char *line)
718e3744 427{
ac4d0be5 428 return vtysh_execute_func(line, 1);
718e3744 429}
430
ac4d0be5 431static char *trim(char *s)
a5b89524 432{
ac4d0be5 433 size_t size;
434 char *end;
a5b89524 435
ac4d0be5 436 size = strlen(s);
a5b89524 437
ac4d0be5 438 if (!size)
439 return s;
a5b89524 440
ac4d0be5 441 end = s + size - 1;
442 while (end >= s && isspace(*end))
443 end--;
444 *(end + 1) = '\0';
a5b89524 445
ac4d0be5 446 while (*s && isspace(*s))
447 s++;
a5b89524 448
ac4d0be5 449 return s;
a5b89524
DW
450}
451
ac4d0be5 452int vtysh_mark_file(const char *filename)
0846286b 453{
ac4d0be5 454 struct vty *vty;
455 FILE *confp = NULL;
456 int ret;
457 vector vline;
458 int tried = 0;
459 const struct cmd_element *cmd;
460 int saved_ret, prev_node;
461 int lineno = 0;
462 char *vty_buf_copy = NULL;
463 char *vty_buf_trimmed = NULL;
0846286b 464
ac4d0be5 465 if (strncmp("-", filename, 1) == 0)
466 confp = stdin;
467 else
468 confp = fopen(filename, "r");
0846286b 469
ac4d0be5 470 if (confp == NULL) {
471 fprintf(stderr, "%% Can't open config file %s due to '%s'.\n",
472 filename, safe_strerror(errno));
473 return (CMD_ERR_NO_FILE);
474 }
0846286b 475
ac4d0be5 476 vty = vty_new();
477 vty->fd = 0; /* stdout */
478 vty->type = VTY_TERM;
479 vty->node = CONFIG_NODE;
0846286b 480
ac4d0be5 481 vtysh_execute_no_pager("enable");
482 vtysh_execute_no_pager("configure terminal");
483 vty_buf_copy = XCALLOC(MTYPE_VTYSH_CMD, VTY_BUFSIZ);
0846286b 484
ac4d0be5 485 while (fgets(vty->buf, VTY_BUFSIZ, confp)) {
486 lineno++;
487 tried = 0;
488 strcpy(vty_buf_copy, vty->buf);
489 vty_buf_trimmed = trim(vty_buf_copy);
0846286b 490
ac4d0be5 491 if (vty_buf_trimmed[0] == '!' || vty_buf_trimmed[0] == '#') {
492 fprintf(stdout, "%s", vty->buf);
493 continue;
494 }
0846286b 495
ac4d0be5 496 /* Split readline string up into the vector. */
497 vline = cmd_make_strvec(vty->buf);
0846286b 498
ac4d0be5 499 if (vline == NULL) {
500 fprintf(stdout, "%s", vty->buf);
501 continue;
502 }
0846286b 503
ac4d0be5 504 /* Ignore the "end" lines, we will generate these where
505 * appropriate */
506 if (strlen(vty_buf_trimmed) == 3
507 && strncmp("end", vty_buf_trimmed, 3) == 0) {
508 continue;
509 }
0846286b 510
ac4d0be5 511 prev_node = vty->node;
512 saved_ret = ret = cmd_execute_command_strict(vline, vty, &cmd);
513
514 /* If command doesn't succeeded in current node, try to walk up
515 * in node tree.
516 * Changing vty->node is enough to try it just out without
517 * actual walkup in
518 * the vtysh. */
519 while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON
520 && ret != CMD_WARNING && vty->node > CONFIG_NODE) {
521 vty->node = node_parent(vty->node);
522 ret = cmd_execute_command_strict(vline, vty, &cmd);
523 tried++;
524 }
0846286b 525
ac4d0be5 526 /* If command succeeded in any other node than current (tried >
527 * 0) we have
528 * to move into node in the vtysh where it succeeded. */
529 if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON
530 || ret == CMD_WARNING) {
531 if ((prev_node == BGP_VPNV4_NODE
532 || prev_node == BGP_IPV4_NODE
533 || prev_node == BGP_IPV6_NODE
534 || prev_node == BGP_IPV4M_NODE
535 || prev_node == BGP_IPV6M_NODE
536 || prev_node == BGP_VPNV6_NODE
537 || prev_node == BGP_EVPN_NODE)
538 && (tried == 1)) {
539 fprintf(stdout, "exit-address-family\n");
540 } else if ((prev_node == KEYCHAIN_KEY_NODE)
541 && (tried == 1)) {
542 fprintf(stdout, "exit\n");
543 } else if (tried) {
544 fprintf(stdout, "end\n");
545 }
546 }
547 /* If command didn't succeed in any node, continue with return
548 * value from
549 * first try. */
550 else if (tried) {
551 ret = saved_ret;
552 vty->node = prev_node;
553 }
554
555 cmd_free_strvec(vline);
556 switch (ret) {
557 case CMD_WARNING:
558 if (vty->type == VTY_FILE)
559 fprintf(stderr, "line %d: Warning...: %s\n",
560 lineno, vty->buf);
561 fclose(confp);
562 vty_close(vty);
563 XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
564 return CMD_WARNING;
565 case CMD_ERR_AMBIGUOUS:
566 fprintf(stderr, "line %d: %% Ambiguous command: %s\n",
567 lineno, vty->buf);
568 fclose(confp);
569 vty_close(vty);
570 XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
571 return CMD_ERR_AMBIGUOUS;
572 case CMD_ERR_NO_MATCH:
573 fprintf(stderr, "line %d: %% Unknown command: %s\n",
574 lineno, vty->buf);
575 fclose(confp);
576 vty_close(vty);
577 XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
578 return CMD_ERR_NO_MATCH;
579 case CMD_ERR_INCOMPLETE:
580 fprintf(stderr, "line %d: %% Command incomplete: %s\n",
581 lineno, vty->buf);
582 fclose(confp);
583 vty_close(vty);
584 XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
585 return CMD_ERR_INCOMPLETE;
586 case CMD_SUCCESS:
587 fprintf(stdout, "%s", vty->buf);
588 break;
589 case CMD_SUCCESS_DAEMON: {
590 u_int i;
591 int cmd_stat = CMD_SUCCESS;
592
593 fprintf(stdout, "%s", vty->buf);
594 for (i = 0; i < array_size(vtysh_client); i++) {
595 if (cmd->daemon & vtysh_client[i].flag) {
596 cmd_stat = vtysh_client_execute(
597 &vtysh_client[i], vty->buf,
598 stdout);
599 if (cmd_stat != CMD_SUCCESS)
600 break;
601 }
602 }
603 if (cmd_stat != CMD_SUCCESS)
604 break;
605
606 if (cmd->func)
607 (*cmd->func)(cmd, vty, 0, NULL);
608 }
609 }
0846286b 610 }
ac4d0be5 611 /* This is the end */
612 fprintf(stdout, "\nend\n");
613 vty_close(vty);
614 XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
0846286b 615
ac4d0be5 616 if (confp != stdin)
617 fclose(confp);
0846286b 618
ac4d0be5 619 return (0);
0846286b
DS
620}
621
718e3744 622/* Configration make from file. */
ac4d0be5 623int vtysh_config_from_file(struct vty *vty, FILE *fp)
624{
625 int ret;
626 const struct cmd_element *cmd;
627 int lineno = 0;
628 int retcode = CMD_SUCCESS;
629
630 while (fgets(vty->buf, VTY_BUFSIZ, fp)) {
631 lineno++;
632
633 ret = command_config_read_one_line(vty, &cmd, 1);
634
635 switch (ret) {
636 case CMD_WARNING:
637 if (vty->type == VTY_FILE)
638 fprintf(stderr, "line %d: Warning[%d]...: %s\n",
639 lineno, vty->node, vty->buf);
640 retcode = CMD_WARNING; /* once we have an error, we
641 remember & return that */
642 break;
643 case CMD_ERR_AMBIGUOUS:
644 fprintf(stderr,
645 "line %d: %% Ambiguous command[%d]: %s\n",
646 lineno, vty->node, vty->buf);
647 retcode = CMD_ERR_AMBIGUOUS; /* once we have an error,
648 we remember & return
649 that */
650 break;
651 case CMD_ERR_NO_MATCH:
652 fprintf(stderr, "line %d: %% Unknown command[%d]: %s",
653 lineno, vty->node, vty->buf);
654 retcode =
655 CMD_ERR_NO_MATCH; /* once we have an error, we
656 remember & return that */
657 break;
658 case CMD_ERR_INCOMPLETE:
659 fprintf(stderr,
660 "line %d: %% Command incomplete[%d]: %s\n",
661 lineno, vty->node, vty->buf);
662 retcode = CMD_ERR_INCOMPLETE; /* once we have an error,
663 we remember & return
664 that */
665 break;
666 case CMD_SUCCESS_DAEMON: {
667 u_int i;
668 int cmd_stat = CMD_SUCCESS;
669
670 for (i = 0; i < array_size(vtysh_client); i++) {
671 if (cmd->daemon & vtysh_client[i].flag) {
672 cmd_stat = vtysh_client_execute(
673 &vtysh_client[i], vty->buf,
674 stdout);
675 /*
676 * CMD_WARNING - Can mean that the
677 * command was
678 * parsed successfully but it was
679 * already entered
680 * in a few spots. As such if we
681 * receive a
682 * CMD_WARNING from a daemon we
683 * shouldn't stop
684 * talking to the other daemons for the
685 * particular
686 * command.
687 */
688 if (cmd_stat != CMD_SUCCESS
689 && cmd_stat != CMD_WARNING) {
690 fprintf(stderr,
691 "line %d: Failure to communicate[%d] to %s, line: %s\n",
692 lineno, cmd_stat,
693 vtysh_client[i].name,
694 vty->buf);
695 break;
696 }
697 }
698 }
699 if (cmd_stat != CMD_SUCCESS)
700 break;
701
702 if (cmd->func)
703 (*cmd->func)(cmd, vty, 0, NULL);
704 }
705 }
706 }
707
708 return (retcode);
709}
710
711/* We don't care about the point of the cursor when '?' is typed. */
712static int vtysh_rl_describe(void)
718e3744 713{
ac4d0be5 714 int ret;
715 unsigned int i;
716 vector vline;
717 vector describe;
718 int width;
719 struct cmd_token *token;
718e3744 720
ac4d0be5 721 vline = cmd_make_strvec(rl_line_buffer);
718e3744 722
ac4d0be5 723 /* In case of '> ?'. */
724 if (vline == NULL) {
725 vline = vector_init(1);
726 vector_set(vline, NULL);
727 } else if (rl_end && isspace((int)rl_line_buffer[rl_end - 1]))
728 vector_set(vline, NULL);
718e3744 729
ac4d0be5 730 describe = cmd_describe_command(vline, vty, &ret);
731
732 fprintf(stdout, "\n");
733
734 /* Ambiguous and no match error. */
735 switch (ret) {
718e3744 736 case CMD_ERR_AMBIGUOUS:
ac4d0be5 737 cmd_free_strvec(vline);
738 fprintf(stdout, "%% Ambiguous command.\n");
739 rl_on_new_line();
740 return 0;
741 break;
718e3744 742 case CMD_ERR_NO_MATCH:
ac4d0be5 743 cmd_free_strvec(vline);
744 fprintf(stdout, "%% There is no matched command.\n");
745 rl_on_new_line();
746 return 0;
747 break;
718e3744 748 }
3221dca8 749
ac4d0be5 750 /* Get width of command string. */
751 width = 0;
752 for (i = 0; i < vector_active(describe); i++)
753 if ((token = vector_slot(describe, i)) != NULL) {
754 if (token->text[0] == '\0')
755 continue;
718e3744 756
ac4d0be5 757 int len = strlen(token->text);
758
759 if (width < len)
760 width = len;
761 }
762
763 for (i = 0; i < vector_active(describe); i++)
764 if ((token = vector_slot(describe, i)) != NULL) {
765 if (!token->desc)
766 fprintf(stdout, " %-s\n", token->text);
767 else
768 fprintf(stdout, " %-*s %s\n", width,
769 token->text, token->desc);
770 }
718e3744 771
ac4d0be5 772 cmd_free_strvec(vline);
773 vector_free(describe);
718e3744 774
ac4d0be5 775 rl_on_new_line();
718e3744 776
ac4d0be5 777 return 0;
718e3744 778}
779
95e735b5 780/* Result of cmd_complete_command() call will be stored here
781 * and used in new_completion() in order to put the space in
782 * correct places only. */
718e3744 783int complete_status;
784
ac4d0be5 785static char *command_generator(const char *text, int state)
718e3744 786{
ac4d0be5 787 vector vline;
788 static char **matched = NULL;
789 static int index = 0;
718e3744 790
ac4d0be5 791 /* First call. */
792 if (!state) {
793 index = 0;
718e3744 794
ac4d0be5 795 if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
796 return NULL;
718e3744 797
ac4d0be5 798 vline = cmd_make_strvec(rl_line_buffer);
799 if (vline == NULL)
800 return NULL;
718e3744 801
ac4d0be5 802 if (rl_end && isspace((int)rl_line_buffer[rl_end - 1]))
803 vector_set(vline, NULL);
718e3744 804
ac4d0be5 805 matched = cmd_complete_command(vline, vty, &complete_status);
806 cmd_free_strvec(vline);
807 }
718e3744 808
ac4d0be5 809 if (matched && matched[index])
810 return matched[index++];
718e3744 811
ac4d0be5 812 XFREE(MTYPE_TMP, matched);
813 matched = NULL;
66d29a54 814
ac4d0be5 815 return NULL;
718e3744 816}
817
ac4d0be5 818static char **new_completion(char *text, int start, int end)
718e3744 819{
ac4d0be5 820 char **matches;
718e3744 821
ac4d0be5 822 matches = rl_completion_matches(text, command_generator);
718e3744 823
ac4d0be5 824 if (matches) {
825 rl_point = rl_end;
826 if (complete_status != CMD_COMPLETE_FULL_MATCH)
827 /* only append a space on full match */
828 rl_completion_append_character = '\0';
829 }
718e3744 830
ac4d0be5 831 return matches;
718e3744 832}
833
95e735b5 834/* Vty node structures. */
ac4d0be5 835static struct cmd_node bgp_node = {
836 BGP_NODE, "%s(config-router)# ",
718e3744 837};
838
ac4d0be5 839static struct cmd_node rip_node = {
840 RIP_NODE, "%s(config-router)# ",
718e3744 841};
842
ac4d0be5 843static struct cmd_node isis_node = {
844 ISIS_NODE, "%s(config-router)# ",
c25e458a 845};
846
ac4d0be5 847static struct cmd_node interface_node = {
848 INTERFACE_NODE, "%s(config-if)# ",
718e3744 849};
850
ac4d0be5 851static struct cmd_node pw_node = {
852 PW_NODE, "%s(config-pw)# ",
1a99ca99
RW
853};
854
ac4d0be5 855static struct cmd_node ns_node = {
856 NS_NODE, "%s(config-logical-router)# ",
13460c44
FL
857};
858
ac4d0be5 859static struct cmd_node vrf_node = {
860 VRF_NODE, "%s(config-vrf)# ",
e9d94ea7
DS
861};
862
ac4d0be5 863static struct cmd_node rmap_node = {RMAP_NODE, "%s(config-route-map)# "};
95e735b5 864
ac4d0be5 865static struct cmd_node zebra_node = {ZEBRA_NODE, "%s(config-router)# "};
95e735b5 866
ac4d0be5 867static struct cmd_node bgp_vpnv4_node = {BGP_VPNV4_NODE,
868 "%s(config-router-af)# "};
95e735b5 869
ac4d0be5 870static struct cmd_node bgp_vpnv6_node = {BGP_VPNV6_NODE,
871 "%s(config-router-af)# "};
8ecd3266 872
ac4d0be5 873static struct cmd_node bgp_ipv4_node = {BGP_IPV4_NODE,
874 "%s(config-router-af)# "};
95e735b5 875
ac4d0be5 876static struct cmd_node bgp_ipv4m_node = {BGP_IPV4M_NODE,
877 "%s(config-router-af)# "};
95e735b5 878
ac4d0be5 879static struct cmd_node bgp_ipv6_node = {BGP_IPV6_NODE,
880 "%s(config-router-af)# "};
95e735b5 881
ac4d0be5 882static struct cmd_node bgp_ipv6m_node = {BGP_IPV6M_NODE,
883 "%s(config-router-af)# "};
57b5b7ed 884
ac4d0be5 885static struct cmd_node bgp_evpn_node = {BGP_EVPN_NODE,
886 "%s(config-router-af)# "};
887
888static struct cmd_node bgp_vnc_defaults_node = {
889 BGP_VNC_DEFAULTS_NODE, "%s(config-router-vnc-defaults)# "};
890
891static struct cmd_node bgp_vnc_nve_group_node = {
892 BGP_VNC_NVE_GROUP_NODE, "%s(config-router-vnc-nve-group)# "};
893
894static struct cmd_node bgp_vrf_policy_node = {BGP_VRF_POLICY_NODE,
895 "%s(config-router-vrf-policy)# "};
896
897static struct cmd_node bgp_vnc_l2_group_node = {
898 BGP_VNC_L2_GROUP_NODE, "%s(config-router-vnc-l2-group)# "};
899
900static struct cmd_node ospf_node = {OSPF_NODE, "%s(config-router)# "};
901
902static struct cmd_node ripng_node = {RIPNG_NODE, "%s(config-router)# "};
903
904static struct cmd_node ospf6_node = {OSPF6_NODE, "%s(config-ospf6)# "};
905
906static struct cmd_node ldp_node = {LDP_NODE, "%s(config-ldp)# "};
907
908static struct cmd_node ldp_ipv4_node = {LDP_IPV4_NODE, "%s(config-ldp-af)# "};
909
910static struct cmd_node ldp_ipv6_node = {LDP_IPV6_NODE, "%s(config-ldp-af)# "};
911
912static struct cmd_node ldp_ipv4_iface_node = {LDP_IPV4_IFACE_NODE,
913 "%s(config-ldp-af-if)# "};
914
915static struct cmd_node ldp_ipv6_iface_node = {LDP_IPV6_IFACE_NODE,
916 "%s(config-ldp-af-if)# "};
917
918static struct cmd_node ldp_l2vpn_node = {LDP_L2VPN_NODE, "%s(config-l2vpn)# "};
919
920static struct cmd_node ldp_pseudowire_node = {LDP_PSEUDOWIRE_NODE,
921 "%s(config-l2vpn-pw)# "};
922
923static struct cmd_node keychain_node = {KEYCHAIN_NODE, "%s(config-keychain)# "};
924
925static struct cmd_node keychain_key_node = {KEYCHAIN_KEY_NODE,
926 "%s(config-keychain-key)# "};
927
928struct cmd_node link_params_node = {
929 LINK_PARAMS_NODE, "%s(config-link-params)# ",
14a227b8
PG
930};
931
ac4d0be5 932/* Defined in lib/vty.c */
933extern struct cmd_node vty_node;
934
935/* When '^Z' is received from vty, move down to the enable mode. */
936static int vtysh_end(void)
937{
938 switch (vty->node) {
939 case VIEW_NODE:
940 case ENABLE_NODE:
941 /* Nothing to do. */
942 break;
943 default:
944 vty->node = ENABLE_NODE;
945 break;
946 }
947 return CMD_SUCCESS;
948}
949
950DEFUNSH(VTYSH_REALLYALL, vtysh_end_all, vtysh_end_all_cmd, "end",
951 "End current mode and change to enable mode\n")
65efcfce 952{
ac4d0be5 953 return vtysh_end();
954}
65efcfce 955
ac4d0be5 956DEFUNSH(VTYSH_BGPD, router_bgp, router_bgp_cmd,
957 "router bgp [(1-4294967295) [<view|vrf> WORD]]",
958 ROUTER_STR BGP_STR AS_STR
959 "BGP view\nBGP VRF\n"
960 "View/VRF name\n")
65efcfce 961{
ac4d0be5 962 vty->node = BGP_NODE;
963 return CMD_SUCCESS;
964}
65efcfce 965
ac4d0be5 966DEFUNSH(VTYSH_BGPD, address_family_vpnv4, address_family_vpnv4_cmd,
967 "address-family vpnv4 [unicast]",
968 "Enter Address Family command mode\n"
969 "Address Family\n"
970 "Address Family Modifier\n")
971{
972 vty->node = BGP_VPNV4_NODE;
973 return CMD_SUCCESS;
974}
5ff06872 975
ac4d0be5 976DEFUNSH(VTYSH_BGPD, address_family_vpnv6, address_family_vpnv6_cmd,
977 "address-family vpnv6 [unicast]",
978 "Enter Address Family command mode\n"
979 "Address Family\n"
980 "Address Family Modifier\n")
65efcfce 981{
ac4d0be5 982 vty->node = BGP_VPNV6_NODE;
983 return CMD_SUCCESS;
984}
65efcfce 985
ac4d0be5 986DEFUNSH(VTYSH_BGPD, address_family_ipv4, address_family_ipv4_cmd,
987 "address-family ipv4 [unicast]",
988 "Enter Address Family command mode\n"
989 "Address Family\n"
990 "Address Family Modifier\n")
95e735b5 991{
ac4d0be5 992 vty->node = BGP_IPV4_NODE;
993 return CMD_SUCCESS;
994}
95e735b5 995
ac4d0be5 996DEFUNSH(VTYSH_BGPD, address_family_ipv4_multicast,
997 address_family_ipv4_multicast_cmd, "address-family ipv4 multicast",
998 "Enter Address Family command mode\n"
999 "Address Family\n"
1000 "Address Family modifier\n")
95e735b5 1001{
ac4d0be5 1002 vty->node = BGP_IPV4M_NODE;
1003 return CMD_SUCCESS;
1004}
95e735b5 1005
ac4d0be5 1006DEFUNSH(VTYSH_BGPD, address_family_ipv4_vpn, address_family_ipv4_vpn_cmd,
1007 "address-family ipv4 vpn",
1008 "Enter Address Family command mode\n"
1009 "Address Family\n"
1010 "Address Family modifier\n")
95e735b5 1011{
ac4d0be5 1012 vty->node = BGP_VPNV4_NODE;
1013 return CMD_SUCCESS;
1014}
95e735b5 1015
ac4d0be5 1016DEFUNSH(VTYSH_BGPD, address_family_ipv6, address_family_ipv6_cmd,
1017 "address-family ipv6 [unicast]",
1018 "Enter Address Family command mode\n"
1019 "Address Family\n"
1020 "Address Family modifier\n")
4fcbf6e2 1021{
ac4d0be5 1022 vty->node = BGP_IPV6_NODE;
1023 return CMD_SUCCESS;
1024}
4fcbf6e2 1025
ac4d0be5 1026DEFUNSH(VTYSH_BGPD, address_family_ipv6_multicast,
1027 address_family_ipv6_multicast_cmd, "address-family ipv6 multicast",
1028 "Enter Address Family command mode\n"
1029 "Address Family\n"
1030 "Address Family modifier\n")
4fcbf6e2 1031{
ac4d0be5 1032 vty->node = BGP_IPV6M_NODE;
1033 return CMD_SUCCESS;
1034}
4fcbf6e2 1035
ac4d0be5 1036DEFUNSH(VTYSH_BGPD, address_family_ipv6_vpn, address_family_ipv6_vpn_cmd,
1037 "address-family ipv6 vpn",
1038 "Enter Address Family command mode\n"
1039 "Address Family\n"
1040 "Address Family modifier\n")
4fcbf6e2 1041{
ac4d0be5 1042 vty->node = BGP_VPNV6_NODE;
1043 return CMD_SUCCESS;
1044}
4fcbf6e2 1045
ac4d0be5 1046DEFUNSH(VTYSH_BGPD, address_family_evpn, address_family_evpn_cmd,
1047 "address-family <l2vpn evpn>",
1048 "Enter Address Family command mode\n"
1049 "EVPN Address family\n"
1050 "Layer2 VPN Address family\n"
1051 "Ethernet Virtual Private Network Subsequent Address Family\n")
4fcbf6e2 1052{
ac4d0be5 1053 vty->node = BGP_EVPN_NODE;
1054 return CMD_SUCCESS;
1055}
4fcbf6e2 1056
ac4d0be5 1057#if defined(ENABLE_BGP_VNC)
1058DEFUNSH(VTYSH_BGPD, vnc_defaults, vnc_defaults_cmd, "vnc defaults",
1059 "VNC/RFP related configuration\n"
1060 "Configure default NVE group\n")
4fcbf6e2 1061{
ac4d0be5 1062 vty->node = BGP_VNC_DEFAULTS_NODE;
1063 return CMD_SUCCESS;
1064}
4fcbf6e2 1065
ac4d0be5 1066DEFUNSH(VTYSH_BGPD, vnc_nve_group, vnc_nve_group_cmd, "vnc nve-group NAME",
1067 "VNC/RFP related configuration\n"
1068 "Configure a NVE group\n"
1069 "Group name\n")
4fcbf6e2 1070{
ac4d0be5 1071 vty->node = BGP_VNC_NVE_GROUP_NODE;
1072 return CMD_SUCCESS;
1073}
4fcbf6e2 1074
ac4d0be5 1075DEFUNSH(VTYSH_BGPD, vnc_vrf_policy, vnc_vrf_policy_cmd, "vrf-policy NAME",
1076 "Configure a VRF policy group\n"
1077 "Group name\n")
4fcbf6e2 1078{
ac4d0be5 1079 vty->node = BGP_VRF_POLICY_NODE;
1080 return CMD_SUCCESS;
1081}
4fcbf6e2 1082
ac4d0be5 1083DEFUNSH(VTYSH_BGPD, vnc_l2_group, vnc_l2_group_cmd, "vnc l2-group NAME",
1084 "VNC/RFP related configuration\n"
1085 "Configure a L2 group\n"
1086 "Group name\n")
95e735b5 1087{
ac4d0be5 1088 vty->node = BGP_VNC_L2_GROUP_NODE;
1089 return CMD_SUCCESS;
1090}
1091#endif
95e735b5 1092
ac4d0be5 1093DEFUNSH(VTYSH_RIPD, key_chain, key_chain_cmd, "key chain WORD",
1094 "Authentication key management\n"
1095 "Key-chain management\n"
1096 "Key-chain name\n")
95e735b5 1097{
ac4d0be5 1098 vty->node = KEYCHAIN_NODE;
1099 return CMD_SUCCESS;
1100}
95e735b5 1101
ac4d0be5 1102DEFUNSH(VTYSH_RIPD, key, key_cmd, "key (0-2147483647)",
1103 "Configure a key\n"
1104 "Key identifier number\n")
16f1b9ee 1105{
ac4d0be5 1106 vty->node = KEYCHAIN_KEY_NODE;
1107 return CMD_SUCCESS;
1108}
16f1b9ee 1109
ac4d0be5 1110DEFUNSH(VTYSH_RIPD, router_rip, router_rip_cmd, "router rip",
1111 ROUTER_STR "RIP\n")
1112{
1113 vty->node = RIP_NODE;
1114 return CMD_SUCCESS;
1115}
e7168df4 1116
ac4d0be5 1117DEFUNSH(VTYSH_RIPNGD, router_ripng, router_ripng_cmd, "router ripng",
1118 ROUTER_STR "RIPng\n")
718e3744 1119{
ac4d0be5 1120 vty->node = RIPNG_NODE;
1121 return CMD_SUCCESS;
1122}
1123
1124DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd, "router ospf [(1-65535)]",
1125 "Enable a routing process\n"
1126 "Start OSPF configuration\n"
1127 "Instance ID\n")
718e3744 1128{
ac4d0be5 1129 vty->node = OSPF_NODE;
1130 return CMD_SUCCESS;
39530dfe 1131}
c7f1274b 1132
ac4d0be5 1133DEFUNSH(VTYSH_OSPF6D, router_ospf6, router_ospf6_cmd, "router ospf6",
1134 ROUTER_STR OSPF6_STR)
39530dfe 1135{
ac4d0be5 1136 vty->node = OSPF6_NODE;
1137 return CMD_SUCCESS;
39530dfe 1138}
718e3744 1139
ac4d0be5 1140#if defined(HAVE_LDPD)
1141DEFUNSH(VTYSH_LDPD, ldp_mpls_ldp, ldp_mpls_ldp_cmd, "mpls ldp",
1142 "Global MPLS configuration subcommands\n"
1143 "Label Distribution Protocol\n")
39530dfe 1144{
ac4d0be5 1145 vty->node = LDP_NODE;
1146 return CMD_SUCCESS;
57b5b7ed 1147}
1148
ac4d0be5 1149DEFUNSH(VTYSH_LDPD, ldp_address_family_ipv4, ldp_address_family_ipv4_cmd,
1150 "address-family ipv4",
1151 "Configure Address Family and its parameters\n"
1152 "IPv4\n")
14a227b8 1153{
ac4d0be5 1154 vty->node = LDP_IPV4_NODE;
1155 return CMD_SUCCESS;
14a227b8
PG
1156}
1157
ac4d0be5 1158DEFUNSH(VTYSH_LDPD, ldp_address_family_ipv6, ldp_address_family_ipv6_cmd,
1159 "address-family ipv6",
1160 "Configure Address Family and its parameters\n"
1161 "IPv6\n")
65efcfce 1162{
ac4d0be5 1163 vty->node = LDP_IPV6_NODE;
1164 return CMD_SUCCESS;
65efcfce
LB
1165}
1166
ac4d0be5 1167DEFUNSH(VTYSH_LDPD, ldp_interface_ifname, ldp_interface_ifname_cmd,
1168 "interface IFNAME",
1169 "Enable LDP on an interface and enter interface submode\n"
1170 "Interface's name\n")
65efcfce 1171{
ac4d0be5 1172 switch (vty->node) {
1173 case LDP_IPV4_NODE:
1174 vty->node = LDP_IPV4_IFACE_NODE;
1175 break;
1176 case LDP_IPV6_NODE:
1177 vty->node = LDP_IPV6_IFACE_NODE;
1178 break;
1179 default:
1180 break;
1181 }
1182
1183 return CMD_SUCCESS;
65efcfce
LB
1184}
1185
ac4d0be5 1186DEFUNSH(VTYSH_LDPD, ldp_l2vpn_word_type_vpls, ldp_l2vpn_word_type_vpls_cmd,
1187 "l2vpn WORD type vpls",
1188 "Configure l2vpn commands\n"
1189 "L2VPN name\n"
1190 "L2VPN type\n"
1191 "Virtual Private LAN Service\n")
5ff06872 1192{
ac4d0be5 1193 vty->node = LDP_L2VPN_NODE;
1194 return CMD_SUCCESS;
5ff06872
LB
1195}
1196
ac4d0be5 1197DEFUNSH(VTYSH_LDPD, ldp_member_pseudowire_ifname,
1198 ldp_member_pseudowire_ifname_cmd, "member pseudowire IFNAME",
1199 "L2VPN member configuration\n"
1200 "Pseudowire interface\n"
1201 "Interface's name\n")
65efcfce 1202{
ac4d0be5 1203 vty->node = LDP_PSEUDOWIRE_NODE;
1204 return CMD_SUCCESS;
65efcfce 1205}
87ab4aec 1206#endif
65efcfce 1207
ac4d0be5 1208DEFUNSH(VTYSH_ISISD, router_isis, router_isis_cmd, "router isis WORD",
1209 ROUTER_STR
1210 "ISO IS-IS\n"
1211 "ISO Routing area tag")
1212{
1213 vty->node = ISIS_NODE;
1214 return CMD_SUCCESS;
1215}
1216
1217DEFUNSH(VTYSH_RMAP, vtysh_route_map, vtysh_route_map_cmd,
1218 "route-map WORD <deny|permit> (1-65535)",
1219 "Create route-map or enter route-map command mode\n"
1220 "Route map tag\n"
1221 "Route map denies set operations\n"
1222 "Route map permits set operations\n"
1223 "Sequence to insert to/delete from existing route-map entry\n")
1224{
1225 vty->node = RMAP_NODE;
1226 return CMD_SUCCESS;
1227}
1228
1229DEFUNSH(VTYSH_ALL, vtysh_line_vty, vtysh_line_vty_cmd, "line vty",
1230 "Configure a terminal line\n"
1231 "Virtual terminal\n")
1232{
1233 vty->node = VTY_NODE;
1234 return CMD_SUCCESS;
1235}
1236
1237DEFUNSH(VTYSH_REALLYALL, vtysh_enable, vtysh_enable_cmd, "enable",
1238 "Turn on privileged mode command\n")
1239{
1240 vty->node = ENABLE_NODE;
1241 return CMD_SUCCESS;
1242}
1243
1244DEFUNSH(VTYSH_REALLYALL, vtysh_disable, vtysh_disable_cmd, "disable",
1245 "Turn off privileged mode command\n")
1246{
1247 if (vty->node == ENABLE_NODE)
1248 vty->node = VIEW_NODE;
1249 return CMD_SUCCESS;
1250}
1251
1252DEFUNSH(VTYSH_REALLYALL, vtysh_config_terminal, vtysh_config_terminal_cmd,
1253 "configure terminal",
1254 "Configuration from vty interface\n"
1255 "Configuration terminal\n")
1256{
1257 vty->node = CONFIG_NODE;
1258 return CMD_SUCCESS;
1259}
1260
1261static int vtysh_exit(struct vty *vty)
1262{
1263 switch (vty->node) {
1264 case VIEW_NODE:
1265 case ENABLE_NODE:
1266 exit(0);
1267 break;
1268 case CONFIG_NODE:
1269 vty->node = ENABLE_NODE;
1270 break;
1271 case INTERFACE_NODE:
1272 case PW_NODE:
1273 case NS_NODE:
1274 case VRF_NODE:
1275 case ZEBRA_NODE:
1276 case BGP_NODE:
1277 case RIP_NODE:
1278 case RIPNG_NODE:
1279 case OSPF_NODE:
1280 case OSPF6_NODE:
1281 case LDP_NODE:
1282 case LDP_L2VPN_NODE:
1283 case ISIS_NODE:
1284 case MASC_NODE:
1285 case RMAP_NODE:
1286 case VTY_NODE:
1287 case KEYCHAIN_NODE:
1288 vtysh_execute("end");
1289 vtysh_execute("configure terminal");
1290 vty->node = CONFIG_NODE;
1291 break;
1292 case BGP_VPNV4_NODE:
1293 case BGP_VPNV6_NODE:
1294 case BGP_IPV4_NODE:
1295 case BGP_IPV4M_NODE:
1296 case BGP_IPV6_NODE:
1297 case BGP_IPV6M_NODE:
1298 case BGP_VRF_POLICY_NODE:
1299 case BGP_EVPN_NODE:
1300 case BGP_VNC_DEFAULTS_NODE:
1301 case BGP_VNC_NVE_GROUP_NODE:
1302 case BGP_VNC_L2_GROUP_NODE:
1303 vty->node = BGP_NODE;
1304 break;
1305 case LDP_IPV4_NODE:
1306 case LDP_IPV6_NODE:
1307 vty->node = LDP_NODE;
1308 break;
1309 case LDP_IPV4_IFACE_NODE:
1310 vty->node = LDP_IPV4_NODE;
1311 break;
1312 case LDP_IPV6_IFACE_NODE:
1313 vty->node = LDP_IPV6_NODE;
1314 break;
1315 case LDP_PSEUDOWIRE_NODE:
1316 vty->node = LDP_L2VPN_NODE;
1317 break;
1318 case KEYCHAIN_KEY_NODE:
1319 vty->node = KEYCHAIN_NODE;
1320 break;
1321 case LINK_PARAMS_NODE:
1322 vty->node = INTERFACE_NODE;
1323 break;
1324 default:
1325 break;
1326 }
1327 return CMD_SUCCESS;
1328}
1329
1330DEFUNSH(VTYSH_REALLYALL, vtysh_exit_all, vtysh_exit_all_cmd, "exit",
1331 "Exit current mode and down to previous mode\n")
718e3744 1332{
ac4d0be5 1333 return vtysh_exit(vty);
1334}
718e3744 1335
ac4d0be5 1336DEFUNSH(VTYSH_ALL, vtysh_quit_all, vtysh_quit_all_cmd, "quit",
1337 "Exit current mode and down to previous mode\n")
1338{
1339 return vtysh_exit_all(self, vty, argc, argv);
1340}
4fcbf6e2 1341
ac4d0be5 1342DEFUNSH(VTYSH_BGPD, exit_address_family, exit_address_family_cmd,
1343 "exit-address-family", "Exit from Address Family configuration mode\n")
1344{
1345 if (vty->node == BGP_IPV4_NODE || vty->node == BGP_IPV4M_NODE
1346 || vty->node == BGP_VPNV4_NODE || vty->node == BGP_VPNV6_NODE
1347 || vty->node == BGP_IPV6_NODE || vty->node == BGP_IPV6M_NODE)
1348 vty->node = BGP_NODE;
1349 return CMD_SUCCESS;
4fcbf6e2 1350}
ac4d0be5 1351
1352DEFUNSH(VTYSH_BGPD, exit_vnc_config, exit_vnc_config_cmd, "exit-vnc",
1353 "Exit from VNC configuration mode\n")
4fcbf6e2 1354{
ac4d0be5 1355 if (vty->node == BGP_VNC_DEFAULTS_NODE
1356 || vty->node == BGP_VNC_NVE_GROUP_NODE
1357 || vty->node == BGP_VNC_L2_GROUP_NODE)
1358 vty->node = BGP_NODE;
1359 return CMD_SUCCESS;
4fcbf6e2
RW
1360}
1361
ac4d0be5 1362DEFUNSH(VTYSH_BGPD, exit_vrf_policy, exit_vrf_policy_cmd, "exit-vrf-policy",
1363 "Exit from VRF configuration mode\n")
1364{
1365 if (vty->node == BGP_VRF_POLICY_NODE)
1366 vty->node = BGP_NODE;
1367 return CMD_SUCCESS;
5ff06872
LB
1368}
1369
ac4d0be5 1370DEFUNSH(VTYSH_RIPD, vtysh_exit_ripd, vtysh_exit_ripd_cmd, "exit",
1371 "Exit current mode and down to previous mode\n")
718e3744 1372{
ac4d0be5 1373 return vtysh_exit(vty);
718e3744 1374}
1375
ac4d0be5 1376DEFUNSH(VTYSH_RIPD, vtysh_quit_ripd, vtysh_quit_ripd_cmd, "quit",
1377 "Exit current mode and down to previous mode\n")
a98d33ab 1378{
ac4d0be5 1379 return vtysh_exit_ripd(self, vty, argc, argv);
a98d33ab 1380}
718e3744 1381
ac4d0be5 1382DEFUNSH(VTYSH_RIPNGD, vtysh_exit_ripngd, vtysh_exit_ripngd_cmd, "exit",
1383 "Exit current mode and down to previous mode\n")
68980084 1384{
ac4d0be5 1385 return vtysh_exit(vty);
68980084 1386}
1387
ac4d0be5 1388DEFUNSH(VTYSH_RIPNGD, vtysh_quit_ripngd, vtysh_quit_ripngd_cmd, "quit",
1389 "Exit current mode and down to previous mode\n")
a98d33ab 1390{
ac4d0be5 1391 return vtysh_exit_ripngd(self, vty, argc, argv);
a98d33ab 1392}
68980084 1393
ac4d0be5 1394DEFUNSH(VTYSH_RMAP, vtysh_exit_rmap, vtysh_exit_rmap_cmd, "exit",
1395 "Exit current mode and down to previous mode\n")
718e3744 1396{
ac4d0be5 1397 return vtysh_exit(vty);
718e3744 1398}
1399
ac4d0be5 1400DEFUNSH(VTYSH_RMAP, vtysh_quit_rmap, vtysh_quit_rmap_cmd, "quit",
1401 "Exit current mode and down to previous mode\n")
a98d33ab 1402{
ac4d0be5 1403 return vtysh_exit_rmap(self, vty, argc, argv);
a98d33ab 1404}
718e3744 1405
ac4d0be5 1406DEFUNSH(VTYSH_BGPD, vtysh_exit_bgpd, vtysh_exit_bgpd_cmd, "exit",
1407 "Exit current mode and down to previous mode\n")
718e3744 1408{
ac4d0be5 1409 return vtysh_exit(vty);
718e3744 1410}
1411
ac4d0be5 1412DEFUNSH(VTYSH_BGPD, vtysh_quit_bgpd, vtysh_quit_bgpd_cmd, "quit",
1413 "Exit current mode and down to previous mode\n")
a98d33ab 1414{
ac4d0be5 1415 return vtysh_exit_bgpd(self, vty, argc, argv);
a98d33ab 1416}
718e3744 1417
ac4d0be5 1418DEFUNSH(VTYSH_OSPFD, vtysh_exit_ospfd, vtysh_exit_ospfd_cmd, "exit",
1419 "Exit current mode and down to previous mode\n")
718e3744 1420{
ac4d0be5 1421 return vtysh_exit(vty);
718e3744 1422}
1423
ac4d0be5 1424DEFUNSH(VTYSH_OSPFD, vtysh_quit_ospfd, vtysh_quit_ospfd_cmd, "quit",
1425 "Exit current mode and down to previous mode\n")
a98d33ab 1426{
ac4d0be5 1427 return vtysh_exit_ospfd(self, vty, argc, argv);
a98d33ab 1428}
718e3744 1429
ac4d0be5 1430DEFUNSH(VTYSH_OSPF6D, vtysh_exit_ospf6d, vtysh_exit_ospf6d_cmd, "exit",
1431 "Exit current mode and down to previous mode\n")
68980084 1432{
ac4d0be5 1433 return vtysh_exit(vty);
68980084 1434}
1435
ac4d0be5 1436DEFUNSH(VTYSH_OSPF6D, vtysh_quit_ospf6d, vtysh_quit_ospf6d_cmd, "quit",
1437 "Exit current mode and down to previous mode\n")
a98d33ab 1438{
ac4d0be5 1439 return vtysh_exit_ospf6d(self, vty, argc, argv);
a98d33ab 1440}
68980084 1441
ac4d0be5 1442#if defined(HAVE_LDPD)
1443DEFUNSH(VTYSH_LDPD, vtysh_exit_ldpd, vtysh_exit_ldpd_cmd, "exit",
1444 "Exit current mode and down to previous mode\n")
4fcbf6e2 1445{
ac4d0be5 1446 return vtysh_exit(vty);
4fcbf6e2
RW
1447}
1448
ac4d0be5 1449ALIAS(vtysh_exit_ldpd, vtysh_quit_ldpd_cmd, "quit",
1450 "Exit current mode and down to previous mode\n")
87ab4aec 1451#endif
4fcbf6e2 1452
ac4d0be5 1453DEFUNSH(VTYSH_ISISD, vtysh_exit_isisd, vtysh_exit_isisd_cmd, "exit",
1454 "Exit current mode and down to previous mode\n")
c25e458a 1455{
ac4d0be5 1456 return vtysh_exit(vty);
c25e458a 1457}
1458
ac4d0be5 1459DEFUNSH(VTYSH_ISISD, vtysh_quit_isisd, vtysh_quit_isisd_cmd, "quit",
1460 "Exit current mode and down to previous mode\n")
a98d33ab 1461{
ac4d0be5 1462 return vtysh_exit_isisd(self, vty, argc, argv);
a98d33ab 1463}
c25e458a 1464
ac4d0be5 1465DEFUNSH(VTYSH_ALL, vtysh_exit_line_vty, vtysh_exit_line_vty_cmd, "exit",
1466 "Exit current mode and down to previous mode\n")
e7168df4 1467{
ac4d0be5 1468 return vtysh_exit(vty);
e7168df4 1469}
1470
ac4d0be5 1471DEFUNSH(VTYSH_ALL, vtysh_quit_line_vty, vtysh_quit_line_vty_cmd, "quit",
1472 "Exit current mode and down to previous mode\n")
a98d33ab 1473{
ac4d0be5 1474 return vtysh_exit_line_vty(self, vty, argc, argv);
a98d33ab 1475}
e7168df4 1476
ac4d0be5 1477DEFUNSH(VTYSH_INTERFACE, vtysh_interface, vtysh_interface_cmd,
1478 "interface IFNAME [vrf NAME]",
1479 "Select an interface to configure\n"
1480 "Interface's name\n" VRF_CMD_HELP_STR)
718e3744 1481{
ac4d0be5 1482 vty->node = INTERFACE_NODE;
1483 return CMD_SUCCESS;
718e3744 1484}
1485
ac4d0be5 1486DEFUNSH(VTYSH_ZEBRA, vtysh_pseudowire, vtysh_pseudowire_cmd,
1487 "pseudowire IFNAME",
1488 "Static pseudowire configuration\n"
1489 "Pseudowire name\n")
1a99ca99 1490{
ac4d0be5 1491 vty->node = PW_NODE;
1492 return CMD_SUCCESS;
1a99ca99
RW
1493}
1494
95e735b5 1495/* TODO Implement "no interface command in isisd. */
ac4d0be5 1496DEFSH(VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_OSPFD | VTYSH_OSPF6D,
1497 vtysh_no_interface_cmd, "no interface IFNAME", NO_STR
1498 "Delete a pseudo interface's configuration\n"
1499 "Interface's name\n")
32d2463c 1500
ac4d0be5 1501DEFSH(VTYSH_ZEBRA, vtysh_no_interface_vrf_cmd, "no interface IFNAME vrf NAME",
1502 NO_STR
1503 "Delete a pseudo interface's configuration\n"
1504 "Interface's name\n" VRF_CMD_HELP_STR)
cd2a8a42 1505
ac4d0be5 1506DEFUNSH(VTYSH_NS, vtysh_ns, vtysh_ns_cmd, "logical-router (1-65535) ns NAME",
1507 "Enable a logical-router\n"
1508 "Specify the logical-router indentifier\n"
1509 "The Name Space\n"
1510 "The file name in " NS_RUN_DIR ", or a full pathname\n")
13460c44 1511{
ac4d0be5 1512 vty->node = NS_NODE;
1513 return CMD_SUCCESS;
13460c44
FL
1514}
1515
ac4d0be5 1516DEFUNSH(VTYSH_VRF, vtysh_vrf, vtysh_vrf_cmd, "vrf NAME",
1517 "Select a VRF to configure\n"
1518 "VRF's name\n")
e9d94ea7 1519{
ac4d0be5 1520 vty->node = VRF_NODE;
1521 return CMD_SUCCESS;
e9d94ea7
DS
1522}
1523
ac4d0be5 1524DEFSH(VTYSH_ZEBRA, vtysh_no_vrf_cmd, "no vrf NAME", NO_STR
1525 "Delete a pseudo vrf's configuration\n"
1526 "VRF's name\n")
e9d94ea7 1527
ac4d0be5 1528DEFUNSH(VTYSH_NS, vtysh_exit_ns, vtysh_exit_ns_cmd, "exit",
1529 "Exit current mode and down to previous mode\n")
13460c44 1530{
ac4d0be5 1531 return vtysh_exit(vty);
13460c44
FL
1532}
1533
ac4d0be5 1534DEFUNSH(VTYSH_NS, vtysh_quit_ns, vtysh_quit_ns_cmd, "quit",
1535 "Exit current mode and down to previous mode\n")
a98d33ab 1536{
ac4d0be5 1537 return vtysh_exit_ns(self, vty, argc, argv);
a98d33ab 1538}
13460c44 1539
ac4d0be5 1540DEFUNSH(VTYSH_VRF, vtysh_exit_vrf, vtysh_exit_vrf_cmd, "exit",
1541 "Exit current mode and down to previous mode\n")
e9d94ea7 1542{
ac4d0be5 1543 return vtysh_exit(vty);
e9d94ea7
DS
1544}
1545
ac4d0be5 1546DEFUNSH(VTYSH_VRF, vtysh_quit_vrf, vtysh_quit_vrf_cmd, "quit",
1547 "Exit current mode and down to previous mode\n")
a98d33ab 1548{
ac4d0be5 1549 return vtysh_exit_vrf(self, vty, argc, argv);
a98d33ab 1550}
e9d94ea7 1551
95e735b5 1552/* TODO Implement interface description commands in ripngd, ospf6d
1553 * and isisd. */
ac4d0be5 1554DEFSH(VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_OSPFD, vtysh_interface_desc_cmd,
1555 "description LINE...",
1556 "Interface specific description\n"
1557 "Characters describing this interface\n")
338a9916 1558
ac4d0be5 1559DEFSH(VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_OSPFD, vtysh_no_interface_desc_cmd,
1560 "no description", NO_STR "Interface specific description\n")
1561
1562DEFUNSH(VTYSH_INTERFACE, vtysh_exit_interface, vtysh_exit_interface_cmd, "exit",
1563 "Exit current mode and down to previous mode\n")
718e3744 1564{
ac4d0be5 1565 return vtysh_exit(vty);
718e3744 1566}
1567
ac4d0be5 1568DEFUNSH(VTYSH_INTERFACE, vtysh_quit_interface, vtysh_quit_interface_cmd, "quit",
1569 "Exit current mode and down to previous mode\n")
a98d33ab 1570{
ac4d0be5 1571 return vtysh_exit_interface(self, vty, argc, argv);
a98d33ab 1572}
718e3744 1573
0f69b58c
DS
1574DEFUN (vtysh_show_thread,
1575 vtysh_show_thread_cmd,
1576 "show thread cpu [FILTER]",
1577 SHOW_STR
1578 "Thread information\n"
1579 "Thread CPU usage\n"
1580 "Display filter (rwtexb)\n")
1581{
ac4d0be5 1582 int idx_filter = 3;
1583 unsigned int i;
1584 int ret = CMD_SUCCESS;
1585 char line[100];
0f69b58c 1586
ac4d0be5 1587 sprintf(line, "show thread cpu %s\n",
1588 (argc == 4) ? argv[idx_filter]->arg : "");
1589 for (i = 0; i < array_size(vtysh_client); i++)
1590 if (vtysh_client[i].fd >= 0) {
1591 fprintf(stdout, "Thread statistics for %s:\n",
1592 vtysh_client[i].name);
1593 ret = vtysh_client_execute(&vtysh_client[i], line,
1594 stdout);
1595 fprintf(stdout, "\n");
1596 }
1597 return ret;
0f69b58c
DS
1598}
1599
1600DEFUN (vtysh_show_work_queues,
1601 vtysh_show_work_queues_cmd,
1602 "show work-queues",
1603 SHOW_STR
1604 "Work Queue information\n")
1605{
ac4d0be5 1606 unsigned int i;
1607 int ret = CMD_SUCCESS;
1608 char line[] = "show work-queues\n";
0f69b58c 1609
ac4d0be5 1610 for (i = 0; i < array_size(vtysh_client); i++)
1611 if (vtysh_client[i].fd >= 0) {
1612 fprintf(stdout, "Work queue statistics for %s:\n",
1613 vtysh_client[i].name);
1614 ret = vtysh_client_execute(&vtysh_client[i], line,
1615 stdout);
1616 fprintf(stdout, "\n");
1617 }
0f69b58c 1618
ac4d0be5 1619 return ret;
0f69b58c
DS
1620}
1621
b47b0a84
DS
1622DEFUN (vtysh_show_work_queues_daemon,
1623 vtysh_show_work_queues_daemon_cmd,
6147e2c6 1624 "show work-queues <zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd>",
b47b0a84
DS
1625 SHOW_STR
1626 "Work Queue information\n"
1627 "For the zebra daemon\n"
1628 "For the rip daemon\n"
1629 "For the ripng daemon\n"
1630 "For the ospf daemon\n"
1631 "For the ospfv6 daemon\n"
1632 "For the bgp daemon\n"
1633 "For the isis daemon\n")
1634{
ac4d0be5 1635 int idx_protocol = 2;
1636 unsigned int i;
1637 int ret = CMD_SUCCESS;
b47b0a84 1638
ac4d0be5 1639 for (i = 0; i < array_size(vtysh_client); i++) {
1640 if (strmatch(vtysh_client[i].name, argv[idx_protocol]->text))
1641 break;
1642 }
b47b0a84 1643
ac4d0be5 1644 ret = vtysh_client_execute(&vtysh_client[i], "show work-queues\n",
1645 stdout);
b47b0a84 1646
ac4d0be5 1647 return ret;
b47b0a84
DS
1648}
1649
ac4d0be5 1650DEFUNSH(VTYSH_ZEBRA, vtysh_link_params, vtysh_link_params_cmd, "link-params",
1651 LINK_PARAMS_STR)
16f1b9ee 1652{
ac4d0be5 1653 vty->node = LINK_PARAMS_NODE;
1654 return CMD_SUCCESS;
16f1b9ee
OD
1655}
1656
ac4d0be5 1657DEFUNSH(VTYSH_ZEBRA, exit_link_params, exit_link_params_cmd, "exit-link-params",
1658 "Exit from Link Params configuration node\n")
03f99d9a 1659{
ac4d0be5 1660 if (vty->node == LINK_PARAMS_NODE)
1661 vty->node = INTERFACE_NODE;
1662 return CMD_SUCCESS;
03f99d9a
DS
1663}
1664
ac4d0be5 1665static int show_per_daemon(const char *line, const char *headline)
362b4031 1666{
ac4d0be5 1667 unsigned int i;
1668 int ret = CMD_SUCCESS;
2a8e27af 1669
ac4d0be5 1670 for (i = 0; i < array_size(vtysh_client); i++)
1671 if (vtysh_client[i].fd >= 0) {
1672 fprintf(stdout, headline, vtysh_client[i].name);
1673 ret = vtysh_client_execute(&vtysh_client[i], line,
1674 stdout);
1675 fprintf(stdout, "\n");
1676 }
2a8e27af 1677
ac4d0be5 1678 return ret;
362b4031
PJ
1679}
1680
2a8e27af
DL
1681/* Memory */
1682DEFUN (vtysh_show_memory,
1683 vtysh_show_memory_cmd,
1684 "show memory",
1685 SHOW_STR
1686 "Memory statistics\n")
1687{
ac4d0be5 1688 return show_per_daemon("show memory\n", "Memory statistics for %s:\n");
2a8e27af
DL
1689}
1690
1691DEFUN (vtysh_show_modules,
1692 vtysh_show_modules_cmd,
1693 "show modules",
1694 SHOW_STR
1695 "Loaded modules\n")
1696{
ac4d0be5 1697 return show_per_daemon("show modules\n",
1698 "Module information for %s:\n");
2a8e27af
DL
1699}
1700
95e735b5 1701/* Logging commands. */
dbf7d13d
PJ
1702DEFUN (vtysh_show_logging,
1703 vtysh_show_logging_cmd,
1704 "show logging",
1705 SHOW_STR
1706 "Show current logging configuration\n")
1707{
ac4d0be5 1708 unsigned int i;
1709 int ret = CMD_SUCCESS;
1710 char line[] = "show logging\n";
1711
1712 for (i = 0; i < array_size(vtysh_client); i++)
1713 if (vtysh_client[i].fd >= 0) {
1714 fprintf(stdout, "Logging configuration for %s:\n",
1715 vtysh_client[i].name);
1716 ret = vtysh_client_execute(&vtysh_client[i], line,
1717 stdout);
1718 fprintf(stdout, "\n");
1719 }
1720
1721 return ret;
1722}
1723
1724DEFUNSH(VTYSH_ALL, vtysh_log_stdout, vtysh_log_stdout_cmd, "log stdout",
1725 "Logging control\n"
1726 "Set stdout logging level\n")
1727{
1728 return CMD_SUCCESS;
1729}
1730
1731DEFUNSH(VTYSH_ALL, vtysh_log_stdout_level, vtysh_log_stdout_level_cmd,
1732 "log stdout <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
1733 "Logging control\n"
1734 "Set stdout logging level\n" LOG_LEVEL_DESC)
95e735b5 1735{
ac4d0be5 1736 return CMD_SUCCESS;
1737}
1738
1739DEFUNSH(VTYSH_ALL, no_vtysh_log_stdout, no_vtysh_log_stdout_cmd,
1740 "no log stdout [LEVEL]", NO_STR
1741 "Logging control\n"
1742 "Cancel logging to stdout\n"
1743 "Logging level\n")
95e735b5 1744{
ac4d0be5 1745 return CMD_SUCCESS;
95e735b5 1746}
1747
ac4d0be5 1748DEFUNSH(VTYSH_ALL, vtysh_log_file, vtysh_log_file_cmd, "log file FILENAME",
1749 "Logging control\n"
1750 "Logging to file\n"
1751 "Logging filename\n")
95e735b5 1752{
ac4d0be5 1753 return CMD_SUCCESS;
95e735b5 1754}
1755
ac4d0be5 1756DEFUNSH(VTYSH_ALL, vtysh_log_file_level, vtysh_log_file_level_cmd,
1757 "log file FILENAME <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
1758 "Logging control\n"
1759 "Logging to file\n"
1760 "Logging filename\n" LOG_LEVEL_DESC)
274a4a44 1761{
ac4d0be5 1762 return CMD_SUCCESS;
274a4a44 1763}
1764
ac4d0be5 1765DEFUNSH(VTYSH_ALL, no_vtysh_log_file, no_vtysh_log_file_cmd,
1766 "no log file [FILENAME [LEVEL]]", NO_STR
1767 "Logging control\n"
1768 "Cancel logging to file\n"
1769 "Logging file name\n"
1770 "Logging level\n")
95e735b5 1771{
ac4d0be5 1772 return CMD_SUCCESS;
95e735b5 1773}
1774
ac4d0be5 1775DEFUNSH(VTYSH_ALL, vtysh_log_monitor, vtysh_log_monitor_cmd,
1776 "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
1777 "Logging control\n"
1778 "Set terminal line (monitor) logging level\n" LOG_LEVEL_DESC)
274a4a44 1779{
ac4d0be5 1780 return CMD_SUCCESS;
274a4a44 1781}
1782
ac4d0be5 1783DEFUNSH(VTYSH_ALL, no_vtysh_log_monitor, no_vtysh_log_monitor_cmd,
1784 "no log monitor [LEVEL]", NO_STR
1785 "Logging control\n"
1786 "Disable terminal line (monitor) logging\n"
1787 "Logging level\n")
274a4a44 1788{
ac4d0be5 1789 return CMD_SUCCESS;
274a4a44 1790}
1791
ac4d0be5 1792DEFUNSH(VTYSH_ALL, vtysh_log_syslog, vtysh_log_syslog_cmd,
1793 "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
1794 "Logging control\n"
1795 "Set syslog logging level\n" LOG_LEVEL_DESC)
95e735b5 1796{
ac4d0be5 1797 return CMD_SUCCESS;
95e735b5 1798}
1799
ac4d0be5 1800DEFUNSH(VTYSH_ALL, no_vtysh_log_syslog, no_vtysh_log_syslog_cmd,
1801 "no log syslog [LEVEL]", NO_STR
1802 "Logging control\n"
1803 "Cancel logging to syslog\n"
1804 "Logging level\n")
95e735b5 1805{
ac4d0be5 1806 return CMD_SUCCESS;
95e735b5 1807}
1808
ac4d0be5 1809DEFUNSH(VTYSH_ALL, vtysh_log_facility, vtysh_log_facility_cmd,
1810 "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>",
1811 "Logging control\n"
1812 "Facility parameter for syslog messages\n" LOG_FACILITY_DESC)
274a4a44 1813
95e735b5 1814{
ac4d0be5 1815 return CMD_SUCCESS;
95e735b5 1816}
1817
ac4d0be5 1818DEFUNSH(VTYSH_ALL, no_vtysh_log_facility, no_vtysh_log_facility_cmd,
1819 "no log facility [FACILITY]", NO_STR
1820 "Logging control\n"
1821 "Reset syslog facility to default (daemon)\n"
1822 "Syslog facility\n")
274a4a44 1823
1824{
ac4d0be5 1825 return CMD_SUCCESS;
274a4a44 1826}
1827
ac4d0be5 1828DEFUNSH_DEPRECATED(
1829 VTYSH_ALL, vtysh_log_trap, vtysh_log_trap_cmd,
1830 "log trap <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
1831 "Logging control\n"
1832 "(Deprecated) Set logging level and default for all destinations\n" LOG_LEVEL_DESC)
274a4a44 1833
1834{
ac4d0be5 1835 return CMD_SUCCESS;
274a4a44 1836}
1837
ac4d0be5 1838DEFUNSH_DEPRECATED(VTYSH_ALL, no_vtysh_log_trap, no_vtysh_log_trap_cmd,
1839 "no log trap [LEVEL]", NO_STR
1840 "Logging control\n"
1841 "Permit all logging information\n"
1842 "Logging level\n")
95e735b5 1843{
ac4d0be5 1844 return CMD_SUCCESS;
95e735b5 1845}
1846
ac4d0be5 1847DEFUNSH(VTYSH_ALL, vtysh_log_record_priority, vtysh_log_record_priority_cmd,
1848 "log record-priority",
1849 "Logging control\n"
1850 "Log the priority of the message within the message\n")
95e735b5 1851{
ac4d0be5 1852 return CMD_SUCCESS;
95e735b5 1853}
1854
ac4d0be5 1855DEFUNSH(VTYSH_ALL, no_vtysh_log_record_priority,
1856 no_vtysh_log_record_priority_cmd, "no log record-priority", NO_STR
1857 "Logging control\n"
1858 "Do not log the priority of the message within the message\n")
95e735b5 1859{
ac4d0be5 1860 return CMD_SUCCESS;
95e735b5 1861}
1862
ac4d0be5 1863DEFUNSH(VTYSH_ALL, vtysh_log_timestamp_precision,
1864 vtysh_log_timestamp_precision_cmd, "log timestamp precision (0-6)",
1865 "Logging control\n"
1866 "Timestamp configuration\n"
1867 "Set the timestamp precision\n"
1868 "Number of subsecond digits\n")
c749b722 1869{
ac4d0be5 1870 return CMD_SUCCESS;
c749b722
AS
1871}
1872
ac4d0be5 1873DEFUNSH(VTYSH_ALL, no_vtysh_log_timestamp_precision,
1874 no_vtysh_log_timestamp_precision_cmd, "no log timestamp precision",
1875 NO_STR
1876 "Logging control\n"
1877 "Timestamp configuration\n"
1878 "Reset the timestamp precision to the default value of 0\n")
c749b722 1879{
ac4d0be5 1880 return CMD_SUCCESS;
c749b722
AS
1881}
1882
ac4d0be5 1883DEFUNSH(VTYSH_ALL, vtysh_service_password_encrypt,
1884 vtysh_service_password_encrypt_cmd, "service password-encryption",
1885 "Set up miscellaneous service\n"
1886 "Enable encrypted passwords\n")
e7168df4 1887{
ac4d0be5 1888 return CMD_SUCCESS;
e7168df4 1889}
1890
ac4d0be5 1891DEFUNSH(VTYSH_ALL, no_vtysh_service_password_encrypt,
1892 no_vtysh_service_password_encrypt_cmd, "no service password-encryption",
1893 NO_STR
1894 "Set up miscellaneous service\n"
1895 "Enable encrypted passwords\n")
e7168df4 1896{
ac4d0be5 1897 return CMD_SUCCESS;
e7168df4 1898}
1899
ac4d0be5 1900DEFUNSH(VTYSH_ALL, vtysh_config_password, vtysh_password_cmd,
1901 "password (8-8) WORD",
1902 "Assign the terminal connection password\n"
1903 "Specifies a HIDDEN password will follow\n"
1904 "dummy string \n"
1905 "The HIDDEN line password string\n")
e7168df4 1906{
ac4d0be5 1907 return CMD_SUCCESS;
e7168df4 1908}
1909
ac4d0be5 1910DEFUNSH(VTYSH_ALL, vtysh_password_text, vtysh_password_text_cmd,
1911 "password LINE",
1912 "Assign the terminal connection password\n"
1913 "The UNENCRYPTED (cleartext) line password\n")
e7168df4 1914{
ac4d0be5 1915 return CMD_SUCCESS;
e7168df4 1916}
1917
ac4d0be5 1918DEFUNSH(VTYSH_ALL, vtysh_config_enable_password, vtysh_enable_password_cmd,
1919 "enable password (8-8) WORD",
1920 "Modify enable password parameters\n"
1921 "Assign the privileged level password\n"
1922 "Specifies a HIDDEN password will follow\n"
1923 "The HIDDEN 'enable' password string\n")
e7168df4 1924{
ac4d0be5 1925 return CMD_SUCCESS;
e7168df4 1926}
1927
ac4d0be5 1928DEFUNSH(VTYSH_ALL, vtysh_enable_password_text, vtysh_enable_password_text_cmd,
1929 "enable password LINE",
1930 "Modify enable password parameters\n"
1931 "Assign the privileged level password\n"
1932 "The UNENCRYPTED (cleartext) 'enable' password\n")
e7168df4 1933{
ac4d0be5 1934 return CMD_SUCCESS;
e7168df4 1935}
1936
ac4d0be5 1937DEFUNSH(VTYSH_ALL, no_vtysh_config_enable_password,
1938 no_vtysh_enable_password_cmd, "no enable password", NO_STR
1939 "Modify enable password parameters\n"
1940 "Assign the privileged level password\n")
e7168df4 1941{
ac4d0be5 1942 return CMD_SUCCESS;
e7168df4 1943}
1944
718e3744 1945DEFUN (vtysh_write_terminal,
1946 vtysh_write_terminal_cmd,
e52702f2 1947 "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
718e3744 1948 "Write running configuration to memory, network, or terminal\n"
066242b5
QY
1949 "Write to terminal\n"
1950 "For the zebra daemon\n"
1951 "For the rip daemon\n"
1952 "For the ripng daemon\n"
1953 "For the ospf daemon\n"
1954 "For the ospfv6 daemon\n"
16cedbb0 1955 "For the ldpd daemon\n"
066242b5
QY
1956 "For the bgp daemon\n"
1957 "For the isis daemon\n"
1958 "For the pim daemon\n")
718e3744 1959{
ac4d0be5 1960 u_int i;
1961 char line[] = "write terminal\n";
1962 FILE *fp = NULL;
1963
1964 if (vtysh_pager_name) {
1965 fp = popen(vtysh_pager_name, "w");
1966 if (fp == NULL) {
1967 perror("popen");
1968 exit(1);
1969 }
1970 } else
1971 fp = stdout;
1972
1973 vty_out(vty, "Building configuration...%s", VTY_NEWLINE);
1974 vty_out(vty, "%sCurrent configuration:%s", VTY_NEWLINE, VTY_NEWLINE);
1975 vty_out(vty, "!%s", VTY_NEWLINE);
1976
1977 for (i = 0; i < array_size(vtysh_client); i++)
1978 if ((argc < 3)
1979 || (strmatch(vtysh_client[i].name, argv[2]->text)))
1980 vtysh_client_config(&vtysh_client[i], line);
1981
1982 /* Integrate vtysh specific configuration. */
1983 vtysh_config_write();
1984
1985 vtysh_config_dump(fp);
1986
1987 if (vtysh_pager_name && fp) {
1988 fflush(fp);
1989 if (pclose(fp) == -1) {
1990 perror("pclose");
1991 exit(1);
1992 }
1993 fp = NULL;
1994 }
1995
1996 vty_out(vty, "end%s", VTY_NEWLINE);
1997 return CMD_SUCCESS;
718e3744 1998}
1999
a98d33ab
QY
2000DEFUN (vtysh_show_running_config,
2001 vtysh_show_running_config_cmd,
e52702f2 2002 "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
a98d33ab
QY
2003 SHOW_STR
2004 "Current operating configuration\n"
c006e89e
DS
2005 "For the zebra daemon\n"
2006 "For the rip daemon\n"
2007 "For the ripng daemon\n"
2008 "For the ospf daemon\n"
2009 "For the ospfv6 daemon\n"
4fcbf6e2 2010 "For the ldp daemon\n"
c006e89e 2011 "For the bgp daemon\n"
0fab7646
DS
2012 "For the isis daemon\n"
2013 "For the pim daemon\n")
c006e89e 2014{
ac4d0be5 2015 return vtysh_write_terminal(self, vty, argc, argv);
c006e89e
DS
2016}
2017
e7168df4 2018DEFUN (vtysh_integrated_config,
2019 vtysh_integrated_config_cmd,
2020 "service integrated-vtysh-config",
2021 "Set up miscellaneous service\n"
2022 "Write configuration into integrated file\n")
4fc01e67 2023{
ac4d0be5 2024 vtysh_write_integrated = WRITE_INTEGRATED_YES;
2025 return CMD_SUCCESS;
4fc01e67 2026}
2027
e7168df4 2028DEFUN (no_vtysh_integrated_config,
2029 no_vtysh_integrated_config_cmd,
2030 "no service integrated-vtysh-config",
2031 NO_STR
2032 "Set up miscellaneous service\n"
2033 "Write configuration into integrated file\n")
4fc01e67 2034{
ac4d0be5 2035 vtysh_write_integrated = WRITE_INTEGRATED_NO;
2036 return CMD_SUCCESS;
4fc01e67 2037}
2038
ac4d0be5 2039static void backup_config_file(const char *fbackup)
718e3744 2040{
ac4d0be5 2041 char *integrate_sav = NULL;
718e3744 2042
ac4d0be5 2043 integrate_sav = malloc(strlen(fbackup) + strlen(CONF_BACKUP_EXT) + 1);
2044 strcpy(integrate_sav, fbackup);
2045 strcat(integrate_sav, CONF_BACKUP_EXT);
718e3744 2046
ac4d0be5 2047 /* Move current configuration file to backup config file. */
2048 unlink(integrate_sav);
2049 rename(fbackup, integrate_sav);
2050 free(integrate_sav);
a7222276
DS
2051}
2052
ac4d0be5 2053int vtysh_write_config_integrated(void)
a7222276 2054{
ac4d0be5 2055 u_int i;
fa984909 2056 char line[] = "do write terminal\n";
ac4d0be5 2057 FILE *fp;
2058 int fd;
2059 struct passwd *pwentry;
2060 struct group *grentry;
2061 uid_t uid = -1;
2062 gid_t gid = -1;
2063 struct stat st;
2064 int err = 0;
a7222276 2065
ac4d0be5 2066 fprintf(stdout, "Building Configuration...\n");
a7222276 2067
ac4d0be5 2068 backup_config_file(quagga_config);
2069 fp = fopen(quagga_config, "w");
2070 if (fp == NULL) {
2071 fprintf(stdout,
2072 "%% Error: failed to open configuration file %s: %s\n",
2073 quagga_config, safe_strerror(errno));
2074 return CMD_WARNING;
2075 }
2076 fd = fileno(fp);
a7222276 2077
ac4d0be5 2078 for (i = 0; i < array_size(vtysh_client); i++)
2079 vtysh_client_config(&vtysh_client[i], line);
718e3744 2080
ac4d0be5 2081 vtysh_config_write();
2082 vtysh_config_dump(fp);
718e3744 2083
ac4d0be5 2084 if (fchmod(fd, CONFIGFILE_MASK) != 0) {
2085 printf("%% Warning: can't chmod configuration file %s: %s\n",
2086 quagga_config, safe_strerror(errno));
2087 err++;
2088 }
718e3744 2089
9e8df988 2090#ifdef FRR_USER
ac4d0be5 2091 pwentry = getpwnam(FRR_USER);
2092 if (pwentry)
2093 uid = pwentry->pw_uid;
2094 else {
2095 printf("%% Warning: could not look up user \"%s\"\n", FRR_USER);
2096 err++;
2097 }
9e8df988
JAG
2098#endif
2099#ifdef FRR_GROUP
ac4d0be5 2100 grentry = getgrnam(FRR_GROUP);
2101 if (grentry)
2102 gid = grentry->gr_gid;
2103 else {
2104 printf("%% Warning: could not look up group \"%s\"\n",
2105 FRR_GROUP);
2106 err++;
2107 }
9e8df988 2108#endif
4fc01e67 2109
ac4d0be5 2110 if (!fstat(fd, &st)) {
2111 if (st.st_uid == uid)
2112 uid = -1;
2113 if (st.st_gid == gid)
2114 gid = -1;
2115 if ((uid != (uid_t)-1 || gid != (gid_t)-1)
2116 && fchown(fd, uid, gid)) {
2117 printf("%% Warning: can't chown configuration file %s: %s\n",
2118 quagga_config, safe_strerror(errno));
2119 err++;
2120 }
2121 } else {
2122 printf("%% Warning: stat() failed on %s: %s\n", quagga_config,
2123 safe_strerror(errno));
2124 err++;
2125 }
2126
2127 fclose(fp);
2128
2129 printf("Integrated configuration saved to %s\n", quagga_config);
2130 if (err)
2131 return CMD_WARNING;
2132
2133 printf("[OK]\n");
2134 return CMD_SUCCESS;
718e3744 2135}
2136
a68f8616 2137static bool want_config_integrated(void)
039eaca3 2138{
ac4d0be5 2139 struct stat s;
2140
2141 switch (vtysh_write_integrated) {
2142 case WRITE_INTEGRATED_UNSPECIFIED:
2143 if (stat(quagga_config, &s) && errno == ENOENT)
2144 return false;
2145 return true;
2146 case WRITE_INTEGRATED_NO:
2147 return false;
2148 case WRITE_INTEGRATED_YES:
2149 return true;
2150 }
2151 return true;
039eaca3
CF
2152}
2153
4fc01e67 2154DEFUN (vtysh_write_memory,
2155 vtysh_write_memory_cmd,
a98d33ab 2156 "write [<memory|file>]",
4fc01e67 2157 "Write running configuration to memory, network, or terminal\n"
a98d33ab
QY
2158 "Write configuration to the file (same as write file)\n"
2159 "Write configuration to the file (same as write memory)\n")
4fc01e67 2160{
ac4d0be5 2161 int ret = CMD_SUCCESS;
2162 char line[] = "write memory\n";
2163 u_int i;
2164
2165 fprintf(stdout,
2166 "Note: this version of vtysh never writes vtysh.conf\n");
2167
2168 /* If integrated frr.conf explicitely set. */
2169 if (want_config_integrated()) {
2170 ret = CMD_WARNING;
2171 for (i = 0; i < array_size(vtysh_client); i++)
2172 if (vtysh_client[i].flag == VTYSH_WATCHFRR)
2173 break;
2174 if (i < array_size(vtysh_client) && vtysh_client[i].fd != -1)
2175 ret = vtysh_client_execute(&vtysh_client[i],
fa984909 2176 "do write integrated", stdout);
ac4d0be5 2177
2178 if (ret != CMD_SUCCESS) {
2179 printf("\nWarning: attempting direct configuration write without "
2180 "watchfrr.\nFile permissions and ownership may be "
2181 "incorrect, or write may fail.\n\n");
2182 ret = vtysh_write_config_integrated();
2183 }
2184 return ret;
2185 }
a7222276 2186
ac4d0be5 2187 fprintf(stdout, "Building Configuration...\n");
a7222276 2188
ac4d0be5 2189 for (i = 0; i < array_size(vtysh_client); i++)
2190 ret = vtysh_client_execute(&vtysh_client[i], line, stdout);
4fc01e67 2191
ac4d0be5 2192 return ret;
4fc01e67 2193}
2194
a98d33ab
QY
2195DEFUN (vtysh_copy_running_config,
2196 vtysh_copy_running_config_cmd,
2197 "copy running-config startup-config",
718e3744 2198 "Copy from one file to another\n"
2199 "Copy from current system configuration\n"
2200 "Copy to startup configuration\n")
a98d33ab 2201{
ac4d0be5 2202 return vtysh_write_memory(self, vty, argc, argv);
a98d33ab 2203}
718e3744 2204
34553cc3 2205DEFUN (vtysh_terminal_length,
2206 vtysh_terminal_length_cmd,
6147e2c6 2207 "terminal length (0-512)",
34553cc3 2208 "Set terminal line parameters\n"
2209 "Set number of lines on a screen\n"
2210 "Number of lines on screen (0 for no pausing)\n")
2211{
ac4d0be5 2212 int idx_number = 2;
2213 int lines;
2214 char *endptr = NULL;
2215 char default_pager[10];
34553cc3 2216
ac4d0be5 2217 lines = strtol(argv[idx_number]->arg, &endptr, 10);
2218 if (lines < 0 || lines > 512 || *endptr != '\0') {
2219 vty_out(vty, "length is malformed%s", VTY_NEWLINE);
2220 return CMD_WARNING;
2221 }
34553cc3 2222
ac4d0be5 2223 if (vtysh_pager_name) {
2224 free(vtysh_pager_name);
2225 vtysh_pager_name = NULL;
2226 }
34553cc3 2227
ac4d0be5 2228 if (lines != 0) {
2229 snprintf(default_pager, 10, "more -%i", lines);
2230 vtysh_pager_name = strdup(default_pager);
2231 }
34553cc3 2232
ac4d0be5 2233 return CMD_SUCCESS;
34553cc3 2234}
2235
2236DEFUN (vtysh_terminal_no_length,
2237 vtysh_terminal_no_length_cmd,
2238 "terminal no length",
2239 "Set terminal line parameters\n"
2240 NO_STR
2241 "Set number of lines on a screen\n")
2242{
ac4d0be5 2243 if (vtysh_pager_name) {
2244 free(vtysh_pager_name);
2245 vtysh_pager_name = NULL;
2246 }
34553cc3 2247
ac4d0be5 2248 vtysh_pager_init();
2249 return CMD_SUCCESS;
34553cc3 2250}
2251
f2799e69 2252DEFUN (vtysh_show_daemons,
2253 vtysh_show_daemons_cmd,
2254 "show daemons",
e7168df4 2255 SHOW_STR
2256 "Show list of running daemons\n")
2257{
ac4d0be5 2258 u_int i;
b1aa147d 2259
ac4d0be5 2260 for (i = 0; i < array_size(vtysh_client); i++)
2261 if (vtysh_client[i].fd >= 0)
2262 vty_out(vty, " %s", vtysh_client[i].name);
2263 vty_out(vty, "%s", VTY_NEWLINE);
e7168df4 2264
ac4d0be5 2265 return CMD_SUCCESS;
e7168df4 2266}
2267
718e3744 2268/* Execute command in child process. */
ac4d0be5 2269static void execute_command(const char *command, int argc,
0b9d4ca7 2270 const char *arg1, const char *arg2)
ac4d0be5 2271{
2272 pid_t pid;
2273 int status;
2274
2275 /* Call fork(). */
2276 pid = fork();
2277
2278 if (pid < 0) {
2279 /* Failure of fork(). */
2280 fprintf(stderr, "Can't fork: %s\n", safe_strerror(errno));
2281 exit(1);
2282 } else if (pid == 0) {
2283 /* This is child process. */
2284 switch (argc) {
2285 case 0:
2286 execlp(command, command, (const char *)NULL);
2287 break;
2288 case 1:
2289 execlp(command, command, arg1, (const char *)NULL);
2290 break;
2291 case 2:
2292 execlp(command, command, arg1, arg2,
2293 (const char *)NULL);
2294 break;
2295 }
718e3744 2296
ac4d0be5 2297 /* When execlp suceed, this part is not executed. */
2298 fprintf(stderr, "Can't execute %s: %s\n", command,
2299 safe_strerror(errno));
2300 exit(1);
2301 } else {
2302 /* This is parent. */
2303 execute_flag = 1;
2304 wait4(pid, &status, 0, NULL);
2305 execute_flag = 0;
2306 }
718e3744 2307}
2308
2309DEFUN (vtysh_ping,
2310 vtysh_ping_cmd,
2311 "ping WORD",
4eeccf18 2312 "Send echo messages\n"
718e3744 2313 "Ping destination address or hostname\n")
2314{
0b9d4ca7
DS
2315 int idx = 1;
2316
2317 argv_find(argv, argc, "WORD", &idx);
2318 execute_command("ping", 1, argv[idx]->arg, NULL);
ac4d0be5 2319 return CMD_SUCCESS;
718e3744 2320}
2321
ac4d0be5 2322ALIAS(vtysh_ping, vtysh_ping_ip_cmd, "ping ip WORD",
2323 "Send echo messages\n"
2324 "IP echo\n"
2325 "Ping destination address or hostname\n")
4eeccf18 2326
718e3744 2327DEFUN (vtysh_traceroute,
2328 vtysh_traceroute_cmd,
2329 "traceroute WORD",
2330 "Trace route to destination\n"
2331 "Trace route to destination address or hostname\n")
2332{
0b9d4ca7
DS
2333 int idx = 1;
2334
2335 argv_find(argv, argc, "WORD", &idx);
2336 execute_command("traceroute", 1, argv[idx]->arg, NULL);
ac4d0be5 2337 return CMD_SUCCESS;
718e3744 2338}
2339
ac4d0be5 2340ALIAS(vtysh_traceroute, vtysh_traceroute_ip_cmd, "traceroute ip WORD",
2341 "Trace route to destination\n"
2342 "IP trace\n"
2343 "Trace route to destination address or hostname\n")
4eeccf18 2344
4eeccf18 2345DEFUN (vtysh_ping6,
2346 vtysh_ping6_cmd,
2347 "ping ipv6 WORD",
2348 "Send echo messages\n"
2349 "IPv6 echo\n"
2350 "Ping destination address or hostname\n")
2351{
0b9d4ca7 2352 execute_command("ping6", 1, argv[2]->arg, NULL);
ac4d0be5 2353 return CMD_SUCCESS;
4eeccf18 2354}
2355
2356DEFUN (vtysh_traceroute6,
2357 vtysh_traceroute6_cmd,
2358 "traceroute ipv6 WORD",
2359 "Trace route to destination\n"
2360 "IPv6 trace\n"
2361 "Trace route to destination address or hostname\n")
2362{
0b9d4ca7 2363 execute_command("traceroute6", 1, argv[2]->arg, NULL);
ac4d0be5 2364 return CMD_SUCCESS;
4eeccf18 2365}
4eeccf18 2366
576b6b5d 2367#if defined(HAVE_SHELL_ACCESS)
718e3744 2368DEFUN (vtysh_telnet,
2369 vtysh_telnet_cmd,
2370 "telnet WORD",
2371 "Open a telnet connection\n"
2372 "IP address or hostname of a remote system\n")
2373{
0b9d4ca7 2374 execute_command("telnet", 1, argv[1]->arg, NULL);
ac4d0be5 2375 return CMD_SUCCESS;
718e3744 2376}
2377
2378DEFUN (vtysh_telnet_port,
2379 vtysh_telnet_port_cmd,
2380 "telnet WORD PORT",
2381 "Open a telnet connection\n"
2382 "IP address or hostname of a remote system\n"
2383 "TCP Port number\n")
2384{
0b9d4ca7 2385 execute_command("telnet", 2, argv[1]->arg, argv[2]->arg);
ac4d0be5 2386 return CMD_SUCCESS;
718e3744 2387}
2388
5087df56 2389DEFUN (vtysh_ssh,
2390 vtysh_ssh_cmd,
2391 "ssh WORD",
2392 "Open an ssh connection\n"
2393 "[user@]host\n")
2394{
0b9d4ca7 2395 execute_command("ssh", 1, argv[1]->arg, NULL);
ac4d0be5 2396 return CMD_SUCCESS;
5087df56 2397}
2398
718e3744 2399DEFUN (vtysh_start_shell,
2400 vtysh_start_shell_cmd,
2401 "start-shell",
2402 "Start UNIX shell\n")
2403{
ac4d0be5 2404 execute_command("sh", 0, NULL, NULL);
2405 return CMD_SUCCESS;
718e3744 2406}
2407
2408DEFUN (vtysh_start_bash,
2409 vtysh_start_bash_cmd,
2410 "start-shell bash",
2411 "Start UNIX shell\n"
2412 "Start bash\n")
2413{
ac4d0be5 2414 execute_command("bash", 0, NULL, NULL);
2415 return CMD_SUCCESS;
718e3744 2416}
2417
2418DEFUN (vtysh_start_zsh,
2419 vtysh_start_zsh_cmd,
2420 "start-shell zsh",
2421 "Start UNIX shell\n"
2422 "Start Z shell\n")
2423{
ac4d0be5 2424 execute_command("zsh", 0, NULL, NULL);
2425 return CMD_SUCCESS;
718e3744 2426}
576b6b5d 2427#endif
b094d260 2428
0b84f294
DL
2429DEFUN (config_list,
2430 config_list_cmd,
2431 "list [permutations]",
2432 "Print command list\n"
2433 "Print all possible command permutations\n")
2434{
ac4d0be5 2435 return cmd_list_cmds(vty, argc == 2);
0b84f294
DL
2436}
2437
ac4d0be5 2438static void vtysh_install_default(enum node_type node)
718e3744 2439{
ac4d0be5 2440 install_element(node, &config_list_cmd);
718e3744 2441}
2442
2443/* Making connection to protocol daemon. */
ac4d0be5 2444static int vtysh_connect(struct vtysh_client *vclient)
2445{
2446 int ret;
2447 int sock, len;
2448 struct sockaddr_un addr;
2449 struct stat s_stat;
2450 const char *path;
2451
2452 if (!vclient->path[0])
2453 snprintf(vclient->path, sizeof(vclient->path), "%s/%s.vty",
2454 vty_sock_path, vclient->name);
2455 path = vclient->path;
2456
2457 /* Stat socket to see if we have permission to access it. */
2458 ret = stat(path, &s_stat);
2459 if (ret < 0 && errno != ENOENT) {
2460 fprintf(stderr, "vtysh_connect(%s): stat = %s\n", path,
2461 safe_strerror(errno));
2462 exit(1);
718e3744 2463 }
718e3744 2464
ac4d0be5 2465 if (ret >= 0) {
2466 if (!S_ISSOCK(s_stat.st_mode)) {
2467 fprintf(stderr, "vtysh_connect(%s): Not a socket\n",
2468 path);
2469 exit(1);
2470 }
2471 }
2472
2473 sock = socket(AF_UNIX, SOCK_STREAM, 0);
2474 if (sock < 0) {
718e3744 2475#ifdef DEBUG
ac4d0be5 2476 fprintf(stderr, "vtysh_connect(%s): socket = %s\n", path,
2477 safe_strerror(errno));
718e3744 2478#endif /* DEBUG */
ac4d0be5 2479 return -1;
2480 }
718e3744 2481
ac4d0be5 2482 memset(&addr, 0, sizeof(struct sockaddr_un));
2483 addr.sun_family = AF_UNIX;
2484 strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
6f0e3f6e 2485#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
ac4d0be5 2486 len = addr.sun_len = SUN_LEN(&addr);
718e3744 2487#else
ac4d0be5 2488 len = sizeof(addr.sun_family) + strlen(addr.sun_path);
6f0e3f6e 2489#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
718e3744 2490
ac4d0be5 2491 ret = connect(sock, (struct sockaddr *)&addr, len);
2492 if (ret < 0) {
718e3744 2493#ifdef DEBUG
ac4d0be5 2494 fprintf(stderr, "vtysh_connect(%s): connect = %s\n", path,
2495 safe_strerror(errno));
718e3744 2496#endif /* DEBUG */
ac4d0be5 2497 close(sock);
2498 return -1;
2499 }
2500 vclient->fd = sock;
718e3744 2501
ac4d0be5 2502 return 0;
718e3744 2503}
2504
7c8ff89e 2505/* Return true if str ends with suffix, else return false */
ac4d0be5 2506static int ends_with(const char *str, const char *suffix)
7c8ff89e 2507{
ac4d0be5 2508 if (!str || !suffix)
2509 return 0;
2510 size_t lenstr = strlen(str);
2511 size_t lensuffix = strlen(suffix);
2512 if (lensuffix > lenstr)
2513 return 0;
2514 return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
7c8ff89e
DS
2515}
2516
ac4d0be5 2517static void vtysh_client_sorted_insert(struct vtysh_client *head_client,
2518 struct vtysh_client *client)
7c8ff89e 2519{
ac4d0be5 2520 struct vtysh_client *prev_node, *current_node;
7c8ff89e 2521
ac4d0be5 2522 prev_node = head_client;
2523 current_node = head_client->next;
2524 while (current_node) {
2525 if (strcmp(current_node->path, client->path) > 0)
2526 break;
7c8ff89e 2527
ac4d0be5 2528 prev_node = current_node;
2529 current_node = current_node->next;
2530 }
2531 client->next = current_node;
2532 prev_node->next = client;
7c8ff89e
DS
2533}
2534
2535#define MAXIMUM_INSTANCES 10
2536
ac4d0be5 2537static void vtysh_update_all_insances(struct vtysh_client *head_client)
2538{
2539 struct vtysh_client *client;
2540 DIR *dir;
2541 struct dirent *file;
2542 int n = 0;
2543
2544 if (head_client->flag != VTYSH_OSPFD)
2545 return;
2546
2547 /* ls vty_sock_dir and look for all files ending in .vty */
2548 dir = opendir(vty_sock_path);
2549 if (dir) {
2550 while ((file = readdir(dir)) != NULL) {
2551 if (begins_with(file->d_name, "ospfd-")
2552 && ends_with(file->d_name, ".vty")) {
2553 if (n == MAXIMUM_INSTANCES) {
2554 fprintf(stderr,
2555 "Parsing %s, client limit(%d) reached!\n",
2556 vty_sock_path, n);
2557 break;
2558 }
2559 client = (struct vtysh_client *)malloc(
2560 sizeof(struct vtysh_client));
2561 client->fd = -1;
2562 client->name = "ospfd";
2563 client->flag = VTYSH_OSPFD;
2564 snprintf(client->path, sizeof(client->path),
2565 "%s/%s", vty_sock_path, file->d_name);
2566 client->next = NULL;
2567 vtysh_client_sorted_insert(head_client, client);
2568 n++;
2569 }
2570 }
2571 closedir(dir);
2572 }
2573}
2574
2575static int vtysh_connect_all_instances(struct vtysh_client *head_client)
2576{
2577 struct vtysh_client *client;
2578 int rc = 0;
2579
2580 vtysh_update_all_insances(head_client);
2581
2582 client = head_client->next;
2583 while (client) {
2584 if (vtysh_connect(client) == 0)
2585 rc++;
2586 client = client->next;
2587 }
2588
2589 return rc;
2590}
2591
2592int vtysh_connect_all(const char *daemon_name)
2593{
2594 u_int i;
2595 int rc = 0;
2596 int matches = 0;
2597
2598 for (i = 0; i < array_size(vtysh_client); i++) {
2599 if (!daemon_name
2600 || !strcmp(daemon_name, vtysh_client[i].name)) {
2601 matches++;
2602 if (vtysh_connect(&vtysh_client[i]) == 0)
2603 rc++;
2604
2605 rc += vtysh_connect_all_instances(&vtysh_client[i]);
2606 }
2607 }
2608 if (!matches)
2609 fprintf(stderr, "Error: no daemons match name %s!\n",
2610 daemon_name);
2611 return rc;
718e3744 2612}
2613
95e735b5 2614/* To disable readline's filename completion. */
ac4d0be5 2615static char *vtysh_completion_entry_function(const char *ignore,
2616 int invoking_key)
2617{
2618 return NULL;
2619}
2620
2621void vtysh_readline_init(void)
2622{
2623 /* readline related settings. */
2624 rl_initialize();
2625 rl_bind_key('?', (rl_command_func_t *)vtysh_rl_describe);
2626 rl_completion_entry_function = vtysh_completion_entry_function;
2627 rl_attempted_completion_function =
2628 (rl_completion_func_t *)new_completion;
2629}
2630
2631char *vtysh_prompt(void)
2632{
2633 static struct utsname names;
2634 static char buf[100];
2635 const char *hostname;
2636 extern struct host host;
2637
2638 hostname = host.name;
2639
2640 if (!hostname) {
2641 if (!names.nodename[0])
2642 uname(&names);
2643 hostname = names.nodename;
2644 }
2645
2646 snprintf(buf, sizeof buf, cmd_prompt(vty->node), hostname);
2647
2648 return buf;
2649}
2650
2651void vtysh_init_vty(void)
2652{
2653 /* Make vty structure. */
2654 vty = vty_new();
2655 vty->type = VTY_SHELL;
2656 vty->node = VIEW_NODE;
2657
2658 /* Initialize commands. */
2659 cmd_init(0);
2660
2661 /* Install nodes. */
2662 install_node(&bgp_node, NULL);
2663 install_node(&rip_node, NULL);
2664 install_node(&interface_node, NULL);
2665 install_node(&pw_node, NULL);
2666 install_node(&link_params_node, NULL);
2667 install_node(&ns_node, NULL);
2668 install_node(&vrf_node, NULL);
2669 install_node(&rmap_node, NULL);
2670 install_node(&zebra_node, NULL);
2671 install_node(&bgp_vpnv4_node, NULL);
2672 install_node(&bgp_vpnv6_node, NULL);
2673 install_node(&bgp_ipv4_node, NULL);
2674 install_node(&bgp_ipv4m_node, NULL);
2675 install_node(&bgp_ipv6_node, NULL);
2676 install_node(&bgp_ipv6m_node, NULL);
2677 install_node(&bgp_vrf_policy_node, NULL);
2678 install_node(&bgp_evpn_node, NULL);
2679 install_node(&bgp_vnc_defaults_node, NULL);
2680 install_node(&bgp_vnc_nve_group_node, NULL);
2681 install_node(&bgp_vnc_l2_group_node, NULL);
2682 install_node(&ospf_node, NULL);
2683 install_node(&ripng_node, NULL);
2684 install_node(&ospf6_node, NULL);
2685 install_node(&ldp_node, NULL);
2686 install_node(&ldp_ipv4_node, NULL);
2687 install_node(&ldp_ipv6_node, NULL);
2688 install_node(&ldp_ipv4_iface_node, NULL);
2689 install_node(&ldp_ipv6_iface_node, NULL);
2690 install_node(&ldp_l2vpn_node, NULL);
2691 install_node(&ldp_pseudowire_node, NULL);
2692 install_node(&keychain_node, NULL);
2693 install_node(&keychain_key_node, NULL);
2694 install_node(&isis_node, NULL);
2695 install_node(&vty_node, NULL);
2696
2697 vtysh_install_default(VIEW_NODE);
2698 vtysh_install_default(CONFIG_NODE);
2699 vtysh_install_default(BGP_NODE);
2700 vtysh_install_default(RIP_NODE);
2701 vtysh_install_default(INTERFACE_NODE);
2702 vtysh_install_default(PW_NODE);
2703 vtysh_install_default(LINK_PARAMS_NODE);
2704 vtysh_install_default(NS_NODE);
2705 vtysh_install_default(VRF_NODE);
2706 vtysh_install_default(RMAP_NODE);
2707 vtysh_install_default(ZEBRA_NODE);
2708 vtysh_install_default(BGP_VPNV4_NODE);
2709 vtysh_install_default(BGP_VPNV6_NODE);
2710 vtysh_install_default(BGP_IPV4_NODE);
2711 vtysh_install_default(BGP_IPV4M_NODE);
2712 vtysh_install_default(BGP_IPV6_NODE);
2713 vtysh_install_default(BGP_IPV6M_NODE);
2714 vtysh_install_default(BGP_EVPN_NODE);
87ab4aec 2715#if ENABLE_BGP_VNC
ac4d0be5 2716 vtysh_install_default(BGP_VRF_POLICY_NODE);
2717 vtysh_install_default(BGP_VNC_DEFAULTS_NODE);
2718 vtysh_install_default(BGP_VNC_NVE_GROUP_NODE);
2719 vtysh_install_default(BGP_VNC_L2_GROUP_NODE);
87ab4aec 2720#endif
ac4d0be5 2721 vtysh_install_default(OSPF_NODE);
2722 vtysh_install_default(RIPNG_NODE);
2723 vtysh_install_default(OSPF6_NODE);
2724 vtysh_install_default(LDP_NODE);
2725 vtysh_install_default(LDP_IPV4_NODE);
2726 vtysh_install_default(LDP_IPV6_NODE);
2727 vtysh_install_default(LDP_IPV4_IFACE_NODE);
2728 vtysh_install_default(LDP_IPV6_IFACE_NODE);
2729 vtysh_install_default(LDP_L2VPN_NODE);
2730 vtysh_install_default(LDP_PSEUDOWIRE_NODE);
2731 vtysh_install_default(ISIS_NODE);
2732 vtysh_install_default(KEYCHAIN_NODE);
2733 vtysh_install_default(KEYCHAIN_KEY_NODE);
2734 vtysh_install_default(VTY_NODE);
2735
2736 install_element(VIEW_NODE, &vtysh_enable_cmd);
2737 install_element(ENABLE_NODE, &vtysh_config_terminal_cmd);
2738 install_element(ENABLE_NODE, &vtysh_disable_cmd);
2739
2740 /* "exit" command. */
2741 install_element(VIEW_NODE, &vtysh_exit_all_cmd);
2742 install_element(CONFIG_NODE, &vtysh_exit_all_cmd);
2743 install_element(VIEW_NODE, &vtysh_quit_all_cmd);
2744 install_element(CONFIG_NODE, &vtysh_quit_all_cmd);
2745 install_element(RIP_NODE, &vtysh_exit_ripd_cmd);
2746 install_element(RIP_NODE, &vtysh_quit_ripd_cmd);
2747 install_element(RIPNG_NODE, &vtysh_exit_ripngd_cmd);
2748 install_element(RIPNG_NODE, &vtysh_quit_ripngd_cmd);
2749 install_element(OSPF_NODE, &vtysh_exit_ospfd_cmd);
2750 install_element(OSPF_NODE, &vtysh_quit_ospfd_cmd);
2751 install_element(OSPF6_NODE, &vtysh_exit_ospf6d_cmd);
2752 install_element(OSPF6_NODE, &vtysh_quit_ospf6d_cmd);
2753#if defined(HAVE_LDPD)
2754 install_element(LDP_NODE, &vtysh_exit_ldpd_cmd);
2755 install_element(LDP_NODE, &vtysh_quit_ldpd_cmd);
2756 install_element(LDP_IPV4_NODE, &vtysh_exit_ldpd_cmd);
2757 install_element(LDP_IPV4_NODE, &vtysh_quit_ldpd_cmd);
2758 install_element(LDP_IPV6_NODE, &vtysh_exit_ldpd_cmd);
2759 install_element(LDP_IPV6_NODE, &vtysh_quit_ldpd_cmd);
2760 install_element(LDP_IPV4_IFACE_NODE, &vtysh_exit_ldpd_cmd);
2761 install_element(LDP_IPV4_IFACE_NODE, &vtysh_quit_ldpd_cmd);
2762 install_element(LDP_IPV6_IFACE_NODE, &vtysh_exit_ldpd_cmd);
2763 install_element(LDP_IPV6_IFACE_NODE, &vtysh_quit_ldpd_cmd);
2764 install_element(LDP_L2VPN_NODE, &vtysh_exit_ldpd_cmd);
2765 install_element(LDP_L2VPN_NODE, &vtysh_quit_ldpd_cmd);
2766 install_element(LDP_PSEUDOWIRE_NODE, &vtysh_exit_ldpd_cmd);
2767 install_element(LDP_PSEUDOWIRE_NODE, &vtysh_quit_ldpd_cmd);
87ab4aec 2768#endif
ac4d0be5 2769 install_element(BGP_NODE, &vtysh_exit_bgpd_cmd);
2770 install_element(BGP_NODE, &vtysh_quit_bgpd_cmd);
2771 install_element(BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd);
2772 install_element(BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd);
2773 install_element(BGP_VPNV6_NODE, &vtysh_exit_bgpd_cmd);
2774 install_element(BGP_VPNV6_NODE, &vtysh_quit_bgpd_cmd);
2775 install_element(BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd);
2776 install_element(BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd);
2777 install_element(BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd);
2778 install_element(BGP_IPV4M_NODE, &vtysh_quit_bgpd_cmd);
2779 install_element(BGP_IPV6_NODE, &vtysh_exit_bgpd_cmd);
2780 install_element(BGP_IPV6_NODE, &vtysh_quit_bgpd_cmd);
2781 install_element(BGP_IPV6M_NODE, &vtysh_exit_bgpd_cmd);
2782 install_element(BGP_IPV6M_NODE, &vtysh_quit_bgpd_cmd);
2783 install_element(BGP_EVPN_NODE, &vtysh_quit_bgpd_cmd);
2784#if defined(ENABLE_BGP_VNC)
2785 install_element(BGP_VRF_POLICY_NODE, &vtysh_exit_bgpd_cmd);
2786 install_element(BGP_VRF_POLICY_NODE, &vtysh_quit_bgpd_cmd);
2787 install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_exit_bgpd_cmd);
2788 install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_quit_bgpd_cmd);
2789 install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_exit_bgpd_cmd);
2790 install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_quit_bgpd_cmd);
2791 install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_exit_bgpd_cmd);
2792 install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_quit_bgpd_cmd);
87ab4aec 2793#endif
ac4d0be5 2794 install_element(ISIS_NODE, &vtysh_exit_isisd_cmd);
2795 install_element(ISIS_NODE, &vtysh_quit_isisd_cmd);
2796 install_element(KEYCHAIN_NODE, &vtysh_exit_ripd_cmd);
2797 install_element(KEYCHAIN_NODE, &vtysh_quit_ripd_cmd);
2798 install_element(KEYCHAIN_KEY_NODE, &vtysh_exit_ripd_cmd);
2799 install_element(KEYCHAIN_KEY_NODE, &vtysh_quit_ripd_cmd);
2800 install_element(RMAP_NODE, &vtysh_exit_rmap_cmd);
2801 install_element(RMAP_NODE, &vtysh_quit_rmap_cmd);
2802 install_element(VTY_NODE, &vtysh_exit_line_vty_cmd);
2803 install_element(VTY_NODE, &vtysh_quit_line_vty_cmd);
2804
2805 /* "end" command. */
2806 install_element(CONFIG_NODE, &vtysh_end_all_cmd);
2807 install_element(ENABLE_NODE, &vtysh_end_all_cmd);
2808 install_element(RIP_NODE, &vtysh_end_all_cmd);
2809 install_element(RIPNG_NODE, &vtysh_end_all_cmd);
2810 install_element(OSPF_NODE, &vtysh_end_all_cmd);
2811 install_element(OSPF6_NODE, &vtysh_end_all_cmd);
2812 install_element(LDP_NODE, &vtysh_end_all_cmd);
2813 install_element(LDP_IPV4_NODE, &vtysh_end_all_cmd);
2814 install_element(LDP_IPV6_NODE, &vtysh_end_all_cmd);
2815 install_element(LDP_IPV4_IFACE_NODE, &vtysh_end_all_cmd);
2816 install_element(LDP_IPV6_IFACE_NODE, &vtysh_end_all_cmd);
2817 install_element(LDP_L2VPN_NODE, &vtysh_end_all_cmd);
2818 install_element(LDP_PSEUDOWIRE_NODE, &vtysh_end_all_cmd);
2819 install_element(BGP_NODE, &vtysh_end_all_cmd);
2820 install_element(BGP_IPV4_NODE, &vtysh_end_all_cmd);
2821 install_element(BGP_IPV4M_NODE, &vtysh_end_all_cmd);
2822 install_element(BGP_VPNV4_NODE, &vtysh_end_all_cmd);
2823 install_element(BGP_VPNV6_NODE, &vtysh_end_all_cmd);
2824 install_element(BGP_IPV6_NODE, &vtysh_end_all_cmd);
2825 install_element(BGP_IPV6M_NODE, &vtysh_end_all_cmd);
2826 install_element(BGP_VRF_POLICY_NODE, &vtysh_end_all_cmd);
2827 install_element(BGP_EVPN_NODE, &vtysh_end_all_cmd);
2828 install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_end_all_cmd);
2829 install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_end_all_cmd);
2830 install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_end_all_cmd);
2831 install_element(ISIS_NODE, &vtysh_end_all_cmd);
2832 install_element(KEYCHAIN_NODE, &vtysh_end_all_cmd);
2833 install_element(KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd);
2834 install_element(RMAP_NODE, &vtysh_end_all_cmd);
2835 install_element(VTY_NODE, &vtysh_end_all_cmd);
2836
2837 install_element(INTERFACE_NODE, &vtysh_interface_desc_cmd);
2838 install_element(INTERFACE_NODE, &vtysh_no_interface_desc_cmd);
2839 install_element(INTERFACE_NODE, &vtysh_end_all_cmd);
2840 install_element(INTERFACE_NODE, &vtysh_exit_interface_cmd);
2841 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
2842 install_element(LINK_PARAMS_NODE, &vtysh_end_all_cmd);
2843 install_element(LINK_PARAMS_NODE, &vtysh_exit_interface_cmd);
2844 install_element(INTERFACE_NODE, &vtysh_quit_interface_cmd);
2845
2846 install_element(PW_NODE, &vtysh_end_all_cmd);
2847 install_element(PW_NODE, &vtysh_exit_interface_cmd);
2848 install_element(PW_NODE, &vtysh_quit_interface_cmd);
2849
2850 install_element(NS_NODE, &vtysh_end_all_cmd);
2851
2852 install_element(CONFIG_NODE, &vtysh_ns_cmd);
2853 install_element(NS_NODE, &vtysh_exit_ns_cmd);
2854 install_element(NS_NODE, &vtysh_quit_ns_cmd);
2855
2856 install_element(VRF_NODE, &vtysh_end_all_cmd);
2857 install_element(VRF_NODE, &vtysh_exit_vrf_cmd);
2858 install_element(VRF_NODE, &vtysh_quit_vrf_cmd);
2859
2860 install_element(CONFIG_NODE, &router_rip_cmd);
2861 install_element(CONFIG_NODE, &router_ripng_cmd);
2862 install_element(CONFIG_NODE, &router_ospf_cmd);
2863 install_element(CONFIG_NODE, &router_ospf6_cmd);
2864#if defined(HAVE_LDPD)
2865 install_element(CONFIG_NODE, &ldp_mpls_ldp_cmd);
2866 install_element(LDP_NODE, &ldp_address_family_ipv4_cmd);
2867 install_element(LDP_NODE, &ldp_address_family_ipv6_cmd);
2868 install_element(LDP_IPV4_NODE, &ldp_interface_ifname_cmd);
2869 install_element(LDP_IPV6_NODE, &ldp_interface_ifname_cmd);
2870 install_element(CONFIG_NODE, &ldp_l2vpn_word_type_vpls_cmd);
2871 install_element(LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd);
87ab4aec 2872#endif
ac4d0be5 2873 install_element(CONFIG_NODE, &router_isis_cmd);
2874 install_element(CONFIG_NODE, &router_bgp_cmd);
2875 install_element(BGP_NODE, &address_family_vpnv4_cmd);
2876 install_element(BGP_NODE, &address_family_vpnv6_cmd);
87ab4aec 2877#if defined(ENABLE_BGP_VNC)
ac4d0be5 2878 install_element(BGP_NODE, &vnc_vrf_policy_cmd);
2879 install_element(BGP_NODE, &vnc_defaults_cmd);
2880 install_element(BGP_NODE, &vnc_nve_group_cmd);
2881 install_element(BGP_NODE, &vnc_l2_group_cmd);
87ab4aec 2882#endif
ac4d0be5 2883 install_element(BGP_NODE, &address_family_ipv4_cmd);
2884 install_element(BGP_NODE, &address_family_ipv4_multicast_cmd);
2885 install_element(BGP_NODE, &address_family_ipv4_vpn_cmd);
2886 install_element(BGP_NODE, &address_family_ipv6_cmd);
2887 install_element(BGP_NODE, &address_family_ipv6_multicast_cmd);
2888 install_element(BGP_NODE, &address_family_ipv6_vpn_cmd);
2889 install_element(BGP_NODE, &address_family_evpn_cmd);
2890 install_element(BGP_VPNV4_NODE, &exit_address_family_cmd);
2891 install_element(BGP_VPNV6_NODE, &exit_address_family_cmd);
2892 install_element(BGP_IPV4_NODE, &exit_address_family_cmd);
2893 install_element(BGP_IPV4M_NODE, &exit_address_family_cmd);
2894 install_element(BGP_IPV6_NODE, &exit_address_family_cmd);
2895 install_element(BGP_IPV6M_NODE, &exit_address_family_cmd);
2896 install_element(BGP_EVPN_NODE, &exit_address_family_cmd);
2897
2898 install_element(BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd);
2899 install_element(BGP_VNC_DEFAULTS_NODE, &exit_vnc_config_cmd);
2900 install_element(BGP_VNC_NVE_GROUP_NODE, &exit_vnc_config_cmd);
2901 install_element(BGP_VNC_L2_GROUP_NODE, &exit_vnc_config_cmd);
2902
2903 install_element(CONFIG_NODE, &key_chain_cmd);
2904 install_element(CONFIG_NODE, &vtysh_route_map_cmd);
2905 install_element(CONFIG_NODE, &vtysh_line_vty_cmd);
2906 install_element(KEYCHAIN_NODE, &key_cmd);
2907 install_element(KEYCHAIN_NODE, &key_chain_cmd);
2908 install_element(KEYCHAIN_KEY_NODE, &key_chain_cmd);
2909 install_element(CONFIG_NODE, &vtysh_interface_cmd);
2910 install_element(CONFIG_NODE, &vtysh_no_interface_cmd);
2911 install_element(CONFIG_NODE, &vtysh_no_interface_vrf_cmd);
2912 install_element(CONFIG_NODE, &vtysh_pseudowire_cmd);
2913 install_element(INTERFACE_NODE, &vtysh_link_params_cmd);
2914 install_element(ENABLE_NODE, &vtysh_show_running_config_cmd);
2915 install_element(ENABLE_NODE, &vtysh_copy_running_config_cmd);
2916
2917 install_element(CONFIG_NODE, &vtysh_vrf_cmd);
2918 install_element(CONFIG_NODE, &vtysh_no_vrf_cmd);
2919
2920 /* "write terminal" command. */
2921 install_element(ENABLE_NODE, &vtysh_write_terminal_cmd);
2922
2923 install_element(CONFIG_NODE, &vtysh_integrated_config_cmd);
2924 install_element(CONFIG_NODE, &no_vtysh_integrated_config_cmd);
2925
2926 /* "write memory" command. */
2927 install_element(ENABLE_NODE, &vtysh_write_memory_cmd);
2928
2929 install_element(VIEW_NODE, &vtysh_terminal_length_cmd);
2930 install_element(VIEW_NODE, &vtysh_terminal_no_length_cmd);
2931 install_element(VIEW_NODE, &vtysh_show_daemons_cmd);
2932
2933 install_element(VIEW_NODE, &vtysh_ping_cmd);
2934 install_element(VIEW_NODE, &vtysh_ping_ip_cmd);
2935 install_element(VIEW_NODE, &vtysh_traceroute_cmd);
2936 install_element(VIEW_NODE, &vtysh_traceroute_ip_cmd);
2937 install_element(VIEW_NODE, &vtysh_ping6_cmd);
2938 install_element(VIEW_NODE, &vtysh_traceroute6_cmd);
576b6b5d 2939#if defined(HAVE_SHELL_ACCESS)
ac4d0be5 2940 install_element(VIEW_NODE, &vtysh_telnet_cmd);
2941 install_element(VIEW_NODE, &vtysh_telnet_port_cmd);
2942 install_element(VIEW_NODE, &vtysh_ssh_cmd);
4eeccf18 2943#endif
576b6b5d 2944#if defined(HAVE_SHELL_ACCESS)
ac4d0be5 2945 install_element(ENABLE_NODE, &vtysh_start_shell_cmd);
2946 install_element(ENABLE_NODE, &vtysh_start_bash_cmd);
2947 install_element(ENABLE_NODE, &vtysh_start_zsh_cmd);
576b6b5d
DS
2948#endif
2949
ac4d0be5 2950 install_element(VIEW_NODE, &vtysh_show_memory_cmd);
2951 install_element(VIEW_NODE, &vtysh_show_modules_cmd);
2952
2953 install_element(VIEW_NODE, &vtysh_show_work_queues_cmd);
2954 install_element(VIEW_NODE, &vtysh_show_work_queues_daemon_cmd);
2955
2956 install_element(VIEW_NODE, &vtysh_show_thread_cmd);
2957
2958 /* Logging */
2959 install_element(VIEW_NODE, &vtysh_show_logging_cmd);
2960 install_element(CONFIG_NODE, &vtysh_log_stdout_cmd);
2961 install_element(CONFIG_NODE, &vtysh_log_stdout_level_cmd);
2962 install_element(CONFIG_NODE, &no_vtysh_log_stdout_cmd);
2963 install_element(CONFIG_NODE, &vtysh_log_file_cmd);
2964 install_element(CONFIG_NODE, &vtysh_log_file_level_cmd);
2965 install_element(CONFIG_NODE, &no_vtysh_log_file_cmd);
2966 install_element(CONFIG_NODE, &vtysh_log_monitor_cmd);
2967 install_element(CONFIG_NODE, &no_vtysh_log_monitor_cmd);
2968 install_element(CONFIG_NODE, &vtysh_log_syslog_cmd);
2969 install_element(CONFIG_NODE, &no_vtysh_log_syslog_cmd);
2970 install_element(CONFIG_NODE, &vtysh_log_trap_cmd);
2971 install_element(CONFIG_NODE, &no_vtysh_log_trap_cmd);
2972 install_element(CONFIG_NODE, &vtysh_log_facility_cmd);
2973 install_element(CONFIG_NODE, &no_vtysh_log_facility_cmd);
2974 install_element(CONFIG_NODE, &vtysh_log_record_priority_cmd);
2975 install_element(CONFIG_NODE, &no_vtysh_log_record_priority_cmd);
2976 install_element(CONFIG_NODE, &vtysh_log_timestamp_precision_cmd);
2977 install_element(CONFIG_NODE, &no_vtysh_log_timestamp_precision_cmd);
2978
2979 install_element(CONFIG_NODE, &vtysh_service_password_encrypt_cmd);
2980 install_element(CONFIG_NODE, &no_vtysh_service_password_encrypt_cmd);
2981
2982 install_element(CONFIG_NODE, &vtysh_password_cmd);
2983 install_element(CONFIG_NODE, &vtysh_password_text_cmd);
2984 install_element(CONFIG_NODE, &vtysh_enable_password_cmd);
2985 install_element(CONFIG_NODE, &vtysh_enable_password_text_cmd);
2986 install_element(CONFIG_NODE, &no_vtysh_enable_password_cmd);
718e3744 2987}