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