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