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