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