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