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