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