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