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