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