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