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