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