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