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