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