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