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