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