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