]> git.proxmox.com Git - mirror_frr.git/blame - vtysh/vtysh.c
lib: adapt to version 2 of libyang
[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"
d7b86ae4 41#include "vtysh/vtysh_daemons.h"
6099b3b5 42#include "log.h"
13460c44 43#include "ns.h"
cd2a8a42 44#include "vrf.h"
eb05883f 45#include "libfrr.h"
26fbe472 46#include "command_graph.h"
2cddf2ff 47#include "frrstr.h"
ed8841d3 48#include "json.h"
1f9128d6 49#include "ferr.h"
718e3744 50
bf8d3d6a 51DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CMD, "Vtysh cmd copy");
4a1ab8e4 52
718e3744 53/* Struct VTY. */
54struct vty *vty;
55
56/* VTY shell pager name. */
57char *vtysh_pager_name = NULL;
58
2cddf2ff 59/* VTY shell client structure */
d62a17ae 60struct vtysh_client {
61 int fd;
62 const char *name;
63 int flag;
64 char path[MAXPATHLEN];
65 struct vtysh_client *next;
7c8ff89e
DS
66};
67
2cddf2ff
QY
68/* Some utility functions for working on vtysh-specific vty tasks */
69
70static FILE *vty_open_pager(struct vty *vty)
71{
72 if (vty->is_paged)
73 return vty->of;
74
5d806ec6
QY
75 if (!vtysh_pager_name)
76 return NULL;
77
2cddf2ff
QY
78 vty->of_saved = vty->of;
79 vty->of = popen(vtysh_pager_name, "w");
80 if (vty->of == NULL) {
81 vty->of = vty->of_saved;
82 perror("popen");
83 exit(1);
84 }
85
86 vty->is_paged = true;
87
88 return vty->of;
89}
90
91static int vty_close_pager(struct vty *vty)
92{
93 if (!vty->is_paged)
94 return 0;
95
96 fflush(vty->of);
97 if (pclose(vty->of) == -1) {
98 perror("pclose");
99 exit(1);
100 }
101
102 vty->of = vty->of_saved;
103 vty->is_paged = false;
104
105 return 0;
106}
107
1569f224 108static void vtysh_pager_envdef(bool fallback)
2cddf2ff
QY
109{
110 char *pager_defined;
111
112 pager_defined = getenv("VTYSH_PAGER");
113
114 if (pager_defined)
115 vtysh_pager_name = strdup(pager_defined);
1569f224 116 else if (fallback)
2cddf2ff
QY
117 vtysh_pager_name = strdup(VTYSH_PAGER);
118}
119
120/* --- */
121
d62a17ae 122struct vtysh_client vtysh_client[] = {
123 {.fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .next = NULL},
124 {.fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .next = NULL},
125 {.fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .next = NULL},
126 {.fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .next = NULL},
127 {.fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .next = NULL},
128 {.fd = -1, .name = "ldpd", .flag = VTYSH_LDPD, .next = NULL},
129 {.fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .next = NULL},
130 {.fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .next = NULL},
131 {.fd = -1, .name = "pimd", .flag = VTYSH_PIMD, .next = NULL},
132 {.fd = -1, .name = "nhrpd", .flag = VTYSH_NHRPD, .next = NULL},
133 {.fd = -1, .name = "eigrpd", .flag = VTYSH_EIGRPD, .next = NULL},
134 {.fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .next = NULL},
996c9314 135 {.fd = -1, .name = "sharpd", .flag = VTYSH_SHARPD, .next = NULL},
770ccdf8 136 {.fd = -1, .name = "fabricd", .flag = VTYSH_FABRICD, .next = NULL},
d62a17ae 137 {.fd = -1, .name = "watchfrr", .flag = VTYSH_WATCHFRR, .next = NULL},
e5c83d9b 138 {.fd = -1, .name = "pbrd", .flag = VTYSH_PBRD, .next = NULL},
7e24fdf3 139 {.fd = -1, .name = "staticd", .flag = VTYSH_STATICD, .next = NULL},
c2f29cf3 140 {.fd = -1, .name = "bfdd", .flag = VTYSH_BFDD, .next = NULL},
a8144d7f 141 {.fd = -1, .name = "vrrpd", .flag = VTYSH_VRRPD, .next = NULL},
4d7b695d 142 {.fd = -1, .name = "pathd", .flag = VTYSH_PATHD, .next = NULL},
b1aa147d 143};
144
2d96ff08
SW
145/* Searches for client by name, returns index */
146static int vtysh_client_lookup(const char *name)
147{
148 int idx = -1;
149
150 for (unsigned int i = 0; i < array_size(vtysh_client); i++) {
151 if (strmatch(vtysh_client[i].name, name)) {
152 idx = i;
153 break;
154 }
155 }
156
157 return idx;
158}
159
d62a17ae 160enum vtysh_write_integrated vtysh_write_integrated =
161 WRITE_INTEGRATED_UNSPECIFIED;
e7168df4 162
67736451
MS
163static int vtysh_reconnect(struct vtysh_client *vclient);
164
d62a17ae 165static void vclient_close(struct vtysh_client *vclient)
718e3744 166{
d62a17ae 167 if (vclient->fd >= 0) {
52038aca
QY
168 if (vty->of)
169 vty_out(vty,
170 "Warning: closing connection to %s because of an I/O error!\n",
171 vclient->name);
d62a17ae 172 close(vclient->fd);
67736451
MS
173 /* indicate as candidate for reconnect */
174 vclient->fd = VTYSH_WAS_ACTIVE;
d62a17ae 175 }
718e3744 176}
177
2cddf2ff
QY
178/*
179 * Send a CLI command to a client and read the response.
180 *
181 * Output will be printed to vty->of. If you want to suppress output, set that
182 * to NULL.
183 *
184 * vclient
185 * the client to send the command to
186 *
187 * line
188 * the command to send
189 *
190 * callback
191 * if non-null, this will be called with each line of output received from
192 * the client passed in the second parameter
193 *
194 * cbarg
195 * optional first argument to pass to callback
196 *
197 * Returns:
198 * a status code
199 */
d62a17ae 200static int vtysh_client_run(struct vtysh_client *vclient, const char *line,
2cddf2ff 201 void (*callback)(void *, const char *), void *cbarg)
d62a17ae 202{
203 int ret;
204 char stackbuf[4096];
205 char *buf = stackbuf;
206 size_t bufsz = sizeof(stackbuf);
207 char *bufvalid, *end = NULL;
208 char terminator[3] = {0, 0, 0};
209
67736451
MS
210 /* vclinet was previously active, try to reconnect */
211 if (vclient->fd == VTYSH_WAS_ACTIVE) {
212 ret = vtysh_reconnect(vclient);
213 if (ret < 0)
214 goto out_err;
215 }
216
d62a17ae 217 if (vclient->fd < 0)
218 return CMD_SUCCESS;
219
220 ret = write(vclient->fd, line, strlen(line) + 1);
67736451
MS
221 if (ret <= 0) {
222 /* close connection and try to reconnect */
223 vclient_close(vclient);
224 ret = vtysh_reconnect(vclient);
225 if (ret < 0)
226 goto out_err;
227 /* retry line */
228 ret = write(vclient->fd, line, strlen(line) + 1);
229 if (ret <= 0)
230 goto out_err;
231 }
d62a17ae 232
233 bufvalid = buf;
234 do {
235 ssize_t nread =
acf59d7a 236 read(vclient->fd, bufvalid, buf + bufsz - bufvalid - 1);
d62a17ae 237
238 if (nread < 0 && (errno == EINTR || errno == EAGAIN))
239 continue;
240
241 if (nread <= 0) {
52038aca
QY
242 if (vty->of)
243 vty_out(vty,
244 "vtysh: error reading from %s: %s (%d)",
245 vclient->name, safe_strerror(errno),
246 errno);
d62a17ae 247 goto out_err;
248 }
249
250 bufvalid += nread;
251
acf59d7a
QY
252 /* Null terminate so we may pass this to *printf later. */
253 bufvalid[0] = '\0';
254
fe53c680
QY
255 /*
256 * We expect string output from daemons, so instead of looking
257 * for the full 3 null bytes of the terminator, we check for
258 * just one instead and assume it is the first byte of the
259 * terminator. The presence of the full terminator is checked
260 * later.
261 */
08ee8e22 262 if (bufvalid - buf >= 4)
fe53c680 263 end = memmem(bufvalid - 4, 4, "\0", 1);
d62a17ae 264
08ee8e22
QY
265 /*
266 * calculate # bytes we have, up to & not including the
267 * terminator if present
268 */
269 size_t textlen = (end ? end : bufvalid) - buf;
fe53c680 270 bool b = false;
08ee8e22
QY
271
272 /* feed line processing callback if present */
273 while (callback && bufvalid > buf && (end > buf || !end)) {
274 textlen = (end ? end : bufvalid) - buf;
d62a17ae 275 char *eol = memchr(buf, '\n', textlen);
276 if (eol)
277 /* line break */
278 *eol++ = '\0';
279 else if (end == buf)
fe53c680
QY
280 /*
281 * no line break, end of input, no text left
282 * before end; nothing to write
283 */
284 b = true;
d62a17ae 285 else if (end)
fe53c680 286 /* no nl, end of input, but some text left */
d62a17ae 287 eol = end;
acf59d7a 288 else if (bufvalid == buf + bufsz - 1) {
fe53c680
QY
289 /*
290 * no nl, no end of input, no buffer space;
291 * realloc
292 */
293 char *new;
294
295 bufsz *= 2;
296 if (buf == stackbuf) {
297 new = XMALLOC(MTYPE_TMP, bufsz);
298 memcpy(new, stackbuf, sizeof(stackbuf));
299 } else
300 new = XREALLOC(MTYPE_TMP, buf, bufsz);
301
302 bufvalid = bufvalid - buf + new;
303 buf = new;
304 /* if end != NULL, we won't be reading more
305 * data... */
306 assert(end == NULL);
307 b = true;
308 } else
309 b = true;
310
311 if (b)
d62a17ae 312 break;
313
08ee8e22 314 /* eol is at line end now, either \n => \0 or \0\0\0 */
d62a17ae 315 assert(eol && eol <= bufvalid);
316
2cddf2ff
QY
317 if (vty->of)
318 vty_out(vty, "%s\n", buf);
319
320 callback(cbarg, buf);
d62a17ae 321
fe53c680 322 /* shift back data and adjust bufvalid */
d62a17ae 323 memmove(buf, eol, bufvalid - eol);
324 bufvalid -= eol - buf;
325 if (end)
326 end -= eol - buf;
327 }
328
08ee8e22
QY
329 /* else if no callback, dump raw */
330 if (!callback) {
2cddf2ff
QY
331 if (vty->of)
332 vty_out(vty, "%s", buf);
08ee8e22
QY
333 memmove(buf, buf + textlen, bufvalid - buf - textlen);
334 bufvalid -= textlen;
fe53c680
QY
335 if (end)
336 end -= textlen;
337
338 /*
339 * ----------------------------------------------------
340 * At this point `buf` should be in one of two states:
341 * - Empty (i.e. buf == bufvalid)
342 * - Contains up to 4 bytes of the terminator
343 * ----------------------------------------------------
344 */
345 assert(((buf == bufvalid)
346 || (bufvalid - buf <= 4 && buf[0] == 0x00)));
08ee8e22
QY
347 }
348
fe53c680
QY
349 /* if we have the terminator, break */
350 if (end && bufvalid - buf == 4) {
351 assert(!memcmp(buf, terminator, 3));
352 ret = buf[3];
353 break;
d62a17ae 354 }
fe53c680
QY
355
356 } while (true);
d62a17ae 357 goto out;
7526a182
DL
358
359out_err:
d62a17ae 360 vclient_close(vclient);
361 ret = CMD_SUCCESS;
7526a182 362out:
d62a17ae 363 if (buf != stackbuf)
364 XFREE(MTYPE_TMP, buf);
365 return ret;
718e3744 366}
367
d62a17ae 368static int vtysh_client_run_all(struct vtysh_client *head_client,
2cddf2ff 369 const char *line, int continue_on_err,
d62a17ae 370 void (*callback)(void *, const char *),
371 void *cbarg)
7c8ff89e 372{
d62a17ae 373 struct vtysh_client *client;
374 int rc, rc_all = CMD_SUCCESS;
a3d826f0 375 int correct_instance = 0, wrong_instance = 0;
7c8ff89e 376
d62a17ae 377 for (client = head_client; client; client = client->next) {
2cddf2ff 378 rc = vtysh_client_run(client, line, callback, cbarg);
a3d826f0
CS
379 if (rc == CMD_NOT_MY_INSTANCE) {
380 wrong_instance++;
381 continue;
382 }
91fd1b8d
QY
383 if (client->fd > 0)
384 correct_instance++;
d62a17ae 385 if (rc != CMD_SUCCESS) {
386 if (!continue_on_err)
387 return rc;
388 rc_all = rc;
389 }
390 }
52038aca 391 if (wrong_instance && !correct_instance && vty->of) {
2cddf2ff 392 vty_out(vty,
b4e197b5 393 "%% [%s]: command ignored as it targets an instance that is not running\n",
a3d826f0 394 head_client->name);
ac28e4ec 395 rc_all = CMD_WARNING_CONFIG_FAILED;
a3d826f0 396 }
d62a17ae 397 return rc_all;
7526a182
DL
398}
399
2cddf2ff
QY
400/*
401 * Execute command against all daemons.
402 *
403 * head_client
404 * where to start walking in the daemon list
405 *
406 * line
407 * the specific command to execute
408 *
409 * Returns:
410 * a status code
411 */
d62a17ae 412static int vtysh_client_execute(struct vtysh_client *head_client,
2cddf2ff 413 const char *line)
7526a182 414{
2cddf2ff 415 return vtysh_client_run_all(head_client, line, 0, NULL, NULL);
7526a182
DL
416}
417
2d96ff08
SW
418/* Execute by name */
419static int vtysh_client_execute_name(const char *name, const char *line)
420{
421 int ret = CMD_SUCCESS;
422 int idx_client = -1;
423
424 idx_client = vtysh_client_lookup(name);
425 if (idx_client != -1)
426 ret = vtysh_client_execute(&vtysh_client[idx_client], line);
427 else {
428 vty_out(vty, "Client not found\n");
429 ret = CMD_WARNING;
430 }
431
432 return ret;
433}
434
2cddf2ff
QY
435/*
436 * Retrieve all running config from daemons and parse it with the vtysh config
437 * parser. Returned output is not displayed to the user.
438 *
439 * head_client
440 * where to start walking in the daemon list
441 *
442 * line
443 * the specific command to execute
444 */
d62a17ae 445static void vtysh_client_config(struct vtysh_client *head_client, char *line)
7526a182 446{
a23587fa
DL
447 /* watchfrr currently doesn't load any config, and has some hardcoded
448 * settings that show up in "show run". skip it here (for now at
449 * least) so we don't get that mangled up in config-write.
450 */
451 if (head_client->flag == VTYSH_WATCHFRR)
452 return;
453
2cddf2ff
QY
454 /* suppress output to user */
455 vty->of_saved = vty->of;
456 vty->of = NULL;
457 vtysh_client_run_all(head_client, line, 1, vtysh_config_parse_line,
458 NULL);
459 vty->of = vty->of_saved;
718e3744 460}
461
462/* Command execution over the vty interface. */
d62a17ae 463static int vtysh_execute_func(const char *line, int pager)
464{
465 int ret, cmd_stat;
d7c0a89a 466 unsigned int i;
d62a17ae 467 vector vline;
468 const struct cmd_element *cmd;
d62a17ae 469 int tried = 0;
470 int saved_ret, saved_node;
471
472 /* Split readline string up into the vector. */
473 vline = cmd_make_strvec(line);
474
475 if (vline == NULL)
476 return CMD_SUCCESS;
477
86b28610
LB
478 if (user_mode) {
479 if (strncmp("en", vector_slot(vline, 0), 2) == 0) {
9d144835 480 cmd_free_strvec(vline);
2cddf2ff 481 vty_out(vty, "%% Command not allowed: enable\n");
86b28610
LB
482 return CMD_WARNING;
483 }
484 }
485
2cddf2ff 486 saved_ret = ret = cmd_execute(vty, line, &cmd, 1);
d62a17ae 487 saved_node = vty->node;
488
76015847
QY
489 /*
490 * If command doesn't succeeded in current node, try to walk up in node
491 * tree. Changing vty->node is enough to try it just out without actual
492 * walkup in the vtysh.
493 */
d62a17ae 494 while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON
495 && ret != CMD_WARNING && ret != CMD_WARNING_CONFIG_FAILED
496 && vty->node > CONFIG_NODE) {
497 vty->node = node_parent(vty->node);
2cddf2ff 498 ret = cmd_execute(vty, line, &cmd, 1);
d62a17ae 499 tried++;
65efcfce 500 }
d62a17ae 501
502 vty->node = saved_node;
503
76015847
QY
504 /*
505 * If command succeeded in any other node than current (tried > 0) we
506 * have to move into node in the vtysh where it succeeded.
507 */
d62a17ae 508 if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON
509 || ret == CMD_WARNING) {
510 if ((saved_node == BGP_VPNV4_NODE
511 || saved_node == BGP_VPNV6_NODE
512 || saved_node == BGP_IPV4_NODE
513 || saved_node == BGP_IPV6_NODE
e7d78d0f
PG
514 || saved_node == BGP_FLOWSPECV4_NODE
515 || saved_node == BGP_FLOWSPECV6_NODE
d62a17ae 516 || saved_node == BGP_IPV4M_NODE
517 || saved_node == BGP_IPV4L_NODE
518 || saved_node == BGP_IPV6L_NODE
519 || saved_node == BGP_IPV6M_NODE
983bd6f7
RW
520 || saved_node == BGP_EVPN_NODE
521 || saved_node == LDP_IPV4_NODE
522 || saved_node == LDP_IPV6_NODE)
d62a17ae 523 && (tried == 1)) {
524 vtysh_execute("exit-address-family");
525 } else if ((saved_node == BGP_EVPN_VNI_NODE) && (tried == 1)) {
526 vtysh_execute("exit-vni");
527 } else if (saved_node == BGP_VRF_POLICY_NODE && (tried == 1)) {
528 vtysh_execute("exit-vrf-policy");
529 } else if ((saved_node == BGP_VNC_DEFAULTS_NODE
530 || saved_node == BGP_VNC_NVE_GROUP_NODE
531 || saved_node == BGP_VNC_L2_GROUP_NODE)
532 && (tried == 1)) {
533 vtysh_execute("exit-vnc");
16d6ea59
QY
534 } else if (saved_node == VRF_NODE && (tried == 1)) {
535 vtysh_execute("exit-vrf");
d62a17ae 536 } else if ((saved_node == KEYCHAIN_KEY_NODE
537 || saved_node == LDP_PSEUDOWIRE_NODE
538 || saved_node == LDP_IPV4_IFACE_NODE
b9c7bc5a 539 || saved_node == LDP_IPV6_IFACE_NODE)
d62a17ae 540 && (tried == 1)) {
541 vtysh_execute("exit");
4d7b695d
SM
542 } else if ((saved_node == SR_SEGMENT_LIST_NODE
543 || saved_node == SR_POLICY_NODE
efba0985
SM
544 || saved_node == SR_CANDIDATE_DYN_NODE
545 || saved_node == PCEP_NODE
546 || saved_node == PCEP_PCE_CONFIG_NODE
547 || saved_node == PCEP_PCE_NODE
548 || saved_node == PCEP_PCC_NODE)
549 && (tried > 0)) {
4d7b695d 550 vtysh_execute("exit");
d62a17ae 551 } else if (tried) {
552 vtysh_execute("end");
dc1c13c0 553 vtysh_execute("configure");
d62a17ae 554 }
13bfca7a 555 }
76015847
QY
556 /*
557 * If command didn't succeed in any node, continue with return value
558 * from first try.
559 */
d62a17ae 560 else if (tried) {
561 ret = saved_ret;
13bfca7a 562 }
718e3744 563
d62a17ae 564 cmd_free_strvec(vline);
565
566 cmd_stat = ret;
567 switch (ret) {
568 case CMD_WARNING:
569 case CMD_WARNING_CONFIG_FAILED:
570 if (vty->type == VTY_FILE)
2cddf2ff 571 vty_out(vty, "Warning...\n");
d62a17ae 572 break;
573 case CMD_ERR_AMBIGUOUS:
2cddf2ff 574 vty_out(vty, "%% Ambiguous command: %s\n", line);
d62a17ae 575 break;
576 case CMD_ERR_NO_MATCH:
2cddf2ff 577 vty_out(vty, "%% Unknown command: %s\n", line);
d62a17ae 578 break;
579 case CMD_ERR_INCOMPLETE:
2cddf2ff 580 vty_out(vty, "%% Command incomplete: %s\n", line);
d62a17ae 581 break;
582 case CMD_SUCCESS_DAEMON: {
193a5a95
QY
583 /*
584 * FIXME: Don't open pager for exit commands. popen() causes
585 * problems if exited from vtysh at all. This hack shouldn't
586 * cause any problem but is really ugly.
587 */
2cddf2ff
QY
588 if (pager && strncmp(line, "exit", 4))
589 vty_open_pager(vty);
d62a17ae 590
dc1c13c0 591 if (!strcmp(cmd->string, "configure")) {
d62a17ae 592 for (i = 0; i < array_size(vtysh_client); i++) {
593 cmd_stat = vtysh_client_execute(
2cddf2ff 594 &vtysh_client[i], line);
d62a17ae 595 if (cmd_stat == CMD_WARNING)
596 break;
597 }
598
599 if (cmd_stat) {
600 line = "end";
601 vline = cmd_make_strvec(line);
602
a0c14c54 603
604 if (vline == NULL) {
605 if (vty->is_paged)
606 vty_close_pager(vty);
d62a17ae 607 return CMD_SUCCESS;
608 }
609
610 ret = cmd_execute_command(vline, vty, &cmd, 1);
611 cmd_free_strvec(vline);
612 if (ret != CMD_SUCCESS_DAEMON)
613 break;
614 } else if (cmd->func) {
615 (*cmd->func)(cmd, vty, 0, NULL);
616 break;
617 }
b094d260 618 }
718e3744 619
d62a17ae 620 cmd_stat = CMD_SUCCESS;
2a191994 621 struct vtysh_client *vc;
d62a17ae 622 for (i = 0; i < array_size(vtysh_client); i++) {
623 if (cmd->daemon & vtysh_client[i].flag) {
67736451
MS
624 if (vtysh_client[i].fd < 0
625 && (cmd->daemon == vtysh_client[i].flag)) {
626 for (vc = &vtysh_client[i]; vc;
627 vc = vc->next)
b2443937 628 if (vc->fd == VTYSH_WAS_ACTIVE)
67736451
MS
629 vtysh_reconnect(vc);
630 }
cde69cc2
QY
631 if (vtysh_client[i].fd < 0
632 && (cmd->daemon == vtysh_client[i].flag)) {
2a191994
QY
633 bool any_inst = false;
634 for (vc = &vtysh_client[i]; vc;
635 vc = vc->next)
636 any_inst = any_inst
637 || (vc->fd > 0);
91fd1b8d 638 if (!any_inst) {
2a191994
QY
639 fprintf(stderr,
640 "%s is not running\n",
641 vtysh_client[i].name);
91fd1b8d
QY
642 continue;
643 }
cde69cc2 644 }
d62a17ae 645 cmd_stat = vtysh_client_execute(
2cddf2ff 646 &vtysh_client[i], line);
d62a17ae 647 if (cmd_stat != CMD_SUCCESS)
648 break;
649 }
650 }
b1aa147d 651 if (cmd_stat != CMD_SUCCESS)
d62a17ae 652 break;
653
654 if (cmd->func)
655 (*cmd->func)(cmd, vty, 0, NULL);
656 }
718e3744 657 }
2cddf2ff
QY
658 if (vty->is_paged)
659 vty_close_pager(vty);
660
d62a17ae 661 return cmd_stat;
718e3744 662}
663
d62a17ae 664int vtysh_execute_no_pager(const char *line)
718e3744 665{
d62a17ae 666 return vtysh_execute_func(line, 0);
718e3744 667}
668
d62a17ae 669int vtysh_execute(const char *line)
718e3744 670{
d62a17ae 671 return vtysh_execute_func(line, 1);
718e3744 672}
673
d62a17ae 674static char *trim(char *s)
a5b89524 675{
d62a17ae 676 size_t size;
677 char *end;
a5b89524 678
d62a17ae 679 size = strlen(s);
a5b89524 680
d62a17ae 681 if (!size)
682 return s;
a5b89524 683
d62a17ae 684 end = s + size - 1;
fefa5e0f 685 while (end >= s && isspace((unsigned char)*end))
d62a17ae 686 end--;
687 *(end + 1) = '\0';
a5b89524 688
fefa5e0f 689 while (*s && isspace((unsigned char)*s))
d62a17ae 690 s++;
a5b89524 691
d62a17ae 692 return s;
a5b89524
DW
693}
694
d62a17ae 695int vtysh_mark_file(const char *filename)
0846286b 696{
d62a17ae 697 struct vty *vty;
698 FILE *confp = NULL;
699 int ret;
700 vector vline;
701 int tried = 0;
4d7b695d 702 bool ending;
d62a17ae 703 const struct cmd_element *cmd;
704 int saved_ret, prev_node;
705 int lineno = 0;
706 char *vty_buf_copy = NULL;
707 char *vty_buf_trimmed = NULL;
0846286b 708
d62a17ae 709 if (strncmp("-", filename, 1) == 0)
710 confp = stdin;
711 else
712 confp = fopen(filename, "r");
0846286b 713
d62a17ae 714 if (confp == NULL) {
715 fprintf(stderr, "%% Can't open config file %s due to '%s'.\n",
716 filename, safe_strerror(errno));
95f7965d 717 return CMD_ERR_NO_FILE;
d62a17ae 718 }
0846286b 719
d62a17ae 720 vty = vty_new();
812f0880 721 vty->wfd = STDOUT_FILENO;
d62a17ae 722 vty->type = VTY_TERM;
723 vty->node = CONFIG_NODE;
0846286b 724
d62a17ae 725 vtysh_execute_no_pager("enable");
dc1c13c0 726 vtysh_execute_no_pager("configure");
d62a17ae 727 vty_buf_copy = XCALLOC(MTYPE_VTYSH_CMD, VTY_BUFSIZ);
0846286b 728
d62a17ae 729 while (fgets(vty->buf, VTY_BUFSIZ, confp)) {
730 lineno++;
731 tried = 0;
2e600d75 732 strlcpy(vty_buf_copy, vty->buf, VTY_BUFSIZ);
d62a17ae 733 vty_buf_trimmed = trim(vty_buf_copy);
0846286b 734
a701f7ea
RW
735 switch (vty->node) {
736 case LDP_IPV4_IFACE_NODE:
737 if (strncmp(vty_buf_copy, " ", 3)) {
609ac8dd 738 vty_out(vty, " exit-ldp-if\n");
a701f7ea
RW
739 vty->node = LDP_IPV4_NODE;
740 }
741 break;
742 case LDP_IPV6_IFACE_NODE:
743 if (strncmp(vty_buf_copy, " ", 3)) {
609ac8dd 744 vty_out(vty, " exit-ldp-if\n");
a701f7ea
RW
745 vty->node = LDP_IPV6_NODE;
746 }
747 break;
748 case LDP_PSEUDOWIRE_NODE:
749 if (strncmp(vty_buf_copy, " ", 2)) {
ccef6e47 750 vty_out(vty, " exit\n");
a701f7ea
RW
751 vty->node = LDP_L2VPN_NODE;
752 }
753 break;
4d7b695d
SM
754 case SR_CANDIDATE_DYN_NODE:
755 if (strncmp(vty_buf_copy, " ", 2)) {
756 vty_out(vty, " exit\n");
757 vty->node = SR_POLICY_NODE;
758 }
759 break;
a701f7ea
RW
760 default:
761 break;
762 }
763
d62a17ae 764 if (vty_buf_trimmed[0] == '!' || vty_buf_trimmed[0] == '#') {
2cddf2ff 765 vty_out(vty, "%s", vty->buf);
d62a17ae 766 continue;
767 }
0846286b 768
d62a17ae 769 /* Split readline string up into the vector. */
770 vline = cmd_make_strvec(vty->buf);
0846286b 771
d62a17ae 772 if (vline == NULL) {
2cddf2ff 773 vty_out(vty, "%s", vty->buf);
d62a17ae 774 continue;
775 }
0846286b 776
76015847
QY
777 /*
778 * Ignore the "end" lines, we will generate these where
779 * appropriate
780 */
d62a17ae 781 if (strlen(vty_buf_trimmed) == 3
782 && strncmp("end", vty_buf_trimmed, 3) == 0) {
44f12f20 783 cmd_free_strvec(vline);
d62a17ae 784 continue;
785 }
0846286b 786
d62a17ae 787 prev_node = vty->node;
788 saved_ret = ret = cmd_execute_command_strict(vline, vty, &cmd);
789
76015847
QY
790 /*
791 * If command doesn't succeeded in current node, try to walk up
792 * in node tree. Changing vty->node is enough to try it just
793 * out without actual walkup in the vtysh.
794 */
d62a17ae 795 while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON
796 && ret != CMD_WARNING && ret != CMD_WARNING_CONFIG_FAILED
797 && vty->node > CONFIG_NODE) {
798 vty->node = node_parent(vty->node);
799 ret = cmd_execute_command_strict(vline, vty, &cmd);
800 tried++;
801 }
0846286b 802
76015847
QY
803 /*
804 * If command succeeded in any other node than current (tried >
805 * 0) we have to move into node in the vtysh where it
806 * succeeded.
807 */
d62a17ae 808 if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON
809 || ret == CMD_WARNING) {
810 if ((prev_node == BGP_VPNV4_NODE
811 || prev_node == BGP_VPNV6_NODE
812 || prev_node == BGP_IPV4_NODE
813 || prev_node == BGP_IPV6_NODE
e7d78d0f
PG
814 || prev_node == BGP_FLOWSPECV4_NODE
815 || prev_node == BGP_FLOWSPECV6_NODE
d62a17ae 816 || prev_node == BGP_IPV4L_NODE
817 || prev_node == BGP_IPV6L_NODE
818 || prev_node == BGP_IPV4M_NODE
819 || prev_node == BGP_IPV6M_NODE
820 || prev_node == BGP_EVPN_NODE)
821 && (tried == 1)) {
2cddf2ff 822 vty_out(vty, "exit-address-family\n");
d62a17ae 823 } else if ((prev_node == BGP_EVPN_VNI_NODE)
824 && (tried == 1)) {
2cddf2ff 825 vty_out(vty, "exit-vni\n");
b9c7bc5a 826 } else if ((prev_node == KEYCHAIN_KEY_NODE)
d62a17ae 827 && (tried == 1)) {
b727c12a
PM
828 vty_out(vty, "exit\n");
829 } else if ((prev_node == BFD_PEER_NODE)
830 && (tried == 1)) {
2cddf2ff 831 vty_out(vty, "exit\n");
4d7b695d 832 } else if (((prev_node == SEGMENT_ROUTING_NODE)
efba0985
SM
833 || (prev_node == SR_TRAFFIC_ENG_NODE)
834 || (prev_node == SR_SEGMENT_LIST_NODE)
835 || (prev_node == SR_POLICY_NODE)
836 || (prev_node == SR_CANDIDATE_DYN_NODE)
837 || (prev_node == PCEP_NODE)
838 || (prev_node == PCEP_PCE_CONFIG_NODE)
839 || (prev_node == PCEP_PCE_NODE)
840 || (prev_node == PCEP_PCC_NODE))
4d7b695d
SM
841 && (tried > 0)) {
842 ending = (vty->node != SEGMENT_ROUTING_NODE)
efba0985
SM
843 && (vty->node != SR_TRAFFIC_ENG_NODE)
844 && (vty->node != SR_SEGMENT_LIST_NODE)
845 && (vty->node != SR_POLICY_NODE)
846 && (vty->node != SR_CANDIDATE_DYN_NODE)
847 && (vty->node != PCEP_NODE)
848 && (vty->node != PCEP_PCE_CONFIG_NODE)
849 && (vty->node != PCEP_PCE_NODE)
850 && (vty->node != PCEP_PCC_NODE);
4d7b695d
SM
851 if (ending)
852 tried--;
853 while (tried-- > 0)
854 vty_out(vty, "exit\n");
855 if (ending)
856 vty_out(vty, "end\n");
d62a17ae 857 } else if (tried) {
2cddf2ff 858 vty_out(vty, "end\n");
d62a17ae 859 }
860 }
76015847
QY
861 /*
862 * If command didn't succeed in any node, continue with return
863 * value from first try.
864 */
d62a17ae 865 else if (tried) {
866 ret = saved_ret;
867 vty->node = prev_node;
868 }
869
870 cmd_free_strvec(vline);
871 switch (ret) {
872 case CMD_WARNING:
873 case CMD_WARNING_CONFIG_FAILED:
874 if (vty->type == VTY_FILE)
875 fprintf(stderr, "line %d: Warning...: %s\n",
876 lineno, vty->buf);
877 fclose(confp);
878 vty_close(vty);
879 XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
880 return ret;
881 case CMD_ERR_AMBIGUOUS:
882 fprintf(stderr, "line %d: %% Ambiguous command: %s\n",
883 lineno, vty->buf);
884 fclose(confp);
885 vty_close(vty);
886 XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
887 return CMD_ERR_AMBIGUOUS;
888 case CMD_ERR_NO_MATCH:
889 fprintf(stderr, "line %d: %% Unknown command: %s\n",
890 lineno, vty->buf);
891 fclose(confp);
892 vty_close(vty);
893 XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
894 return CMD_ERR_NO_MATCH;
895 case CMD_ERR_INCOMPLETE:
896 fprintf(stderr, "line %d: %% Command incomplete: %s\n",
897 lineno, vty->buf);
898 fclose(confp);
899 vty_close(vty);
900 XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
901 return CMD_ERR_INCOMPLETE;
902 case CMD_SUCCESS:
2cddf2ff 903 vty_out(vty, "%s", vty->buf);
13f48fd6
QY
904 if (strmatch(vty_buf_trimmed, "exit-vrf"))
905 vty_out(vty, "end\n");
d62a17ae 906 break;
907 case CMD_SUCCESS_DAEMON: {
6d10727a 908 int cmd_stat;
d62a17ae 909
2cddf2ff 910 vty_out(vty, "%s", vty->buf);
13f48fd6
QY
911 if (strmatch(vty_buf_trimmed, "exit-vrf"))
912 vty_out(vty, "end\n");
2cddf2ff
QY
913 cmd_stat = vtysh_client_execute(&vtysh_client[0],
914 vty->buf);
d62a17ae 915 if (cmd_stat != CMD_SUCCESS)
916 break;
917
918 if (cmd->func)
919 (*cmd->func)(cmd, vty, 0, NULL);
920 }
921 }
0846286b 922 }
d62a17ae 923 /* This is the end */
2cddf2ff 924 vty_out(vty, "\nend\n");
d62a17ae 925 vty_close(vty);
926 XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);
0846286b 927
d62a17ae 928 if (confp != stdin)
929 fclose(confp);
0846286b 930
95f7965d 931 return 0;
0846286b
DS
932}
933
718e3744 934/* Configration make from file. */
d62a17ae 935int vtysh_config_from_file(struct vty *vty, FILE *fp)
936{
937 int ret;
938 const struct cmd_element *cmd;
939 int lineno = 0;
76015847 940 /* once we have an error, we remember & return that */
d62a17ae 941 int retcode = CMD_SUCCESS;
942
943 while (fgets(vty->buf, VTY_BUFSIZ, fp)) {
944 lineno++;
945
7ab57d19 946 ret = command_config_read_one_line(vty, &cmd, lineno, 1);
d62a17ae 947
948 switch (ret) {
949 case CMD_WARNING:
950 case CMD_WARNING_CONFIG_FAILED:
951 if (vty->type == VTY_FILE)
952 fprintf(stderr, "line %d: Warning[%d]...: %s\n",
953 lineno, vty->node, vty->buf);
76015847
QY
954 retcode = ret;
955
d62a17ae 956 break;
957 case CMD_ERR_AMBIGUOUS:
958 fprintf(stderr,
959 "line %d: %% Ambiguous command[%d]: %s\n",
960 lineno, vty->node, vty->buf);
76015847 961 retcode = CMD_ERR_AMBIGUOUS;
d62a17ae 962 break;
963 case CMD_ERR_NO_MATCH:
964 fprintf(stderr, "line %d: %% Unknown command[%d]: %s",
965 lineno, vty->node, vty->buf);
76015847 966 retcode = CMD_ERR_NO_MATCH;
d62a17ae 967 break;
968 case CMD_ERR_INCOMPLETE:
969 fprintf(stderr,
970 "line %d: %% Command incomplete[%d]: %s\n",
971 lineno, vty->node, vty->buf);
76015847 972 retcode = CMD_ERR_INCOMPLETE;
d62a17ae 973 break;
974 case CMD_SUCCESS_DAEMON: {
d7c0a89a 975 unsigned int i;
d62a17ae 976 int cmd_stat = CMD_SUCCESS;
977
978 for (i = 0; i < array_size(vtysh_client); i++) {
979 if (cmd->daemon & vtysh_client[i].flag) {
980 cmd_stat = vtysh_client_execute(
2cddf2ff 981 &vtysh_client[i], vty->buf);
d62a17ae 982 /*
983 * CMD_WARNING - Can mean that the
76015847
QY
984 * command was parsed successfully but
985 * it was already entered in a few
986 * spots. As such if we receive a
d62a17ae 987 * CMD_WARNING from a daemon we
76015847
QY
988 * shouldn't stop talking to the other
989 * daemons for the particular command.
d62a17ae 990 */
991 if (cmd_stat != CMD_SUCCESS
992 && cmd_stat != CMD_WARNING) {
993 fprintf(stderr,
994 "line %d: Failure to communicate[%d] to %s, line: %s\n",
995 lineno, cmd_stat,
996 vtysh_client[i].name,
997 vty->buf);
596074af 998 retcode = cmd_stat;
d62a17ae 999 break;
1000 }
1001 }
1002 }
1003 if (cmd_stat != CMD_SUCCESS)
1004 break;
1005
1006 if (cmd->func)
1007 (*cmd->func)(cmd, vty, 0, NULL);
1008 }
1009 }
1010 }
1011
1012 return (retcode);
1013}
1014
a4364a44
RM
1015/*
1016 * Function processes cli commands terminated with '?' character when entered
1017 * through either 'vtysh' or 'vtysh -c' interfaces.
1018 */
1019static int vtysh_process_questionmark(const char *input, int input_len)
718e3744 1020{
a4364a44 1021 int ret, width = 0;
d62a17ae 1022 unsigned int i;
a4364a44 1023 vector vline, describe;
d62a17ae 1024 struct cmd_token *token;
718e3744 1025
a4364a44
RM
1026 if (!input)
1027 return 1;
1028
1029 vline = cmd_make_strvec(input);
718e3744 1030
d62a17ae 1031 /* In case of '> ?'. */
1032 if (vline == NULL) {
1033 vline = vector_init(1);
1034 vector_set(vline, NULL);
fefa5e0f 1035 } else if (input_len && isspace((unsigned char)input[input_len - 1]))
d62a17ae 1036 vector_set(vline, NULL);
718e3744 1037
80c872f6
RW
1038 describe = cmd_describe_command(vline, vty, &ret);
1039
d62a17ae 1040 /* Ambiguous and no match error. */
1041 switch (ret) {
718e3744 1042 case CMD_ERR_AMBIGUOUS:
d62a17ae 1043 cmd_free_strvec(vline);
80c872f6 1044 vector_free(describe);
2cddf2ff
QY
1045 vty_out(vty, "%% Ambiguous command.\n");
1046 rl_on_new_line();
d62a17ae 1047 return 0;
718e3744 1048 case CMD_ERR_NO_MATCH:
d62a17ae 1049 cmd_free_strvec(vline);
9320658c
QY
1050 if (describe)
1051 vector_free(describe);
2cddf2ff
QY
1052 vty_out(vty, "%% There is no matched command.\n");
1053 rl_on_new_line();
d62a17ae 1054 return 0;
718e3744 1055 }
7f059ea6 1056
d62a17ae 1057 /* Get width of command string. */
1058 width = 0;
1059 for (i = 0; i < vector_active(describe); i++)
1060 if ((token = vector_slot(describe, i)) != NULL) {
1061 if (token->text[0] == '\0')
1062 continue;
7f059ea6 1063
d62a17ae 1064 int len = strlen(token->text);
1a0f614d 1065
d62a17ae 1066 if (width < len)
1067 width = len;
1068 }
1a0f614d 1069
d62a17ae 1070 for (i = 0; i < vector_active(describe); i++)
1071 if ((token = vector_slot(describe, i)) != NULL) {
1072 if (!token->desc)
2cddf2ff 1073 vty_out(vty, " %-s\n", token->text);
d62a17ae 1074 else
2cddf2ff
QY
1075 vty_out(vty, " %-*s %s\n", width, token->text,
1076 token->desc);
d62a17ae 1077
1078 if (IS_VARYING_TOKEN(token->type)) {
1079 const char *ref = vector_slot(
1080 vline, vector_active(vline) - 1);
1081
1082 vector varcomps = vector_init(VECTOR_MIN_SIZE);
1083 cmd_variable_complete(token, ref, varcomps);
1084
1085 if (vector_active(varcomps) > 0) {
1086 int rows, cols;
1087 rl_get_screen_size(&rows, &cols);
1088
1089 char *ac = cmd_variable_comp2str(
1090 varcomps, cols);
2cddf2ff 1091 vty_out(vty, "%s\n", ac);
d62a17ae 1092 XFREE(MTYPE_TMP, ac);
1093 }
1094
1095 vector_free(varcomps);
1096 }
1097 }
718e3744 1098
d62a17ae 1099 cmd_free_strvec(vline);
1100 vector_free(describe);
718e3744 1101
a4364a44
RM
1102 return 0;
1103}
1104
1105/*
1106 * Entry point for user commands terminated with '?' character and typed through
1107 * the usual vtysh's stdin interface. This is the function being registered with
1108 * readline() api's.
1109 */
b1599bb6 1110static int vtysh_rl_describe(int a, int b)
a4364a44
RM
1111{
1112 int ret;
1113
2cddf2ff 1114 vty_out(vty, "\n");
a4364a44
RM
1115
1116 ret = vtysh_process_questionmark(rl_line_buffer, rl_end);
d62a17ae 1117 rl_on_new_line();
718e3744 1118
a4364a44
RM
1119 return ret;
1120}
1121
1122/*
1123 * Function in charged of processing vtysh instructions terminating with '?'
1124 * character and received through the 'vtysh -c' interface. If user's
1125 * instruction is well-formatted, we will call the same processing routine
1126 * utilized by the traditional vtysh's stdin interface.
1127 */
1128int vtysh_execute_command_questionmark(char *input)
1129{
1130 int input_len, qmark_count = 0;
1131 const char *str;
1132
1133 if (!(input && *input))
1134 return 1;
1135
1136 /* Finding out question_mark count and strlen */
1137 for (str = input; *str; ++str) {
1138 if (*str == '?')
1139 qmark_count++;
1140 }
1141 input_len = str - input;
1142
1143 /*
1144 * Verify that user's input terminates in '?' and that patterns such as
1145 * 'cmd ? subcmd ?' are prevented.
1146 */
1147 if (qmark_count != 1 || input[input_len - 1] != '?')
1148 return 1;
1149
1150 /*
1151 * Questionmark-processing function is not expecting to receive '?'
1152 * character in input string.
1153 */
1154 input[input_len - 1] = '\0';
1155
1156 return vtysh_process_questionmark(input, input_len - 1);
718e3744 1157}
1158
95e735b5 1159/* Result of cmd_complete_command() call will be stored here
1160 * and used in new_completion() in order to put the space in
1161 * correct places only. */
718e3744 1162int complete_status;
1163
d62a17ae 1164static char *command_generator(const char *text, int state)
718e3744 1165{
d62a17ae 1166 vector vline;
1167 static char **matched = NULL;
1168 static int index = 0;
718e3744 1169
d62a17ae 1170 /* First call. */
1171 if (!state) {
1172 index = 0;
718e3744 1173
d62a17ae 1174 if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
1175 return NULL;
718e3744 1176
d62a17ae 1177 vline = cmd_make_strvec(rl_line_buffer);
1178 if (vline == NULL)
1179 return NULL;
718e3744 1180
fefa5e0f
DL
1181 if (rl_end &&
1182 isspace((unsigned char)rl_line_buffer[rl_end - 1]))
d62a17ae 1183 vector_set(vline, NULL);
718e3744 1184
d62a17ae 1185 matched = cmd_complete_command(vline, vty, &complete_status);
1186 cmd_free_strvec(vline);
1187 }
718e3744 1188
6df43392
IR
1189 if (matched && matched[index]) {
1190 XCOUNTFREE(MTYPE_COMPLETION, matched[index]);
d62a17ae 1191 return matched[index++];
6df43392 1192 }
718e3744 1193
d62a17ae 1194 XFREE(MTYPE_TMP, matched);
66d29a54 1195
d62a17ae 1196 return NULL;
718e3744 1197}
1198
7c70dc57 1199static char **new_completion(const char *text, int start, int end)
718e3744 1200{
d62a17ae 1201 char **matches;
718e3744 1202
d62a17ae 1203 matches = rl_completion_matches(text, command_generator);
718e3744 1204
d62a17ae 1205 if (matches) {
1206 rl_point = rl_end;
1207 if (complete_status != CMD_COMPLETE_FULL_MATCH)
1208 /* only append a space on full match */
1209 rl_completion_append_character = '\0';
1210 }
718e3744 1211
d62a17ae 1212 return matches;
718e3744 1213}
1214
95e735b5 1215/* Vty node structures. */
0eb5751d 1216#ifdef HAVE_BGPD
d62a17ae 1217static struct cmd_node bgp_node = {
f4b8291f 1218 .name = "bgp",
62b346ee 1219 .node = BGP_NODE,
24389580 1220 .parent_node = CONFIG_NODE,
62b346ee 1221 .prompt = "%s(config-router)# ",
718e3744 1222};
0eb5751d 1223#endif /* HAVE_BGPD */
718e3744 1224
d62a17ae 1225static struct cmd_node rip_node = {
f4b8291f 1226 .name = "rip",
62b346ee 1227 .node = RIP_NODE,
24389580 1228 .parent_node = CONFIG_NODE,
62b346ee 1229 .prompt = "%s(config-router)# ",
718e3744 1230};
1231
0eb5751d 1232#ifdef HAVE_ISISD
d62a17ae 1233static struct cmd_node isis_node = {
f4b8291f 1234 .name = "isis",
62b346ee 1235 .node = ISIS_NODE,
24389580 1236 .parent_node = CONFIG_NODE,
62b346ee 1237 .prompt = "%s(config-router)# ",
c25e458a 1238};
0eb5751d 1239#endif /* HAVE_ISISD */
c25e458a 1240
0eb5751d 1241#ifdef HAVE_FABRICD
770ccdf8 1242static struct cmd_node openfabric_node = {
f4b8291f 1243 .name = "openfabric",
62b346ee 1244 .node = OPENFABRIC_NODE,
24389580 1245 .parent_node = CONFIG_NODE,
62b346ee 1246 .prompt = "%s(config-router)# ",
770ccdf8 1247};
0eb5751d 1248#endif /* HAVE_FABRICD */
770ccdf8 1249
d62a17ae 1250static struct cmd_node interface_node = {
f4b8291f 1251 .name = "interface",
62b346ee 1252 .node = INTERFACE_NODE,
24389580 1253 .parent_node = CONFIG_NODE,
62b346ee 1254 .prompt = "%s(config-if)# ",
718e3744 1255};
1256
2dd0d726 1257static struct cmd_node pw_node = {
f4b8291f 1258 .name = "pw",
62b346ee 1259 .node = PW_NODE,
24389580 1260 .parent_node = CONFIG_NODE,
62b346ee 1261 .prompt = "%s(config-pw)# ",
2dd0d726
RW
1262};
1263
f7f6a796 1264#if defined(HAVE_PATHD)
4d7b695d
SM
1265static struct cmd_node segment_routing_node = {
1266 .name = "segment-routing",
1267 .node = SEGMENT_ROUTING_NODE,
1268 .parent_node = CONFIG_NODE,
1269 .prompt = "%s(config-sr)# ",
1270};
1271
1272static struct cmd_node sr_traffic_eng_node = {
1273 .name = "sr traffic-eng",
1274 .node = SR_TRAFFIC_ENG_NODE,
1275 .parent_node = SEGMENT_ROUTING_NODE,
1276 .prompt = "%s(config-sr-te)# ",
1277};
1278
1279static struct cmd_node srte_segment_list_node = {
1280 .name = "srte segment-list",
1281 .node = SR_SEGMENT_LIST_NODE,
1282 .parent_node = SR_TRAFFIC_ENG_NODE,
1283 .prompt = "%s(config-sr-te-segment-list)# ",
1284};
1285
1286static struct cmd_node srte_policy_node = {
1287 .name = "srte policy",
1288 .node = SR_POLICY_NODE,
1289 .parent_node = SR_TRAFFIC_ENG_NODE,
1290 .prompt = "%s(config-sr-te-policy)# ",
1291};
1292
1293static struct cmd_node srte_candidate_dyn_node = {
1294 .name = "srte candidate-dyn",
1295 .node = SR_CANDIDATE_DYN_NODE,
1296 .parent_node = SR_POLICY_NODE,
1297 .prompt = "%s(config-sr-te-candidate)# ",
1298};
1299
f7f6a796 1300#if defined(HAVE_PATHD_PCEP)
efba0985
SM
1301static struct cmd_node pcep_node = {
1302 .name = "srte pcep",
1303 .node = PCEP_NODE,
1304 .parent_node = SR_TRAFFIC_ENG_NODE,
1305 .prompt = "%s(config-sr-te-pcep)# "
1306};
1307
1308static struct cmd_node pcep_pcc_node = {
1309 .name = "srte pcep pcc",
1310 .node = PCEP_PCC_NODE,
1311 .parent_node = PCEP_NODE,
1312 .prompt = "%s(config-sr-te-pcep-pcc)# ",
1313};
1314
1315static struct cmd_node pcep_pce_node = {
1316 .name = "srte pcep pce-peer",
1317 .node = PCEP_PCE_NODE,
1318 .parent_node = PCEP_NODE,
1319 .prompt = "%s(config-sr-te-pcep-pce-peer)# ",
1320};
1321
1322static struct cmd_node pcep_pce_config_node = {
1323 .name = "srte pcep pce-config",
1324 .node = PCEP_PCE_CONFIG_NODE,
1325 .parent_node = PCEP_NODE,
1326 .prompt = "%s(pcep-sr-te-pcep-pce-config)# ",
1327};
f7f6a796
SM
1328#endif /* HAVE_PATHD_PCEP */
1329#endif /* HAVE_PATHD */
efba0985 1330
d62a17ae 1331static struct cmd_node vrf_node = {
f4b8291f 1332 .name = "vrf",
62b346ee 1333 .node = VRF_NODE,
24389580 1334 .parent_node = CONFIG_NODE,
62b346ee 1335 .prompt = "%s(config-vrf)# ",
e9d94ea7
DS
1336};
1337
e5c83d9b 1338static struct cmd_node nh_group_node = {
f4b8291f 1339 .name = "nexthop-group",
62b346ee 1340 .node = NH_GROUP_NODE,
24389580 1341 .parent_node = CONFIG_NODE,
62b346ee 1342 .prompt = "%s(config-nh-group)# ",
e5c83d9b
DS
1343};
1344
62b346ee 1345static struct cmd_node rmap_node = {
f4b8291f 1346 .name = "routemap",
62b346ee 1347 .node = RMAP_NODE,
24389580 1348 .parent_node = CONFIG_NODE,
62b346ee
DL
1349 .prompt = "%s(config-route-map)# ",
1350};
95e735b5 1351
0eb5751d 1352#ifdef HAVE_PBRD
62b346ee 1353static struct cmd_node pbr_map_node = {
f4b8291f 1354 .name = "pbr-map",
62b346ee 1355 .node = PBRMAP_NODE,
24389580 1356 .parent_node = CONFIG_NODE,
62b346ee
DL
1357 .prompt = "%s(config-pbr-map)# ",
1358};
0eb5751d 1359#endif /* HAVE_PBRD */
e5c83d9b 1360
62b346ee 1361static struct cmd_node zebra_node = {
f4b8291f 1362 .name = "zebra",
62b346ee 1363 .node = ZEBRA_NODE,
24389580 1364 .parent_node = CONFIG_NODE,
62b346ee
DL
1365 .prompt = "%s(config-router)# ",
1366};
95e735b5 1367
0eb5751d 1368#ifdef HAVE_BGPD
62b346ee 1369static struct cmd_node bgp_vpnv4_node = {
f4b8291f 1370 .name = "bgp vpnv4",
62b346ee 1371 .node = BGP_VPNV4_NODE,
24389580 1372 .parent_node = BGP_NODE,
62b346ee
DL
1373 .prompt = "%s(config-router-af)# ",
1374};
95e735b5 1375
62b346ee 1376static struct cmd_node bgp_vpnv6_node = {
f4b8291f 1377 .name = "bgp vpnv6",
62b346ee 1378 .node = BGP_VPNV6_NODE,
24389580 1379 .parent_node = BGP_NODE,
62b346ee
DL
1380 .prompt = "%s(config-router-af)# ",
1381};
8ecd3266 1382
62b346ee 1383static struct cmd_node bgp_flowspecv4_node = {
f4b8291f 1384 .name = "bgp ipv4 flowspec",
62b346ee 1385 .node = BGP_FLOWSPECV4_NODE,
24389580 1386 .parent_node = BGP_NODE,
62b346ee
DL
1387 .prompt = "%s(config-router-af)# ",
1388};
e7d78d0f 1389
62b346ee 1390static struct cmd_node bgp_flowspecv6_node = {
f4b8291f 1391 .name = "bgp ipv6 flowspec",
62b346ee 1392 .node = BGP_FLOWSPECV6_NODE,
24389580 1393 .parent_node = BGP_NODE,
62b346ee
DL
1394 .prompt = "%s(config-router-af)# ",
1395};
e7d78d0f 1396
62b346ee 1397static struct cmd_node bgp_ipv4_node = {
f4b8291f 1398 .name = "bgp ipv4 unicast",
62b346ee 1399 .node = BGP_IPV4_NODE,
24389580 1400 .parent_node = BGP_NODE,
62b346ee
DL
1401 .prompt = "%s(config-router-af)# ",
1402};
95e735b5 1403
62b346ee 1404static struct cmd_node bgp_ipv4m_node = {
f4b8291f 1405 .name = "bgp ipv4 multicast",
62b346ee 1406 .node = BGP_IPV4M_NODE,
24389580 1407 .parent_node = BGP_NODE,
62b346ee
DL
1408 .prompt = "%s(config-router-af)# ",
1409};
95e735b5 1410
62b346ee 1411static struct cmd_node bgp_ipv4l_node = {
f4b8291f 1412 .name = "bgp ipv4 labeled unicast",
62b346ee 1413 .node = BGP_IPV4L_NODE,
24389580 1414 .parent_node = BGP_NODE,
62b346ee
DL
1415 .prompt = "%s(config-router-af)# ",
1416};
f51bae9c 1417
62b346ee 1418static struct cmd_node bgp_ipv6_node = {
f4b8291f 1419 .name = "bgp ipv6",
62b346ee 1420 .node = BGP_IPV6_NODE,
24389580 1421 .parent_node = BGP_NODE,
62b346ee
DL
1422 .prompt = "%s(config-router-af)# ",
1423};
95e735b5 1424
62b346ee 1425static struct cmd_node bgp_ipv6m_node = {
f4b8291f 1426 .name = "bgp ipv6 multicast",
62b346ee 1427 .node = BGP_IPV6M_NODE,
24389580 1428 .parent_node = BGP_NODE,
62b346ee
DL
1429 .prompt = "%s(config-router-af)# ",
1430};
57b5b7ed 1431
62b346ee 1432static struct cmd_node bgp_evpn_node = {
f4b8291f 1433 .name = "bgp evpn",
62b346ee 1434 .node = BGP_EVPN_NODE,
24389580 1435 .parent_node = BGP_NODE,
62b346ee
DL
1436 .prompt = "%s(config-router-af)# ",
1437};
14a227b8 1438
62b346ee 1439static struct cmd_node bgp_evpn_vni_node = {
f4b8291f 1440 .name = "bgp evpn vni",
62b346ee 1441 .node = BGP_EVPN_VNI_NODE,
24389580 1442 .parent_node = BGP_EVPN_NODE,
62b346ee
DL
1443 .prompt = "%s(config-router-af-vni)# ",
1444};
90e60aa7 1445
62b346ee 1446static struct cmd_node bgp_ipv6l_node = {
f4b8291f 1447 .name = "bgp ipv6 labeled unicast",
62b346ee 1448 .node = BGP_IPV6L_NODE,
24389580 1449 .parent_node = BGP_NODE,
62b346ee
DL
1450 .prompt = "%s(config-router-af)# ",
1451};
f51bae9c 1452
0eb5751d 1453#ifdef ENABLE_BGP_VNC
d62a17ae 1454static struct cmd_node bgp_vnc_defaults_node = {
f4b8291f 1455 .name = "bgp vnc defaults",
62b346ee 1456 .node = BGP_VNC_DEFAULTS_NODE,
24389580 1457 .parent_node = BGP_NODE,
62b346ee
DL
1458 .prompt = "%s(config-router-vnc-defaults)# ",
1459};
65efcfce 1460
d62a17ae 1461static struct cmd_node bgp_vnc_nve_group_node = {
f4b8291f 1462 .name = "bgp vnc nve",
62b346ee 1463 .node = BGP_VNC_NVE_GROUP_NODE,
24389580 1464 .parent_node = BGP_NODE,
62b346ee
DL
1465 .prompt = "%s(config-router-vnc-nve-group)# ",
1466};
65efcfce 1467
62b346ee 1468static struct cmd_node bgp_vrf_policy_node = {
f4b8291f 1469 .name = "bgp vrf policy",
62b346ee 1470 .node = BGP_VRF_POLICY_NODE,
24389580 1471 .parent_node = BGP_NODE,
62b346ee
DL
1472 .prompt = "%s(config-router-vrf-policy)# ",
1473};
5ff06872 1474
d62a17ae 1475static struct cmd_node bgp_vnc_l2_group_node = {
f4b8291f 1476 .name = "bgp vnc l2",
62b346ee 1477 .node = BGP_VNC_L2_GROUP_NODE,
24389580 1478 .parent_node = BGP_NODE,
62b346ee
DL
1479 .prompt = "%s(config-router-vnc-l2-group)# ",
1480};
0eb5751d 1481#endif /* ENABLE_BGP_VNC */
65efcfce 1482
62b346ee 1483static struct cmd_node bmp_node = {
f4b8291f 1484 .name = "bmp",
62b346ee 1485 .node = BMP_NODE,
24389580 1486 .parent_node = BGP_NODE,
62b346ee
DL
1487 .prompt = "%s(config-bgp-bmp)# "
1488};
0eb5751d 1489#endif /* HAVE_BGPD */
ed18356f 1490
0eb5751d 1491#ifdef HAVE_OSPFD
62b346ee 1492static struct cmd_node ospf_node = {
f4b8291f 1493 .name = "ospf",
62b346ee 1494 .node = OSPF_NODE,
24389580 1495 .parent_node = CONFIG_NODE,
62b346ee
DL
1496 .prompt = "%s(config-router)# ",
1497};
0eb5751d 1498#endif /* HAVE_OSPFD */
d62a17ae 1499
0eb5751d 1500#ifdef HAVE_EIGRPD
62b346ee 1501static struct cmd_node eigrp_node = {
f4b8291f 1502 .name = "eigrp",
62b346ee 1503 .node = EIGRP_NODE,
24389580 1504 .parent_node = CONFIG_NODE,
62b346ee
DL
1505 .prompt = "%s(config-router)# ",
1506};
0eb5751d 1507#endif /* HAVE_EIGRPD */
d62a17ae 1508
0eb5751d 1509#ifdef HAVE_BABELD
62b346ee 1510static struct cmd_node babel_node = {
f4b8291f 1511 .name = "babel",
62b346ee 1512 .node = BABEL_NODE,
24389580 1513 .parent_node = CONFIG_NODE,
62b346ee
DL
1514 .prompt = "%s(config-router)# ",
1515};
0eb5751d 1516#endif /* HAVE_BABELD */
d62a17ae 1517
62b346ee 1518static struct cmd_node ripng_node = {
f4b8291f 1519 .name = "ripng",
62b346ee 1520 .node = RIPNG_NODE,
24389580 1521 .parent_node = CONFIG_NODE,
62b346ee
DL
1522 .prompt = "%s(config-router)# ",
1523};
d62a17ae 1524
0eb5751d 1525#ifdef HAVE_OSPF6D
62b346ee 1526static struct cmd_node ospf6_node = {
f4b8291f 1527 .name = "ospf6",
62b346ee 1528 .node = OSPF6_NODE,
24389580 1529 .parent_node = CONFIG_NODE,
62b346ee
DL
1530 .prompt = "%s(config-ospf6)# ",
1531};
0eb5751d 1532#endif /* HAVE_OSPF6D */
d62a17ae 1533
0eb5751d 1534#ifdef HAVE_LDPD
62b346ee 1535static struct cmd_node ldp_node = {
f4b8291f 1536 .name = "ldp",
62b346ee 1537 .node = LDP_NODE,
24389580 1538 .parent_node = CONFIG_NODE,
62b346ee
DL
1539 .prompt = "%s(config-ldp)# ",
1540};
d62a17ae 1541
62b346ee 1542static struct cmd_node ldp_ipv4_node = {
f4b8291f 1543 .name = "ldp ipv4",
62b346ee 1544 .node = LDP_IPV4_NODE,
24389580 1545 .parent_node = LDP_NODE,
62b346ee
DL
1546 .prompt = "%s(config-ldp-af)# ",
1547};
d62a17ae 1548
62b346ee 1549static struct cmd_node ldp_ipv6_node = {
f4b8291f 1550 .name = "ldp ipv6",
62b346ee 1551 .node = LDP_IPV6_NODE,
24389580 1552 .parent_node = LDP_NODE,
62b346ee
DL
1553 .prompt = "%s(config-ldp-af)# ",
1554};
d62a17ae 1555
62b346ee 1556static struct cmd_node ldp_ipv4_iface_node = {
f4b8291f 1557 .name = "ldp ipv4 interface",
62b346ee 1558 .node = LDP_IPV4_IFACE_NODE,
24389580 1559 .parent_node = LDP_IPV4_NODE,
62b346ee
DL
1560 .prompt = "%s(config-ldp-af-if)# ",
1561};
d62a17ae 1562
62b346ee 1563static struct cmd_node ldp_ipv6_iface_node = {
f4b8291f 1564 .name = "ldp ipv6 interface",
62b346ee 1565 .node = LDP_IPV6_IFACE_NODE,
24389580 1566 .parent_node = LDP_IPV6_NODE,
62b346ee
DL
1567 .prompt = "%s(config-ldp-af-if)# ",
1568};
d62a17ae 1569
62b346ee 1570static struct cmd_node ldp_l2vpn_node = {
f4b8291f 1571 .name = "ldp l2vpn",
62b346ee 1572 .node = LDP_L2VPN_NODE,
24389580 1573 .parent_node = CONFIG_NODE,
62b346ee
DL
1574 .prompt = "%s(config-l2vpn)# ",
1575};
d62a17ae 1576
62b346ee 1577static struct cmd_node ldp_pseudowire_node = {
f4b8291f 1578 .name = "ldp",
62b346ee 1579 .node = LDP_PSEUDOWIRE_NODE,
24389580 1580 .parent_node = LDP_L2VPN_NODE,
62b346ee
DL
1581 .prompt = "%s(config-l2vpn-pw)# ",
1582};
0eb5751d 1583#endif /* HAVE_LDPD */
d62a17ae 1584
62b346ee 1585static struct cmd_node keychain_node = {
f4b8291f 1586 .name = "keychain",
62b346ee 1587 .node = KEYCHAIN_NODE,
24389580 1588 .parent_node = CONFIG_NODE,
62b346ee
DL
1589 .prompt = "%s(config-keychain)# ",
1590};
d62a17ae 1591
62b346ee 1592static struct cmd_node keychain_key_node = {
f4b8291f 1593 .name = "keychain key",
62b346ee 1594 .node = KEYCHAIN_KEY_NODE,
24389580 1595 .parent_node = KEYCHAIN_NODE,
62b346ee
DL
1596 .prompt = "%s(config-keychain-key)# ",
1597};
d62a17ae 1598
1599struct cmd_node link_params_node = {
f4b8291f 1600 .name = "link-params",
62b346ee 1601 .node = LINK_PARAMS_NODE,
24389580 1602 .parent_node = INTERFACE_NODE,
62b346ee 1603 .prompt = "%s(config-link-params)# ",
95e735b5 1604};
1605
0eb5751d 1606#ifdef HAVE_BGPD
62b346ee 1607static struct cmd_node rpki_node = {
f4b8291f 1608 .name = "rpki",
62b346ee 1609 .node = RPKI_NODE,
24389580 1610 .parent_node = CONFIG_NODE,
62b346ee 1611 .prompt = "%s(config-rpki)# ",
62b346ee 1612};
0eb5751d 1613#endif /* HAVE_BGPD */
dabecd7c 1614
c2f29cf3
RZ
1615#if HAVE_BFDD > 0
1616static struct cmd_node bfd_node = {
f4b8291f 1617 .name = "bfd",
62b346ee 1618 .node = BFD_NODE,
24389580 1619 .parent_node = CONFIG_NODE,
62b346ee 1620 .prompt = "%s(config-bfd)# ",
c2f29cf3
RZ
1621};
1622
1623static struct cmd_node bfd_peer_node = {
f4b8291f 1624 .name = "bfd peer",
62b346ee 1625 .node = BFD_PEER_NODE,
24389580 1626 .parent_node = BFD_NODE,
62b346ee 1627 .prompt = "%s(config-bfd-peer)# ",
c2f29cf3 1628};
d40d6c22
RZ
1629
1630static struct cmd_node bfd_profile_node = {
1631 .name = "bfd profile",
1632 .node = BFD_PROFILE_NODE,
1633 .parent_node = BFD_NODE,
1634 .prompt = "%s(config-bfd-profile)# ",
1635};
c2f29cf3
RZ
1636#endif /* HAVE_BFDD */
1637
d62a17ae 1638/* Defined in lib/vty.c */
1639extern struct cmd_node vty_node;
1640
1641/* When '^Z' is received from vty, move down to the enable mode. */
1642static int vtysh_end(void)
1643{
1644 switch (vty->node) {
1645 case VIEW_NODE:
1646 case ENABLE_NODE:
1647 /* Nothing to do. */
1648 break;
1649 default:
1650 vty->node = ENABLE_NODE;
1651 break;
1652 }
1653 return CMD_SUCCESS;
1654}
1655
1656DEFUNSH(VTYSH_REALLYALL, vtysh_end_all, vtysh_end_all_cmd, "end",
1657 "End current mode and change to enable mode\n")
7f57883e 1658{
d62a17ae 1659 return vtysh_end();
1660}
7f57883e 1661
0eb5751d 1662#ifdef HAVE_BGPD
d62a17ae 1663DEFUNSH(VTYSH_BGPD, router_bgp, router_bgp_cmd,
21f5aade 1664 "router bgp [(1-4294967295) [<view|vrf> WORD]]",
d62a17ae 1665 ROUTER_STR BGP_STR AS_STR
1666 "BGP view\nBGP VRF\n"
1667 "View/VRF name\n")
a616ea5f 1668{
d62a17ae 1669 vty->node = BGP_NODE;
1670 return CMD_SUCCESS;
1671}
a616ea5f 1672
64e4a6c5 1673#ifdef KEEP_OLD_VPN_COMMANDS
d62a17ae 1674DEFUNSH(VTYSH_BGPD, address_family_vpnv4, address_family_vpnv4_cmd,
1675 "address-family vpnv4 [unicast]",
1676 "Enter Address Family command mode\n"
1677 "Address Family\n"
1678 "Address Family modifier\n")
95e735b5 1679{
d62a17ae 1680 vty->node = BGP_VPNV4_NODE;
1681 return CMD_SUCCESS;
1682}
95e735b5 1683
d62a17ae 1684DEFUNSH(VTYSH_BGPD, address_family_vpnv6, address_family_vpnv6_cmd,
1685 "address-family vpnv6 [unicast]",
1686 "Enter Address Family command mode\n"
1687 "Address Family\n"
1688 "Address Family modifier\n")
95e735b5 1689{
d62a17ae 1690 vty->node = BGP_VPNV6_NODE;
1691 return CMD_SUCCESS;
1692}
64e4a6c5 1693#endif /* KEEP_OLD_VPN_COMMANDS */
95e735b5 1694
d62a17ae 1695DEFUNSH(VTYSH_BGPD, address_family_ipv4, address_family_ipv4_cmd,
1696 "address-family ipv4 [unicast]",
1697 "Enter Address Family command mode\n"
1698 "Address Family\n"
1699 "Address Family Modifier\n")
4fcbf6e2 1700{
d62a17ae 1701 vty->node = BGP_IPV4_NODE;
1702 return CMD_SUCCESS;
1703}
4fcbf6e2 1704
e7d78d0f
PG
1705DEFUNSH(VTYSH_BGPD, address_family_flowspecv4, address_family_flowspecv4_cmd,
1706 "address-family ipv4 flowspec",
1707 "Enter Address Family command mode\n"
1708 "Address Family\n"
1709 "Address Family Modifier\n")
1710{
1711 vty->node = BGP_FLOWSPECV4_NODE;
1712 return CMD_SUCCESS;
1713}
1714
1715DEFUNSH(VTYSH_BGPD, address_family_flowspecv6, address_family_flowspecv6_cmd,
1716 "address-family ipv6 flowspec",
1717 "Enter Address Family command mode\n"
1718 "Address Family\n"
1719 "Address Family Modifier\n")
1720{
1721 vty->node = BGP_FLOWSPECV6_NODE;
1722 return CMD_SUCCESS;
1723}
1724
d62a17ae 1725DEFUNSH(VTYSH_BGPD, address_family_ipv4_multicast,
1726 address_family_ipv4_multicast_cmd, "address-family ipv4 multicast",
1727 "Enter Address Family command mode\n"
1728 "Address Family\n"
1729 "Address Family modifier\n")
4fcbf6e2 1730{
d62a17ae 1731 vty->node = BGP_IPV4M_NODE;
1732 return CMD_SUCCESS;
1733}
4fcbf6e2 1734
d62a17ae 1735DEFUNSH(VTYSH_BGPD, address_family_ipv4_vpn, address_family_ipv4_vpn_cmd,
1736 "address-family ipv4 vpn",
1737 "Enter Address Family command mode\n"
1738 "Address Family\n"
1739 "Address Family modifier\n")
4fcbf6e2 1740{
d62a17ae 1741 vty->node = BGP_VPNV4_NODE;
1742 return CMD_SUCCESS;
1743}
4fcbf6e2 1744
d62a17ae 1745DEFUNSH(VTYSH_BGPD, address_family_ipv4_labeled_unicast,
1746 address_family_ipv4_labeled_unicast_cmd,
1747 "address-family ipv4 labeled-unicast",
1748 "Enter Address Family command mode\n"
1749 "Address Family\n"
1750 "Address Family modifier\n")
4fcbf6e2 1751{
d62a17ae 1752 vty->node = BGP_IPV4L_NODE;
1753 return CMD_SUCCESS;
1754}
4fcbf6e2 1755
d62a17ae 1756DEFUNSH(VTYSH_BGPD, address_family_ipv6, address_family_ipv6_cmd,
1757 "address-family ipv6 [unicast]",
1758 "Enter Address Family command mode\n"
1759 "Address Family\n"
1760 "Address Family modifier\n")
4fcbf6e2 1761{
d62a17ae 1762 vty->node = BGP_IPV6_NODE;
1763 return CMD_SUCCESS;
1764}
4fcbf6e2 1765
d62a17ae 1766DEFUNSH(VTYSH_BGPD, address_family_ipv6_multicast,
1767 address_family_ipv6_multicast_cmd, "address-family ipv6 multicast",
1768 "Enter Address Family command mode\n"
1769 "Address Family\n"
1770 "Address Family modifier\n")
4fcbf6e2 1771{
d62a17ae 1772 vty->node = BGP_IPV6M_NODE;
1773 return CMD_SUCCESS;
1774}
4fcbf6e2 1775
d62a17ae 1776DEFUNSH(VTYSH_BGPD, address_family_ipv6_vpn, address_family_ipv6_vpn_cmd,
1777 "address-family ipv6 vpn",
1778 "Enter Address Family command mode\n"
1779 "Address Family\n"
1780 "Address Family modifier\n")
4fcbf6e2 1781{
d62a17ae 1782 vty->node = BGP_VPNV6_NODE;
1783 return CMD_SUCCESS;
1784}
4fcbf6e2 1785
d62a17ae 1786DEFUNSH(VTYSH_BGPD, address_family_ipv6_labeled_unicast,
1787 address_family_ipv6_labeled_unicast_cmd,
1788 "address-family ipv6 labeled-unicast",
1789 "Enter Address Family command mode\n"
1790 "Address Family\n"
1791 "Address Family modifier\n")
95e735b5 1792{
d62a17ae 1793 vty->node = BGP_IPV6L_NODE;
1794 return CMD_SUCCESS;
1795}
95e735b5 1796
b86543b8
LB
1797DEFUNSH(VTYSH_BGPD,
1798 rpki,
1799 rpki_cmd,
1800 "rpki",
dabecd7c
MR
1801 "Enable rpki and enter rpki configuration mode\n")
1802{
1803 vty->node = RPKI_NODE;
1804 return CMD_SUCCESS;
1805}
1806
ed18356f
DL
1807DEFUNSH(VTYSH_BGPD,
1808 bmp_targets,
1809 bmp_targets_cmd,
1810 "bmp targets BMPTARGETS",
1811 "BGP Monitoring Protocol\n"
1812 "Create BMP target group\n"
1813 "Name of the BMP target group\n")
1814{
1815 vty->node = BMP_NODE;
1816 return CMD_SUCCESS;
1817}
1818
d62a17ae 1819DEFUNSH(VTYSH_BGPD, address_family_evpn, address_family_evpn_cmd,
1820 "address-family <l2vpn evpn>",
1821 "Enter Address Family command mode\n"
1822 "Address Family\n"
1823 "Address Family modifier\n")
95e735b5 1824{
d62a17ae 1825 vty->node = BGP_EVPN_NODE;
1826 return CMD_SUCCESS;
1827}
95e735b5 1828
d62a17ae 1829#if defined(HAVE_CUMULUS)
98cc8dd4
DS
1830#if CONFDATE > 20211115
1831CPP_NOTICE("Use of `address-family evpn` is deprecated please remove don't forget frr-reload.py")
1832#endif
5014d96f
DW
1833DEFUNSH_HIDDEN(VTYSH_BGPD, address_family_evpn2, address_family_evpn2_cmd,
1834 "address-family evpn",
1835 "Enter Address Family command mode\n"
1836 "EVPN Address family\n")
16f1b9ee 1837{
98cc8dd4
DS
1838 vty_out(vty,
1839 "This command is deprecated please convert to `address-family l2vpn evpn`\n");
d62a17ae 1840 vty->node = BGP_EVPN_NODE;
1841 return CMD_SUCCESS;
1842}
1843#endif
16f1b9ee 1844
093e3f23 1845DEFUNSH(VTYSH_BGPD, bgp_evpn_vni, bgp_evpn_vni_cmd, "vni " CMD_VNI_RANGE,
d62a17ae 1846 "VXLAN Network Identifier\n"
1847 "VNI number\n")
1848{
1849 vty->node = BGP_EVPN_VNI_NODE;
1850 return CMD_SUCCESS;
1851}
e7168df4 1852
d62a17ae 1853#if defined(ENABLE_BGP_VNC)
1854DEFUNSH(VTYSH_BGPD, vnc_defaults, vnc_defaults_cmd, "vnc defaults",
1855 "VNC/RFP related configuration\n"
1856 "Configure default NVE group\n")
718e3744 1857{
d62a17ae 1858 vty->node = BGP_VNC_DEFAULTS_NODE;
1859 return CMD_SUCCESS;
1860}
1861
1862DEFUNSH(VTYSH_BGPD, vnc_nve_group, vnc_nve_group_cmd, "vnc nve-group NAME",
1863 "VNC/RFP related configuration\n"
1864 "Configure a NVE group\n"
1865 "Group name\n")
718e3744 1866{
d62a17ae 1867 vty->node = BGP_VNC_NVE_GROUP_NODE;
1868 return CMD_SUCCESS;
1869}
1870
1871DEFUNSH(VTYSH_BGPD, vnc_vrf_policy, vnc_vrf_policy_cmd, "vrf-policy NAME",
1872 "Configure a VRF policy group\n"
1873 "Group name\n")
8ecd3266 1874{
d62a17ae 1875 vty->node = BGP_VRF_POLICY_NODE;
1876 return CMD_SUCCESS;
1877}
1878
1879DEFUNSH(VTYSH_BGPD, vnc_l2_group, vnc_l2_group_cmd, "vnc l2-group NAME",
1880 "VNC/RFP related configuration\n"
1881 "Configure a L2 group\n"
1882 "Group name\n")
718e3744 1883{
d62a17ae 1884 vty->node = BGP_VNC_L2_GROUP_NODE;
1885 return CMD_SUCCESS;
718e3744 1886}
662a1b05
WC
1887
1888DEFUNSH(VTYSH_BGPD, exit_vnc_config, exit_vnc_config_cmd, "exit-vnc",
1889 "Exit from VNC configuration mode\n")
1890{
1891 if (vty->node == BGP_VNC_DEFAULTS_NODE
1892 || vty->node == BGP_VNC_NVE_GROUP_NODE
1893 || vty->node == BGP_VNC_L2_GROUP_NODE)
1894 vty->node = BGP_NODE;
1895 return CMD_SUCCESS;
1896}
1897
1898DEFUNSH(VTYSH_BGPD, exit_vrf_policy, exit_vrf_policy_cmd, "exit-vrf-policy",
1899 "Exit from VRF policy configuration mode\n")
1900{
1901 if (vty->node == BGP_VRF_POLICY_NODE)
1902 vty->node = BGP_NODE;
1903 return CMD_SUCCESS;
1904}
d62a17ae 1905#endif
0eb5751d 1906#endif /* HAVE_BGPD */
718e3744 1907
3a3a24c8 1908DEFUNSH(VTYSH_KEYS, key_chain, key_chain_cmd, "key chain WORD",
d62a17ae 1909 "Authentication key management\n"
1910 "Key-chain management\n"
1911 "Key-chain name\n")
718e3744 1912{
d62a17ae 1913 vty->node = KEYCHAIN_NODE;
1914 return CMD_SUCCESS;
39530dfe 1915}
c7f1274b 1916
3a3a24c8 1917DEFUNSH(VTYSH_KEYS, key, key_cmd, "key (0-2147483647)",
d62a17ae 1918 "Configure a key\n"
1919 "Key identifier number\n")
39530dfe 1920{
d62a17ae 1921 vty->node = KEYCHAIN_KEY_NODE;
1922 return CMD_SUCCESS;
39530dfe 1923}
f51bae9c 1924
0eb5751d 1925#ifdef HAVE_RIPD
ae7b826a
RW
1926DEFUNSH(VTYSH_RIPD, router_rip, router_rip_cmd, "router rip [vrf NAME]",
1927 ROUTER_STR "RIP\n" VRF_CMD_HELP_STR)
39530dfe 1928{
d62a17ae 1929 vty->node = RIP_NODE;
1930 return CMD_SUCCESS;
57b5b7ed 1931}
0eb5751d 1932#endif /* HAVE_RIPD */
718e3744 1933
0eb5751d 1934#ifdef HAVE_RIPNGD
dde7b15b
RW
1935DEFUNSH(VTYSH_RIPNGD, router_ripng, router_ripng_cmd, "router ripng [vrf NAME]",
1936 ROUTER_STR "RIPng\n" VRF_CMD_HELP_STR)
05ba625a 1937{
d62a17ae 1938 vty->node = RIPNG_NODE;
1939 return CMD_SUCCESS;
57b5b7ed 1940}
0eb5751d 1941#endif /* HAVE_RIPNGD */
57b5b7ed 1942
0eb5751d 1943#ifdef HAVE_OSPFD
b5a8894d
CS
1944DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd,
1945 "router ospf [(1-65535)] [vrf NAME]",
d62a17ae 1946 "Enable a routing process\n"
1947 "Start OSPF configuration\n"
b86543b8
LB
1948 "Instance ID\n"
1949 VRF_CMD_HELP_STR)
90e60aa7 1950{
d62a17ae 1951 vty->node = OSPF_NODE;
1952 return CMD_SUCCESS;
90e60aa7 1953}
0eb5751d 1954#endif /* HAVE_OSPFD */
90e60aa7 1955
0eb5751d 1956#ifdef HAVE_EIGRPD
e9449961 1957DEFUNSH(VTYSH_EIGRPD, router_eigrp, router_eigrp_cmd, "router eigrp (1-65535) [vrf NAME]",
d62a17ae 1958 "Enable a routing process\n"
1959 "Start EIGRP configuration\n"
e9449961
DS
1960 "AS number to use\n"
1961 VRF_CMD_HELP_STR)
14a227b8 1962{
d62a17ae 1963 vty->node = EIGRP_NODE;
1964 return CMD_SUCCESS;
14a227b8 1965}
0eb5751d 1966#endif /* HAVE_EIGRPD */
90e60aa7 1967
0eb5751d 1968#ifdef HAVE_BABELD
d62a17ae 1969DEFUNSH(VTYSH_BABELD, router_babel, router_babel_cmd, "router babel",
1970 "Enable a routing process\n"
1971 "Make Babel instance command\n")
90e60aa7 1972{
d62a17ae 1973 vty->node = BABEL_NODE;
1974 return CMD_SUCCESS;
90e60aa7 1975}
0eb5751d 1976#endif /* HAVE_BABELD */
14a227b8 1977
0eb5751d 1978#ifdef HAVE_OSPF6D
d48ef099 1979DEFUNSH(VTYSH_OSPF6D, router_ospf6, router_ospf6_cmd, "router ospf6 [vrf NAME]",
1980 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR)
65efcfce 1981{
d62a17ae 1982 vty->node = OSPF6_NODE;
1983 return CMD_SUCCESS;
65efcfce 1984}
0eb5751d 1985#endif
65efcfce 1986
d62a17ae 1987#if defined(HAVE_LDPD)
1988DEFUNSH(VTYSH_LDPD, ldp_mpls_ldp, ldp_mpls_ldp_cmd, "mpls ldp",
1989 "Global MPLS configuration subcommands\n"
1990 "Label Distribution Protocol\n")
65efcfce 1991{
d62a17ae 1992 vty->node = LDP_NODE;
1993 return CMD_SUCCESS;
65efcfce
LB
1994}
1995
d62a17ae 1996DEFUNSH(VTYSH_LDPD, ldp_address_family_ipv4, ldp_address_family_ipv4_cmd,
1997 "address-family ipv4",
1998 "Configure Address Family and its parameters\n"
1999 "IPv4\n")
5ff06872 2000{
d62a17ae 2001 vty->node = LDP_IPV4_NODE;
2002 return CMD_SUCCESS;
5ff06872
LB
2003}
2004
d62a17ae 2005DEFUNSH(VTYSH_LDPD, ldp_address_family_ipv6, ldp_address_family_ipv6_cmd,
2006 "address-family ipv6",
2007 "Configure Address Family and its parameters\n"
2008 "IPv6\n")
65efcfce 2009{
d62a17ae 2010 vty->node = LDP_IPV6_NODE;
2011 return CMD_SUCCESS;
65efcfce
LB
2012}
2013
983bd6f7
RW
2014DEFUNSH(VTYSH_LDPD, ldp_exit_address_family, ldp_exit_address_family_cmd,
2015 "exit-address-family", "Exit from Address Family configuration mode\n")
2016{
2017 if (vty->node == LDP_IPV4_NODE || vty->node == LDP_IPV6_NODE)
2018 vty->node = LDP_NODE;
2019 return CMD_SUCCESS;
2020}
2021
d62a17ae 2022DEFUNSH(VTYSH_LDPD, ldp_interface_ifname, ldp_interface_ifname_cmd,
2023 "interface IFNAME",
2024 "Enable LDP on an interface and enter interface submode\n"
2025 "Interface's name\n")
718e3744 2026{
d62a17ae 2027 switch (vty->node) {
2028 case LDP_IPV4_NODE:
2029 vty->node = LDP_IPV4_IFACE_NODE;
2030 break;
2031 case LDP_IPV6_NODE:
2032 vty->node = LDP_IPV6_IFACE_NODE;
2033 break;
2034 default:
2035 break;
2036 }
2037
2038 return CMD_SUCCESS;
2039}
718e3744 2040
d62a17ae 2041DEFUNSH(VTYSH_LDPD, ldp_l2vpn_word_type_vpls, ldp_l2vpn_word_type_vpls_cmd,
2042 "l2vpn WORD type vpls",
2043 "Configure l2vpn commands\n"
2044 "L2VPN name\n"
2045 "L2VPN type\n"
2046 "Virtual Private LAN Service\n")
718e3744 2047{
d62a17ae 2048 vty->node = LDP_L2VPN_NODE;
2049 return CMD_SUCCESS;
718e3744 2050}
2051
d62a17ae 2052DEFUNSH(VTYSH_LDPD, ldp_member_pseudowire_ifname,
2053 ldp_member_pseudowire_ifname_cmd, "member pseudowire IFNAME",
2054 "L2VPN member configuration\n"
2055 "Pseudowire interface\n"
2056 "Interface's name\n")
718e3744 2057{
d62a17ae 2058 vty->node = LDP_PSEUDOWIRE_NODE;
2059 return CMD_SUCCESS;
718e3744 2060}
d62a17ae 2061#endif
718e3744 2062
0eb5751d 2063#ifdef HAVE_ISISD
65251ce8 2064DEFUNSH(VTYSH_ISISD, router_isis, router_isis_cmd,
2065 "router isis WORD [vrf NAME]",
d62a17ae 2066 ROUTER_STR
2067 "ISO IS-IS\n"
65251ce8 2068 "ISO Routing area tag\n" VRF_CMD_HELP_STR)
d62a17ae 2069{
2070 vty->node = ISIS_NODE;
2071 return CMD_SUCCESS;
2072}
0eb5751d 2073#endif /* HAVE_ISISD */
d62a17ae 2074
0eb5751d 2075#ifdef HAVE_FABRICD
770ccdf8
CF
2076DEFUNSH(VTYSH_FABRICD, router_openfabric, router_openfabric_cmd, "router openfabric WORD",
2077 ROUTER_STR
2078 "OpenFabric routing protocol\n"
2079 "ISO Routing area tag\n")
2080{
2081 vty->node = OPENFABRIC_NODE;
2082 return CMD_SUCCESS;
2083}
0eb5751d 2084#endif /* HAVE_FABRICD */
770ccdf8 2085
4d7b695d
SM
2086#if defined(HAVE_PATHD)
2087DEFUNSH(VTYSH_PATHD, segment_routing, segment_routing_cmd,
2088 "segment-routing",
2089 "Configure segment routing\n")
2090{
2091 vty->node = SEGMENT_ROUTING_NODE;
2092 return CMD_SUCCESS;
2093}
2094
2095DEFUNSH(VTYSH_PATHD, sr_traffic_eng, sr_traffic_eng_cmd,
2096 "traffic-eng",
2097 "Configure SR traffic engineering\n")
2098{
2099 vty->node = SR_TRAFFIC_ENG_NODE;
2100 return CMD_SUCCESS;
2101}
2102
2103DEFUNSH(VTYSH_PATHD, srte_segment_list, srte_segment_list_cmd,
2104 "segment-list WORD$name",
2105 "Segment List\n"
2106 "Segment List Name\n")
2107{
2108 vty->node = SR_SEGMENT_LIST_NODE;
2109 return CMD_SUCCESS;
2110}
2111
2112DEFUNSH(VTYSH_PATHD, srte_policy, srte_policy_cmd,
2113 "policy color (0-4294967295) endpoint <A.B.C.D|X:X::X:X>",
2114 "Segment Routing Policy\n"
2115 "SR Policy color\n"
2116 "SR Policy color value\n"
2117 "SR Policy endpoint\n"
2118 "SR Policy endpoint IPv4 address\n"
2119 "SR Policy endpoint IPv6 address\n")
2120{
2121 vty->node = SR_POLICY_NODE;
2122 return CMD_SUCCESS;
2123}
2124
2125DEFUNSH(VTYSH_PATHD, srte_policy_candidate_dyn_path,
2126 srte_policy_candidate_dyn_path_cmd,
2127 "candidate-path preference (0-4294967295) name WORD dynamic",
2128 "Segment Routing Policy Candidate Path\n"
2129 "Segment Routing Policy Candidate Path Preference\n"
2130 "Administrative Preference\n"
2131 "Segment Routing Policy Candidate Path Name\n"
2132 "Symbolic Name\n"
2133 "Dynamic Path\n")
2134{
2135 vty->node = SR_CANDIDATE_DYN_NODE;
2136 return CMD_SUCCESS;
2137}
efba0985
SM
2138
2139#if defined(HAVE_PATHD_PCEP)
2140
2141DEFUNSH(VTYSH_PATHD, pcep, pcep_cmd,
2142 "pcep",
2143 "Configure SR pcep\n")
2144{
2145 vty->node = PCEP_NODE;
2146 return CMD_SUCCESS;
2147}
2148
2149DEFUNSH(VTYSH_PATHD, pcep_cli_pcc, pcep_cli_pcc_cmd,
2150 "[no] pcc",
2151 NO_STR
2152 "PCC configuration\n")
2153{
2154 vty->node = PCEP_PCC_NODE;
2155 return CMD_SUCCESS;
2156}
2157
2158DEFUNSH(VTYSH_PATHD, pcep_cli_pce, pcep_cli_pce_cmd,
2159 "[no] pce WORD",
2160 NO_STR
2161 "PCE configuration\n"
2162 "Peer name\n")
2163{
2164 vty->node = PCEP_PCE_NODE;
2165 return CMD_SUCCESS;
2166}
2167
2168DEFUNSH(VTYSH_PATHD, pcep_cli_pcep_pce_config, pcep_cli_pcep_pce_config_cmd,
2169 "[no] pce-config WORD",
2170 NO_STR
2171 "PCEP peer Configuration Group\n"
2172 "PCEP peer Configuration Group name\n")
2173{
2174 vty->node = PCEP_PCE_CONFIG_NODE;
2175 return CMD_SUCCESS;
2176}
2177
2178#endif /* HAVE_PATHD_PCEP */
2179
4d7b695d
SM
2180#endif /* HAVE_PATHD */
2181
d62a17ae 2182DEFUNSH(VTYSH_RMAP, vtysh_route_map, vtysh_route_map_cmd,
2183 "route-map WORD <deny|permit> (1-65535)",
2184 "Create route-map or enter route-map command mode\n"
2185 "Route map tag\n"
2186 "Route map denies set operations\n"
2187 "Route map permits set operations\n"
2188 "Sequence to insert to/delete from existing route-map entry\n")
2189{
2190 vty->node = RMAP_NODE;
2191 return CMD_SUCCESS;
2192}
2193
0eb5751d 2194#ifdef HAVE_PBRD
e5c83d9b 2195DEFUNSH(VTYSH_PBRD, vtysh_pbr_map, vtysh_pbr_map_cmd,
17f8c652 2196 "pbr-map PBRMAP seq (1-700)",
e5c83d9b
DS
2197 "Create pbr-map or enter pbr-map command mode\n"
2198 "The name of the PBR MAP\n"
2199 "Sequence to insert to/delete from existing pbr-map entry\n"
2200 "Sequence number\n")
2201{
2202 vty->node = PBRMAP_NODE;
2203 return CMD_SUCCESS;
2204}
2205
5d574646
IR
2206DEFSH(VTYSH_PBRD, vtysh_no_pbr_map_cmd, "no pbr-map PBRMAP [seq (1-700)]",
2207 NO_STR
2208 "Delete pbr-map\n"
2209 "The name of the PBR MAP\n"
2210 "Sequence to delete from existing pbr-map entry\n"
2211 "Sequence number\n")
0eb5751d 2212#endif /* HAVE_PBRD */
5d574646 2213
c2f29cf3
RZ
2214#if HAVE_BFDD > 0
2215DEFUNSH(VTYSH_BFDD, bfd_enter, bfd_enter_cmd, "bfd", "Configure BFD peers\n")
2216{
2217 vty->node = BFD_NODE;
2218 return CMD_SUCCESS;
2219}
2220
2221DEFUNSH(VTYSH_BFDD, bfd_peer_enter, bfd_peer_enter_cmd,
2222 "peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
2223 "Configure peer\n"
2224 "IPv4 peer address\n"
2225 "IPv6 peer address\n"
2226 "Configure multihop\n"
2227 "Configure local address\n"
2228 "IPv4 local address\n"
2229 "IPv6 local address\n"
2230 INTERFACE_STR
2231 "Configure interface name to use\n"
2232 "Configure VRF\n"
2233 "Configure VRF name\n")
2234{
2235 vty->node = BFD_PEER_NODE;
2236 return CMD_SUCCESS;
2237}
d40d6c22
RZ
2238
2239DEFUNSH(VTYSH_BFDD, bfd_profile_enter, bfd_profile_enter_cmd,
0a01b0f4 2240 "profile BFDPROF",
d40d6c22
RZ
2241 BFD_PROFILE_STR
2242 BFD_PROFILE_NAME_STR)
2243{
2244 vty->node = BFD_PROFILE_NODE;
2245 return CMD_SUCCESS;
2246}
c2f29cf3
RZ
2247#endif /* HAVE_BFDD */
2248
d62a17ae 2249DEFUNSH(VTYSH_ALL, vtysh_line_vty, vtysh_line_vty_cmd, "line vty",
2250 "Configure a terminal line\n"
2251 "Virtual terminal\n")
2252{
2253 vty->node = VTY_NODE;
2254 return CMD_SUCCESS;
2255}
2256
2257DEFUNSH(VTYSH_REALLYALL, vtysh_enable, vtysh_enable_cmd, "enable",
2258 "Turn on privileged mode command\n")
2259{
2260 vty->node = ENABLE_NODE;
2261 return CMD_SUCCESS;
2262}
2263
2264DEFUNSH(VTYSH_REALLYALL, vtysh_disable, vtysh_disable_cmd, "disable",
2265 "Turn off privileged mode command\n")
2266{
2267 if (vty->node == ENABLE_NODE)
2268 vty->node = VIEW_NODE;
2269 return CMD_SUCCESS;
2270}
2271
2272DEFUNSH(VTYSH_REALLYALL, vtysh_config_terminal, vtysh_config_terminal_cmd,
dc1c13c0 2273 "configure [terminal]",
d62a17ae 2274 "Configuration from vty interface\n"
2275 "Configuration terminal\n")
2276{
2277 vty->node = CONFIG_NODE;
2278 return CMD_SUCCESS;
2279}
2280
2281static int vtysh_exit(struct vty *vty)
2282{
d42eb101
DL
2283 struct cmd_node *cnode = vector_lookup(cmdvec, vty->node);
2284
2285 if (vty->node == VIEW_NODE || vty->node == ENABLE_NODE)
d62a17ae 2286 exit(0);
d42eb101
DL
2287 if (cnode->node_exit)
2288 cnode->node_exit(vty);
2289 if (cnode->parent_node)
2290 vty->node = cnode->parent_node;
2291
2292 if (vty->node == CONFIG_NODE) {
2293 /* resync in case one of the daemons is somewhere else */
d62a17ae 2294 vtysh_execute("end");
dc1c13c0 2295 vtysh_execute("configure");
d62a17ae 2296 }
2297 return CMD_SUCCESS;
2298}
2299
2300DEFUNSH(VTYSH_REALLYALL, vtysh_exit_all, vtysh_exit_all_cmd, "exit",
2301 "Exit current mode and down to previous mode\n")
4fcbf6e2 2302{
d62a17ae 2303 return vtysh_exit(vty);
4fcbf6e2
RW
2304}
2305
5772415b 2306DEFUNSH(VTYSH_REALLYALL, vtysh_quit_all, vtysh_quit_all_cmd, "quit",
d62a17ae 2307 "Exit current mode and down to previous mode\n")
4fcbf6e2 2308{
d62a17ae 2309 return vtysh_exit_all(self, vty, argc, argv);
2310}
4fcbf6e2 2311
0eb5751d 2312#ifdef HAVE_BGPD
d62a17ae 2313DEFUNSH(VTYSH_BGPD, exit_address_family, exit_address_family_cmd,
2314 "exit-address-family", "Exit from Address Family configuration mode\n")
4fcbf6e2 2315{
d62a17ae 2316 if (vty->node == BGP_IPV4_NODE || vty->node == BGP_IPV4M_NODE
2317 || vty->node == BGP_IPV4L_NODE || vty->node == BGP_VPNV4_NODE
2318 || vty->node == BGP_VPNV6_NODE || vty->node == BGP_IPV6_NODE
2319 || vty->node == BGP_IPV6L_NODE || vty->node == BGP_IPV6M_NODE
e7d78d0f
PG
2320 || vty->node == BGP_EVPN_NODE
2321 || vty->node == BGP_FLOWSPECV4_NODE
2322 || vty->node == BGP_FLOWSPECV6_NODE)
d62a17ae 2323 vty->node = BGP_NODE;
2324 return CMD_SUCCESS;
2325}
4fcbf6e2 2326
d62a17ae 2327DEFUNSH(VTYSH_BGPD, exit_vni, exit_vni_cmd, "exit-vni", "Exit from VNI mode\n")
4fcbf6e2 2328{
d62a17ae 2329 if (vty->node == BGP_EVPN_VNI_NODE)
2330 vty->node = BGP_EVPN_NODE;
2331 return CMD_SUCCESS;
2332}
2333
61a484a9
QY
2334DEFUNSH(VTYSH_BGPD, rpki_exit, rpki_exit_cmd, "exit",
2335 "Exit current mode and down to previous mode\n")
2336{
2337 vtysh_exit(vty);
2338 return CMD_SUCCESS;
2339}
2340
2341DEFUNSH(VTYSH_BGPD, rpki_quit, rpki_quit_cmd, "quit",
2342 "Exit current mode and down to previous mode\n")
2343{
2344 return rpki_exit(self, vty, argc, argv);
4fcbf6e2
RW
2345}
2346
ed18356f
DL
2347DEFUNSH(VTYSH_BGPD, bmp_exit, bmp_exit_cmd, "exit",
2348 "Exit current mode and down to previous mode\n")
2349{
2350 vtysh_exit(vty);
2351 return CMD_SUCCESS;
2352}
2353
2354DEFUNSH(VTYSH_BGPD, bmp_quit, bmp_quit_cmd, "quit",
2355 "Exit current mode and down to previous mode\n")
2356{
2357 return bmp_exit(self, vty, argc, argv);
2358}
0eb5751d 2359#endif /* HAVE_BGPD */
5ff06872 2360
5d574646
IR
2361DEFUNSH(VTYSH_VRF, exit_vrf_config, exit_vrf_config_cmd, "exit-vrf",
2362 "Exit from VRF configuration mode\n")
2363{
2364 if (vty->node == VRF_NODE)
2365 vty->node = CONFIG_NODE;
2366 return CMD_SUCCESS;
2367}
2368
0eb5751d 2369#ifdef HAVE_RIPD
d62a17ae 2370DEFUNSH(VTYSH_RIPD, vtysh_exit_ripd, vtysh_exit_ripd_cmd, "exit",
2371 "Exit current mode and down to previous mode\n")
718e3744 2372{
d62a17ae 2373 return vtysh_exit(vty);
718e3744 2374}
2375
d62a17ae 2376DEFUNSH(VTYSH_RIPD, vtysh_quit_ripd, vtysh_quit_ripd_cmd, "quit",
2377 "Exit current mode and down to previous mode\n")
a98d33ab 2378{
d62a17ae 2379 return vtysh_exit_ripd(self, vty, argc, argv);
a98d33ab 2380}
0eb5751d 2381#endif /* HAVE_RIPD */
718e3744 2382
0eb5751d 2383#ifdef HAVE_RIPNGD
d62a17ae 2384DEFUNSH(VTYSH_RIPNGD, vtysh_exit_ripngd, vtysh_exit_ripngd_cmd, "exit",
2385 "Exit current mode and down to previous mode\n")
68980084 2386{
d62a17ae 2387 return vtysh_exit(vty);
68980084 2388}
2389
d62a17ae 2390DEFUNSH(VTYSH_RIPNGD, vtysh_quit_ripngd, vtysh_quit_ripngd_cmd, "quit",
2391 "Exit current mode and down to previous mode\n")
a98d33ab 2392{
d62a17ae 2393 return vtysh_exit_ripngd(self, vty, argc, argv);
a98d33ab 2394}
0eb5751d 2395#endif /* HAVE_RIPNGD */
68980084 2396
d62a17ae 2397DEFUNSH(VTYSH_RMAP, vtysh_exit_rmap, vtysh_exit_rmap_cmd, "exit",
2398 "Exit current mode and down to previous mode\n")
718e3744 2399{
d62a17ae 2400 return vtysh_exit(vty);
718e3744 2401}
2402
d62a17ae 2403DEFUNSH(VTYSH_RMAP, vtysh_quit_rmap, vtysh_quit_rmap_cmd, "quit",
2404 "Exit current mode and down to previous mode\n")
a98d33ab 2405{
d62a17ae 2406 return vtysh_exit_rmap(self, vty, argc, argv);
a98d33ab 2407}
718e3744 2408
0eb5751d 2409#ifdef HAVE_PBRD
e5c83d9b
DS
2410DEFUNSH(VTYSH_PBRD, vtysh_exit_pbr_map, vtysh_exit_pbr_map_cmd, "exit",
2411 "Exit current mode and down to previous mode\n")
2412{
2413 return vtysh_exit(vty);
2414}
2415
2416DEFUNSH(VTYSH_PBRD, vtysh_quit_pbr_map, vtysh_quit_pbr_map_cmd, "quit",
2417 "Exit current mode and down to previous mode\n")
2418{
2419 return vtysh_exit_rmap(self, vty, argc, argv);
2420}
0eb5751d 2421#endif /* HAVE_PBRD */
e5c83d9b 2422
0eb5751d 2423#ifdef HAVE_BGPD
d62a17ae 2424DEFUNSH(VTYSH_BGPD, vtysh_exit_bgpd, vtysh_exit_bgpd_cmd, "exit",
2425 "Exit current mode and down to previous mode\n")
718e3744 2426{
d62a17ae 2427 return vtysh_exit(vty);
718e3744 2428}
2429
d62a17ae 2430DEFUNSH(VTYSH_BGPD, vtysh_quit_bgpd, vtysh_quit_bgpd_cmd, "quit",
2431 "Exit current mode and down to previous mode\n")
a98d33ab 2432{
d62a17ae 2433 return vtysh_exit_bgpd(self, vty, argc, argv);
a98d33ab 2434}
0eb5751d 2435#endif /* HAVE_BGPD */
718e3744 2436
0eb5751d 2437#ifdef HAVE_OSPFD
d62a17ae 2438DEFUNSH(VTYSH_OSPFD, vtysh_exit_ospfd, vtysh_exit_ospfd_cmd, "exit",
2439 "Exit current mode and down to previous mode\n")
718e3744 2440{
d62a17ae 2441 return vtysh_exit(vty);
718e3744 2442}
2443
d62a17ae 2444DEFUNSH(VTYSH_OSPFD, vtysh_quit_ospfd, vtysh_quit_ospfd_cmd, "quit",
2445 "Exit current mode and down to previous mode\n")
a98d33ab 2446{
d62a17ae 2447 return vtysh_exit_ospfd(self, vty, argc, argv);
a98d33ab 2448}
0eb5751d 2449#endif /* HAVE_OSPFD */
718e3744 2450
0eb5751d 2451#ifdef HAVE_EIGRPD
d62a17ae 2452DEFUNSH(VTYSH_EIGRPD, vtysh_exit_eigrpd, vtysh_exit_eigrpd_cmd, "exit",
2453 "Exit current mode and down to previous mode\n")
7f57883e 2454{
d62a17ae 2455 return vtysh_exit(vty);
7f57883e
DS
2456}
2457
d62a17ae 2458DEFUNSH(VTYSH_EIGRPD, vtysh_quit_eigrpd, vtysh_quit_eigrpd_cmd, "quit",
2459 "Exit current mode and down to previous mode\n")
7f57883e 2460{
d62a17ae 2461 return vtysh_exit(vty);
7f57883e 2462}
0eb5751d 2463#endif /* HAVE_EIGRPD */
7f57883e 2464
0eb5751d 2465#ifdef HAVE_BABELD
460982cf 2466DEFUNSH(VTYSH_BABELD, vtysh_exit_babeld, vtysh_exit_babeld_cmd, "exit",
d62a17ae 2467 "Exit current mode and down to previous mode\n")
a616ea5f 2468{
d62a17ae 2469 return vtysh_exit(vty);
a616ea5f
DS
2470}
2471
d62a17ae 2472DEFUNSH(VTYSH_BABELD, vtysh_quit_babeld, vtysh_quit_babeld_cmd, "quit",
2473 "Exit current mode and down to previous mode\n")
a616ea5f 2474{
d62a17ae 2475 return vtysh_exit(vty);
a616ea5f 2476}
0eb5751d 2477#endif /* HAVE_BABELD */
a616ea5f 2478
0eb5751d 2479#ifdef HAVE_OSPF6D
d62a17ae 2480DEFUNSH(VTYSH_OSPF6D, vtysh_exit_ospf6d, vtysh_exit_ospf6d_cmd, "exit",
2481 "Exit current mode and down to previous mode\n")
68980084 2482{
d62a17ae 2483 return vtysh_exit(vty);
68980084 2484}
2485
d62a17ae 2486DEFUNSH(VTYSH_OSPF6D, vtysh_quit_ospf6d, vtysh_quit_ospf6d_cmd, "quit",
2487 "Exit current mode and down to previous mode\n")
a98d33ab 2488{
d62a17ae 2489 return vtysh_exit_ospf6d(self, vty, argc, argv);
a98d33ab 2490}
0eb5751d 2491#endif /* HAVE_OSPF6D */
68980084 2492
d62a17ae 2493#if defined(HAVE_LDPD)
2494DEFUNSH(VTYSH_LDPD, vtysh_exit_ldpd, vtysh_exit_ldpd_cmd, "exit",
2495 "Exit current mode and down to previous mode\n")
4fcbf6e2 2496{
d62a17ae 2497 return vtysh_exit(vty);
4fcbf6e2
RW
2498}
2499
d62a17ae 2500ALIAS(vtysh_exit_ldpd, vtysh_quit_ldpd_cmd, "quit",
2501 "Exit current mode and down to previous mode\n")
87ab4aec 2502#endif
4fcbf6e2 2503
0eb5751d 2504#ifdef HAVE_ISISD
d62a17ae 2505DEFUNSH(VTYSH_ISISD, vtysh_exit_isisd, vtysh_exit_isisd_cmd, "exit",
2506 "Exit current mode and down to previous mode\n")
c25e458a 2507{
d62a17ae 2508 return vtysh_exit(vty);
c25e458a 2509}
2510
d62a17ae 2511DEFUNSH(VTYSH_ISISD, vtysh_quit_isisd, vtysh_quit_isisd_cmd, "quit",
2512 "Exit current mode and down to previous mode\n")
a98d33ab 2513{
d62a17ae 2514 return vtysh_exit_isisd(self, vty, argc, argv);
a98d33ab 2515}
0eb5751d 2516#endif /* HAVE_ISISD */
c25e458a 2517
c2f29cf3
RZ
2518#if HAVE_BFDD > 0
2519DEFUNSH(VTYSH_BFDD, vtysh_exit_bfdd, vtysh_exit_bfdd_cmd, "exit",
2520 "Exit current mode and down to previous mode\n")
2521{
2522 return vtysh_exit(vty);
2523}
2524
2525ALIAS(vtysh_exit_bfdd, vtysh_quit_bfdd_cmd, "quit",
2526 "Exit current mode and down to previous mode\n")
2527#endif
2528
0eb5751d 2529#ifdef HAVE_FABRICD
770ccdf8
CF
2530DEFUNSH(VTYSH_FABRICD, vtysh_exit_fabricd, vtysh_exit_fabricd_cmd, "exit",
2531 "Exit current mode and down to previous mode\n")
2532{
2533 return vtysh_exit(vty);
2534}
2535
2536DEFUNSH(VTYSH_FABRICD, vtysh_quit_fabricd, vtysh_quit_fabricd_cmd, "quit",
2537 "Exit current mode and down to previous mode\n")
2538{
2539 return vtysh_exit_fabricd(self, vty, argc, argv);
2540}
0eb5751d 2541#endif /* HAVE_FABRICD */
770ccdf8 2542
949467e2
IR
2543DEFUNSH(VTYSH_KEYS, vtysh_exit_keys, vtysh_exit_keys_cmd, "exit",
2544 "Exit current mode and down to previous mode\n")
2545{
2546 return vtysh_exit(vty);
2547}
2548
2549DEFUNSH(VTYSH_KEYS, vtysh_quit_keys, vtysh_quit_keys_cmd, "quit",
2550 "Exit current mode and down to previous mode\n")
2551{
2552 return vtysh_exit_keys(self, vty, argc, argv);
2553}
2554
f7f6a796 2555#if defined(HAVE_PATHD)
4d7b695d
SM
2556DEFUNSH(VTYSH_PATHD, vtysh_exit_pathd, vtysh_exit_pathd_cmd, "exit",
2557 "Exit current mode and down to previous mode\n")
2558{
2559 return vtysh_exit(vty);
2560}
2561
2562DEFUNSH(VTYSH_PATHD, vtysh_quit_pathd, vtysh_quit_pathd_cmd, "quit",
2563 "Exit current mode and down to previous mode\n")
2564{
2565 return vtysh_exit_pathd(self, vty, argc, argv);
2566}
f7f6a796 2567#endif /* HAVE_PATHD */
4d7b695d 2568
d62a17ae 2569DEFUNSH(VTYSH_ALL, vtysh_exit_line_vty, vtysh_exit_line_vty_cmd, "exit",
2570 "Exit current mode and down to previous mode\n")
e7168df4 2571{
d62a17ae 2572 return vtysh_exit(vty);
e7168df4 2573}
2574
d62a17ae 2575DEFUNSH(VTYSH_ALL, vtysh_quit_line_vty, vtysh_quit_line_vty_cmd, "quit",
2576 "Exit current mode and down to previous mode\n")
a98d33ab 2577{
d62a17ae 2578 return vtysh_exit_line_vty(self, vty, argc, argv);
a98d33ab 2579}
e7168df4 2580
d62a17ae 2581DEFUNSH(VTYSH_INTERFACE, vtysh_interface, vtysh_interface_cmd,
2582 "interface IFNAME [vrf NAME]",
2583 "Select an interface to configure\n"
2584 "Interface's name\n" VRF_CMD_HELP_STR)
718e3744 2585{
d62a17ae 2586 vty->node = INTERFACE_NODE;
2587 return CMD_SUCCESS;
718e3744 2588}
2589
2dd0d726
RW
2590DEFUNSH(VTYSH_ZEBRA, vtysh_pseudowire, vtysh_pseudowire_cmd,
2591 "pseudowire IFNAME",
2592 "Static pseudowire configuration\n"
2593 "Pseudowire name\n")
2594{
2595 vty->node = PW_NODE;
2596 return CMD_SUCCESS;
2597}
2598
7183a034
MS
2599DEFUNSH(VTYSH_NH_GROUP,
2600 vtysh_nexthop_group, vtysh_nexthop_group_cmd,
868ee86c 2601 "nexthop-group NHGNAME",
e5c83d9b
DS
2602 "Nexthop Group configuration\n"
2603 "Name of the Nexthop Group\n")
2604{
2605 vty->node = NH_GROUP_NODE;
2606 return CMD_SUCCESS;
2607}
2608
7183a034 2609DEFSH(VTYSH_NH_GROUP, vtysh_no_nexthop_group_cmd,
868ee86c 2610 "no nexthop-group NHGNAME",
e5c83d9b
DS
2611 NO_STR
2612 "Nexthop Group Configuration\n"
2613 "Name of the Nexthop Group\n")
2614
d62a17ae 2615DEFUNSH(VTYSH_VRF, vtysh_vrf, vtysh_vrf_cmd, "vrf NAME",
2616 "Select a VRF to configure\n"
2617 "VRF's name\n")
e9d94ea7 2618{
d62a17ae 2619 vty->node = VRF_NODE;
2620 return CMD_SUCCESS;
e9d94ea7
DS
2621}
2622
34c46274
RW
2623DEFSH(VTYSH_ZEBRA, vtysh_vrf_netns_cmd,
2624 "netns NAME",
2625 "Attach VRF to a Namespace\n"
2626 "The file name in " NS_RUN_DIR ", or a full pathname\n")
2627
2628DEFSH(VTYSH_ZEBRA, vtysh_no_vrf_netns_cmd,
2629 "no netns [NAME]",
2630 NO_STR
2631 "Detach VRF from a Namespace\n"
2632 "The file name in " NS_RUN_DIR ", or a full pathname\n")
e9d94ea7 2633
d62a17ae 2634DEFUNSH(VTYSH_VRF, vtysh_exit_vrf, vtysh_exit_vrf_cmd, "exit",
2635 "Exit current mode and down to previous mode\n")
e9d94ea7 2636{
d62a17ae 2637 return vtysh_exit(vty);
e9d94ea7
DS
2638}
2639
d62a17ae 2640DEFUNSH(VTYSH_VRF, vtysh_quit_vrf, vtysh_quit_vrf_cmd, "quit",
2641 "Exit current mode and down to previous mode\n")
a98d33ab 2642{
d62a17ae 2643 return vtysh_exit_vrf(self, vty, argc, argv);
a98d33ab 2644}
e9d94ea7 2645
7183a034
MS
2646DEFUNSH(VTYSH_NH_GROUP,
2647 vtysh_exit_nexthop_group, vtysh_exit_nexthop_group_cmd,
e5c83d9b
DS
2648 "exit", "Exit current mode and down to previous mode\n")
2649{
2650 return vtysh_exit(vty);
2651}
2652
7183a034
MS
2653DEFUNSH(VTYSH_NH_GROUP,
2654 vtysh_quit_nexthop_group, vtysh_quit_nexthop_group_cmd,
e5c83d9b
DS
2655 "quit", "Exit current mode and down to previous mode\n")
2656{
2657 return vtysh_exit_nexthop_group(self, vty, argc, argv);
2658}
2659
d62a17ae 2660DEFUNSH(VTYSH_INTERFACE, vtysh_exit_interface, vtysh_exit_interface_cmd, "exit",
2661 "Exit current mode and down to previous mode\n")
718e3744 2662{
d62a17ae 2663 return vtysh_exit(vty);
718e3744 2664}
2665
d62a17ae 2666DEFUNSH(VTYSH_INTERFACE, vtysh_quit_interface, vtysh_quit_interface_cmd, "quit",
2667 "Exit current mode and down to previous mode\n")
a98d33ab 2668{
d62a17ae 2669 return vtysh_exit_interface(self, vty, argc, argv);
a98d33ab 2670}
718e3744 2671
a5eb3b0d
IR
2672static char *do_prepend(struct vty *vty, struct cmd_token **argv, int argc)
2673{
2674 const char *argstr[argc + 1];
2675 int i, off = 0;
2676
2677 if (vty->node != VIEW_NODE) {
2678 off = 1;
2679 argstr[0] = "do";
2680 }
2681
2682 for (i = 0; i < argc; i++)
2683 argstr[i + off] = argv[i]->arg;
2684
2685 return frrstr_join(argstr, argc + off, " ");
2686}
2687
2688static int show_per_daemon(struct vty *vty, struct cmd_token **argv, int argc,
2689 const char *headline)
8872626b
DS
2690{
2691 unsigned int i;
8872626b 2692 int ret = CMD_SUCCESS;
a5eb3b0d 2693 char *line = do_prepend(vty, argv, argc);
8872626b 2694
8872626b 2695 for (i = 0; i < array_size(vtysh_client); i++)
a4e2dac1 2696 if (vtysh_client[i].fd >= 0 || vtysh_client[i].next) {
a5eb3b0d 2697 vty_out(vty, headline, vtysh_client[i].name);
8872626b
DS
2698 ret = vtysh_client_execute(&vtysh_client[i], line);
2699 vty_out(vty, "\n");
2700 }
a5eb3b0d
IR
2701
2702 XFREE(MTYPE_TMP, line);
2703
2704 return ret;
2705}
2706
2707static int show_one_daemon(struct vty *vty, struct cmd_token **argv, int argc,
2708 const char *name)
2709{
2710 int ret;
2711 char *line = do_prepend(vty, argv, argc);
2712
2713 ret = vtysh_client_execute_name(name, line);
2714
2715 XFREE(MTYPE_TMP, line);
2716
8872626b
DS
2717 return ret;
2718}
2719
a5eb3b0d
IR
2720DEFUN (vtysh_show_poll,
2721 vtysh_show_poll_cmd,
2722 "show thread poll",
2723 SHOW_STR
2724 "Thread information\n"
2725 "Thread Poll Information\n")
2726{
2727 return show_per_daemon(vty, argv, argc, "Thread statistics for %s:\n");
2728}
2729
f75e802d 2730#ifndef EXCLUDE_CPU_TIME
0f69b58c
DS
2731DEFUN (vtysh_show_thread,
2732 vtysh_show_thread_cmd,
2733 "show thread cpu [FILTER]",
c25c6137
QY
2734 SHOW_STR
2735 "Thread information\n"
2736 "Thread CPU usage\n"
2737 "Display filter (rwtexb)\n")
0f69b58c 2738{
a5eb3b0d 2739 return show_per_daemon(vty, argv, argc, "Thread statistics for %s:\n");
0f69b58c 2740}
f75e802d 2741#endif
0f69b58c
DS
2742
2743DEFUN (vtysh_show_work_queues,
2744 vtysh_show_work_queues_cmd,
2745 "show work-queues",
2746 SHOW_STR
2747 "Work Queue information\n")
2748{
a5eb3b0d
IR
2749 return show_per_daemon(vty, argv, argc,
2750 "Work queue statistics for %s:\n");
0f69b58c
DS
2751}
2752
b47b0a84
DS
2753DEFUN (vtysh_show_work_queues_daemon,
2754 vtysh_show_work_queues_daemon_cmd,
2e77de95 2755 "show work-queues " DAEMONS_LIST,
b47b0a84
DS
2756 SHOW_STR
2757 "Work Queue information\n"
2e77de95 2758 DAEMONS_STR)
b47b0a84 2759{
a5eb3b0d 2760 return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
b47b0a84
DS
2761}
2762
d62a17ae 2763DEFUNSH(VTYSH_ZEBRA, vtysh_link_params, vtysh_link_params_cmd, "link-params",
2764 LINK_PARAMS_STR)
16f1b9ee 2765{
d62a17ae 2766 vty->node = LINK_PARAMS_NODE;
2767 return CMD_SUCCESS;
16f1b9ee
OD
2768}
2769
d62a17ae 2770DEFUNSH(VTYSH_ZEBRA, exit_link_params, exit_link_params_cmd, "exit-link-params",
2771 "Exit from Link Params configuration node\n")
03f99d9a 2772{
d62a17ae 2773 if (vty->node == LINK_PARAMS_NODE)
2774 vty->node = INTERFACE_NODE;
2775 return CMD_SUCCESS;
03f99d9a
DS
2776}
2777
aea03ad6
QY
2778DEFUNSH_HIDDEN (0x00,
2779 vtysh_debug_all,
2780 vtysh_debug_all_cmd,
2781 "[no] debug all",
2782 NO_STR
2783 DEBUG_STR
2784 "Toggle all debugs on or off\n")
2785{
2786 return CMD_SUCCESS;
2787}
2788
87f6dc50
DS
2789DEFUN (vtysh_show_debugging,
2790 vtysh_show_debugging_cmd,
2791 "show debugging",
2792 SHOW_STR
2793 DEBUG_STR)
2794{
a5eb3b0d 2795 return show_per_daemon(vty, argv, argc, "");
87f6dc50
DS
2796}
2797
40818cec
DL
2798DEFUN (vtysh_show_debugging_hashtable,
2799 vtysh_show_debugging_hashtable_cmd,
2800 "show debugging hashtable [statistics]",
2801 SHOW_STR
2802 DEBUG_STR
2803 "Statistics about hash tables\n"
2804 "Statistics about hash tables\n")
2805{
a5eb3b0d
IR
2806 bool stats = strmatch(argv[argc - 1]->text, "statistics");
2807
2cddf2ff
QY
2808 vty_out(vty, "\n");
2809 vty_out(vty,
44deef01 2810 "Load factor (LF) - average number of elements across all buckets\n");
2cddf2ff 2811 vty_out(vty,
44deef01 2812 "Full load factor (FLF) - average number of elements across full buckets\n\n");
2cddf2ff 2813 vty_out(vty,
44deef01 2814 "Standard deviation (SD) is calculated for both the LF and FLF\n");
2cddf2ff 2815 vty_out(vty,
44deef01 2816 "and indicates the typical deviation of bucket chain length\n");
2cddf2ff 2817 vty_out(vty, "from the value in the corresponding load factor.\n\n");
44deef01 2818
a5eb3b0d 2819 return show_per_daemon(vty, argv, stats ? argc - 1 : argc,
40818cec
DL
2820 "Hashtable statistics for %s:\n");
2821}
2822
7b526b61
QY
2823DEFUN (vtysh_show_error_code,
2824 vtysh_show_error_code_cmd,
ed8841d3 2825 "show error <(1-4294967296)|all> [json]",
7b526b61
QY
2826 SHOW_STR
2827 "Information on errors\n"
ed8841d3
QY
2828 "Error code to get info about\n"
2829 "Information on all errors\n"
2830 JSON_STR)
7b526b61 2831{
1f9128d6
QY
2832 uint32_t arg = 0;
2833
2834 if (!strmatch(argv[2]->text, "all"))
2835 arg = strtoul(argv[2]->arg, NULL, 10);
2836
2837 /* If it's not a shared code, send it to all the daemons */
2838 if (arg < LIB_FERR_START || arg > LIB_FERR_END) {
a5eb3b0d 2839 show_per_daemon(vty, argv, argc, "");
1f9128d6
QY
2840 /* Otherwise, print it ourselves to avoid duplication */
2841 } else {
2842 bool json = strmatch(argv[argc - 1]->text, "json");
2d6e4d2e 2843
1f9128d6
QY
2844 if (!strmatch(argv[2]->text, "all"))
2845 arg = strtoul(argv[2]->arg, NULL, 10);
2846
2847 log_ref_display(vty, arg, json);
2848 }
ed8841d3 2849
1f9128d6 2850 return CMD_SUCCESS;
7b526b61
QY
2851}
2852
4ad77140 2853/* Northbound. */
122ee38a 2854DEFUN_HIDDEN (show_config_running,
bcbe60d4
IR
2855 show_config_running_cmd,
2856 "show configuration running\
2857 [<json|xml> [translate WORD]]\
2858 [with-defaults]" DAEMONS_LIST,
2859 SHOW_STR
2860 "Configuration information\n"
2861 "Running configuration\n"
2862 "Change output format to JSON\n"
2863 "Change output format to XML\n"
2864 "Translate output\n"
2865 "YANG module translator\n"
2866 "Show default values\n"
2867 DAEMONS_STR)
2868{
2869 return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
2870}
2871
eba4e1ea
RW
2872DEFUN (show_yang_operational_data,
2873 show_yang_operational_data_cmd,
21f5aade 2874 "show yang operational-data XPATH\
eba4e1ea 2875 [{\
21f5aade
RW
2876 format <json|xml>\
2877 |translate WORD\
eba4e1ea
RW
2878 }]" DAEMONS_LIST,
2879 SHOW_STR
2880 "YANG information\n"
2881 "Show YANG operational data\n"
2882 "XPath expression specifying the YANG data path\n"
2883 "Set the output format\n"
2884 "JavaScript Object Notation\n"
2885 "Extensible Markup Language\n"
2886 "Translate operational data\n"
2887 "YANG module translator\n"
2888 DAEMONS_STR)
2889{
a5eb3b0d 2890 return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
eba4e1ea
RW
2891}
2892
3bb513c3
CH
2893DEFUN(show_yang_module, show_yang_module_cmd,
2894 "show yang module [module-translator WORD] " DAEMONS_LIST,
2895 SHOW_STR
2896 "YANG information\n"
2897 "Show loaded modules\n"
2898 "YANG module translator\n"
2899 "YANG module translator\n" DAEMONS_STR)
2900{
2901 return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
2902}
2903
2904DEFUN(show_yang_module_detail, show_yang_module_detail_cmd,
2905 "show yang module\
2906 [module-translator WORD]\
2907 WORD <compiled|summary|tree|yang|yin> " DAEMONS_LIST,
2908 SHOW_STR
2909 "YANG information\n"
2910 "Show loaded modules\n"
2911 "YANG module translator\n"
2912 "YANG module translator\n"
2913 "Module name\n"
2914 "Display compiled module in YANG format\n"
2915 "Display summary information about the module\n"
2916 "Display module in the tree (RFC 8340) format\n"
2917 "Display module in the YANG format\n"
2918 "Display module in the YIN format\n" DAEMONS_STR)
2919{
2920 return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
2921}
2922
2923
4ad77140
RW
2924DEFUNSH(VTYSH_ALL, debug_nb,
2925 debug_nb_cmd,
2926 "[no] debug northbound\
2927 [<\
21f5aade
RW
2928 callbacks [{configuration|state|rpc}]\
2929 |notifications\
2930 |events\
62ae9ade 2931 |libyang\
4ad77140
RW
2932 >]",
2933 NO_STR
2934 DEBUG_STR
2935 "Northbound debugging\n"
2936 "Callbacks\n"
2937 "Configuration\n"
2938 "State\n"
2939 "RPC\n"
2940 "Notifications\n"
62ae9ade
RW
2941 "Events\n"
2942 "libyang debugging\n")
4ad77140
RW
2943{
2944 return CMD_SUCCESS;
2945}
2946
a65f4b5d
DS
2947DEFUN (vtysh_show_history,
2948 vtysh_show_history_cmd,
2949 "show history",
2950 SHOW_STR
2951 "The list of commands stored in history\n")
2952{
2953 HIST_ENTRY **hlist = history_list();
2954 int i = 0;
2955
2956 while (hlist[i]) {
2957 vty_out(vty, "%s\n", hlist[i]->line);
2958 i++;
2959 }
2960 return CMD_SUCCESS;
2961}
2962
2a8e27af
DL
2963/* Memory */
2964DEFUN (vtysh_show_memory,
2965 vtysh_show_memory_cmd,
f09e0369 2966 "show memory [" DAEMONS_LIST "]",
2a8e27af 2967 SHOW_STR
f09e0369
IR
2968 "Memory statistics\n"
2969 DAEMONS_STR)
2a8e27af 2970{
f09e0369
IR
2971 if (argc == 3)
2972 return show_one_daemon(vty, argv, argc - 1,
2973 argv[argc - 1]->text);
2974
a5eb3b0d 2975 return show_per_daemon(vty, argv, argc, "Memory statistics for %s:\n");
2a8e27af
DL
2976}
2977
2978DEFUN (vtysh_show_modules,
2979 vtysh_show_modules_cmd,
2980 "show modules",
2981 SHOW_STR
2982 "Loaded modules\n")
2983{
a5eb3b0d 2984 return show_per_daemon(vty, argv, argc, "Module information for %s:\n");
2a8e27af
DL
2985}
2986
95e735b5 2987/* Logging commands. */
dbf7d13d
PJ
2988DEFUN (vtysh_show_logging,
2989 vtysh_show_logging_cmd,
2990 "show logging",
2991 SHOW_STR
2992 "Show current logging configuration\n")
2993{
a5eb3b0d 2994 return show_per_daemon(vty, argv, argc,
7292d851 2995 "Logging configuration for %s:\n");
d62a17ae 2996}
2997
85a6806d
MS
2998DEFUNSH(VTYSH_ALL, vtysh_debug_memstats,
2999 vtysh_debug_memstats_cmd, "[no] debug memstats-at-exit",
3000 NO_STR
3001 "Debug\n"
3002 "Print memory statistics at exit\n")
3003{
3004 return CMD_SUCCESS;
3005}
3006
d62a17ae 3007DEFUNSH(VTYSH_ALL, vtysh_service_password_encrypt,
3008 vtysh_service_password_encrypt_cmd, "service password-encryption",
3009 "Set up miscellaneous service\n"
3010 "Enable encrypted passwords\n")
e7168df4 3011{
d62a17ae 3012 return CMD_SUCCESS;
e7168df4 3013}
3014
d62a17ae 3015DEFUNSH(VTYSH_ALL, no_vtysh_service_password_encrypt,
3016 no_vtysh_service_password_encrypt_cmd, "no service password-encryption",
3017 NO_STR
3018 "Set up miscellaneous service\n"
3019 "Enable encrypted passwords\n")
e7168df4 3020{
d62a17ae 3021 return CMD_SUCCESS;
e7168df4 3022}
3023
d62a17ae 3024DEFUNSH(VTYSH_ALL, vtysh_config_password, vtysh_password_cmd,
3025 "password [(8-8)] LINE",
322e2d5c 3026 "Modify the terminal connection password\n"
d62a17ae 3027 "Specifies a HIDDEN password will follow\n"
3028 "The password string\n")
e7168df4 3029{
d62a17ae 3030 return CMD_SUCCESS;
e7168df4 3031}
3032
322e2d5c
PM
3033DEFUNSH(VTYSH_ALL, no_vtysh_config_password, no_vtysh_password_cmd,
3034 "no password", NO_STR
3035 "Modify the terminal connection password\n")
3036{
4911ca9c 3037 vty_out(vty, NO_PASSWD_CMD_WARNING);
eb83f7ce 3038
322e2d5c
PM
3039 return CMD_SUCCESS;
3040}
3041
d62a17ae 3042DEFUNSH(VTYSH_ALL, vtysh_config_enable_password, vtysh_enable_password_cmd,
3043 "enable password [(8-8)] LINE",
3044 "Modify enable password parameters\n"
3045 "Assign the privileged level password\n"
3046 "Specifies a HIDDEN password will follow\n"
3047 "The 'enable' password string\n")
e7168df4 3048{
d62a17ae 3049 return CMD_SUCCESS;
e7168df4 3050}
3051
d62a17ae 3052DEFUNSH(VTYSH_ALL, no_vtysh_config_enable_password,
9d303b37 3053 no_vtysh_enable_password_cmd, "no enable password", NO_STR
d62a17ae 3054 "Modify enable password parameters\n"
3055 "Assign the privileged level password\n")
e7168df4 3056{
4911ca9c 3057 vty_out(vty, NO_PASSWD_CMD_WARNING);
eb83f7ce 3058
d62a17ae 3059 return CMD_SUCCESS;
e7168df4 3060}
3061
718e3744 3062DEFUN (vtysh_write_terminal,
3063 vtysh_write_terminal_cmd,
30941443 3064 "write terminal ["DAEMONS_LIST"] [no-header]",
718e3744 3065 "Write running configuration to memory, network, or terminal\n"
066242b5 3066 "Write to terminal\n"
30941443
DL
3067 DAEMONS_STR
3068 "Skip \"Building configuration...\" header\n")
718e3744 3069{
d7c0a89a 3070 unsigned int i;
d62a17ae 3071 char line[] = "do write terminal\n";
d62a17ae 3072
30941443
DL
3073 if (!strcmp(argv[argc - 1]->arg, "no-header"))
3074 argc--;
3075 else {
3076 vty_out(vty, "Building configuration...\n");
3077 vty_out(vty, "\nCurrent configuration:\n");
3078 vty_out(vty, "!\n");
3079 }
d62a17ae 3080
3081 for (i = 0; i < array_size(vtysh_client); i++)
3082 if ((argc < 3)
3083 || (strmatch(vtysh_client[i].name, argv[2]->text)))
3084 vtysh_client_config(&vtysh_client[i], line);
3085
3086 /* Integrate vtysh specific configuration. */
2cddf2ff 3087 vty_open_pager(vty);
d62a17ae 3088 vtysh_config_write();
2cddf2ff
QY
3089 vtysh_config_dump();
3090 vty_close_pager(vty);
3091 vty_out(vty, "end\n");
d62a17ae 3092
d62a17ae 3093 return CMD_SUCCESS;
718e3744 3094}
3095
a98d33ab
QY
3096DEFUN (vtysh_show_running_config,
3097 vtysh_show_running_config_cmd,
30941443 3098 "show running-config ["DAEMONS_LIST"] [no-header]",
a98d33ab
QY
3099 SHOW_STR
3100 "Current operating configuration\n"
30941443
DL
3101 DAEMONS_STR
3102 "Skip \"Building configuration...\" header\n")
c006e89e 3103{
d62a17ae 3104 return vtysh_write_terminal(self, vty, argc, argv);
c006e89e
DS
3105}
3106
e7168df4 3107DEFUN (vtysh_integrated_config,
3108 vtysh_integrated_config_cmd,
3109 "service integrated-vtysh-config",
3110 "Set up miscellaneous service\n"
3111 "Write configuration into integrated file\n")
4fc01e67 3112{
d62a17ae 3113 vtysh_write_integrated = WRITE_INTEGRATED_YES;
3114 return CMD_SUCCESS;
4fc01e67 3115}
3116
e7168df4 3117DEFUN (no_vtysh_integrated_config,
3118 no_vtysh_integrated_config_cmd,
3119 "no service integrated-vtysh-config",
3120 NO_STR
3121 "Set up miscellaneous service\n"
3122 "Write configuration into integrated file\n")
4fc01e67 3123{
d62a17ae 3124 vtysh_write_integrated = WRITE_INTEGRATED_NO;
3125 return CMD_SUCCESS;
4fc01e67 3126}
3127
d62a17ae 3128static void backup_config_file(const char *fbackup)
718e3744 3129{
d62a17ae 3130 char *integrate_sav = NULL;
718e3744 3131
2e600d75
QY
3132 size_t integrate_sav_sz = strlen(fbackup) + strlen(CONF_BACKUP_EXT) + 1;
3133 integrate_sav = malloc(integrate_sav_sz);
3134 strlcpy(integrate_sav, fbackup, integrate_sav_sz);
3135 strlcat(integrate_sav, CONF_BACKUP_EXT, integrate_sav_sz);
718e3744 3136
d62a17ae 3137 /* Move current configuration file to backup config file. */
9fb05a74
TA
3138 if (unlink(integrate_sav) != 0 && errno != ENOENT)
3139 vty_out(vty, "Unlink failed for %s: %s\n", integrate_sav,
3140 strerror(errno));
3141 if (rename(fbackup, integrate_sav) != 0 && errno != ENOENT)
3142 vty_out(vty, "Error renaming %s to %s: %s\n", fbackup,
3143 integrate_sav, strerror(errno));
d62a17ae 3144 free(integrate_sav);
a7222276
DS
3145}
3146
d62a17ae 3147int vtysh_write_config_integrated(void)
a7222276 3148{
d7c0a89a 3149 unsigned int i;
d62a17ae 3150 char line[] = "do write terminal\n";
3151 FILE *fp;
3152 int fd;
029a775e 3153#ifdef FRR_USER
d62a17ae 3154 struct passwd *pwentry;
029a775e 3155#endif
3156#ifdef FRR_GROUP
d62a17ae 3157 struct group *grentry;
029a775e 3158#endif
d62a17ae 3159 uid_t uid = -1;
3160 gid_t gid = -1;
3161 struct stat st;
3162 int err = 0;
a7222276 3163
2cddf2ff 3164 vty_out(vty, "Building Configuration...\n");
a7222276 3165
9b8a8249
DL
3166 backup_config_file(frr_config);
3167 fp = fopen(frr_config, "w");
d62a17ae 3168 if (fp == NULL) {
2cddf2ff 3169 vty_out(vty,
d62a17ae 3170 "%% Error: failed to open configuration file %s: %s\n",
9b8a8249 3171 frr_config, safe_strerror(errno));
d62a17ae 3172 return CMD_WARNING_CONFIG_FAILED;
3173 }
3174 fd = fileno(fp);
a7222276 3175
d62a17ae 3176 for (i = 0; i < array_size(vtysh_client); i++)
3177 vtysh_client_config(&vtysh_client[i], line);
718e3744 3178
d62a17ae 3179 vtysh_config_write();
b7ae6ac4
QY
3180 vty->of_saved = vty->of;
3181 vty->of = fp;
2cddf2ff 3182 vtysh_config_dump();
b7ae6ac4 3183 vty->of = vty->of_saved;
718e3744 3184
d62a17ae 3185 if (fchmod(fd, CONFIGFILE_MASK) != 0) {
3186 printf("%% Warning: can't chmod configuration file %s: %s\n",
9b8a8249 3187 frr_config, safe_strerror(errno));
d62a17ae 3188 err++;
3189 }
718e3744 3190
9e8df988 3191#ifdef FRR_USER
d62a17ae 3192 pwentry = getpwnam(FRR_USER);
3193 if (pwentry)
3194 uid = pwentry->pw_uid;
3195 else {
3196 printf("%% Warning: could not look up user \"%s\"\n", FRR_USER);
3197 err++;
3198 }
9e8df988
JAG
3199#endif
3200#ifdef FRR_GROUP
d62a17ae 3201 grentry = getgrnam(FRR_GROUP);
3202 if (grentry)
3203 gid = grentry->gr_gid;
3204 else {
3205 printf("%% Warning: could not look up group \"%s\"\n",
3206 FRR_GROUP);
3207 err++;
3208 }
9e8df988 3209#endif
4fc01e67 3210
d62a17ae 3211 if (!fstat(fd, &st)) {
3212 if (st.st_uid == uid)
3213 uid = -1;
3214 if (st.st_gid == gid)
3215 gid = -1;
3216 if ((uid != (uid_t)-1 || gid != (gid_t)-1)
3217 && fchown(fd, uid, gid)) {
3218 printf("%% Warning: can't chown configuration file %s: %s\n",
9b8a8249 3219 frr_config, safe_strerror(errno));
d62a17ae 3220 err++;
3221 }
3222 } else {
9b8a8249 3223 printf("%% Warning: stat() failed on %s: %s\n", frr_config,
d62a17ae 3224 safe_strerror(errno));
3225 err++;
3226 }
3227
3228 fclose(fp);
3229
9b8a8249 3230 printf("Integrated configuration saved to %s\n", frr_config);
d62a17ae 3231 if (err)
3232 return CMD_WARNING;
3233
3234 printf("[OK]\n");
3235 return CMD_SUCCESS;
718e3744 3236}
3237
a68f8616 3238static bool want_config_integrated(void)
039eaca3 3239{
d62a17ae 3240 struct stat s;
3241
3242 switch (vtysh_write_integrated) {
3243 case WRITE_INTEGRATED_UNSPECIFIED:
9b8a8249 3244 if (stat(frr_config, &s) && errno == ENOENT)
d62a17ae 3245 return false;
3246 return true;
3247 case WRITE_INTEGRATED_NO:
3248 return false;
3249 case WRITE_INTEGRATED_YES:
3250 return true;
3251 }
3252 return true;
039eaca3
CF
3253}
3254
4fc01e67 3255DEFUN (vtysh_write_memory,
3256 vtysh_write_memory_cmd,
a98d33ab 3257 "write [<memory|file>]",
4fc01e67 3258 "Write running configuration to memory, network, or terminal\n"
a98d33ab
QY
3259 "Write configuration to the file (same as write file)\n"
3260 "Write configuration to the file (same as write memory)\n")
4fc01e67 3261{
d62a17ae 3262 int ret = CMD_SUCCESS;
3263 char line[] = "do write memory\n";
d7c0a89a 3264 unsigned int i;
d62a17ae 3265
2cddf2ff 3266 vty_out(vty, "Note: this version of vtysh never writes vtysh.conf\n");
d62a17ae 3267
3268 /* If integrated frr.conf explicitely set. */
3269 if (want_config_integrated()) {
3270 ret = CMD_WARNING_CONFIG_FAILED;
869f5586
QY
3271
3272 /* first attempt to use watchfrr if it's available */
3273 bool used_watchfrr = false;
3274
d62a17ae 3275 for (i = 0; i < array_size(vtysh_client); i++)
3276 if (vtysh_client[i].flag == VTYSH_WATCHFRR)
3277 break;
869f5586
QY
3278 if (i < array_size(vtysh_client) && vtysh_client[i].fd != -1) {
3279 used_watchfrr = true;
d62a17ae 3280 ret = vtysh_client_execute(&vtysh_client[i],
2cddf2ff 3281 "do write integrated");
869f5586 3282 }
d62a17ae 3283
470bc619 3284 /*
869f5586
QY
3285 * If we didn't use watchfrr, fallback to writing the config
3286 * ourselves
470bc619 3287 */
869f5586 3288 if (!used_watchfrr) {
3efd0893 3289 printf("\nWarning: attempting direct configuration write without watchfrr.\nFile permissions and ownership may be incorrect, or write may fail.\n\n");
d62a17ae 3290 ret = vtysh_write_config_integrated();
3291 }
3292 return ret;
3293 }
a7222276 3294
2cddf2ff 3295 vty_out(vty, "Building Configuration...\n");
a7222276 3296
d62a17ae 3297 for (i = 0; i < array_size(vtysh_client); i++)
2cddf2ff 3298 ret = vtysh_client_execute(&vtysh_client[i], line);
4fc01e67 3299
d62a17ae 3300 return ret;
4fc01e67 3301}
3302
a98d33ab
QY
3303DEFUN (vtysh_copy_running_config,
3304 vtysh_copy_running_config_cmd,
3305 "copy running-config startup-config",
718e3744 3306 "Copy from one file to another\n"
3307 "Copy from current system configuration\n"
3308 "Copy to startup configuration\n")
a98d33ab 3309{
d62a17ae 3310 return vtysh_write_memory(self, vty, argc, argv);
a98d33ab 3311}
718e3744 3312
874f579d
MS
3313DEFUN (vtysh_copy_to_running,
3314 vtysh_copy_to_running_cmd,
3315 "copy FILENAME running-config",
3316 "Apply a configuration file\n"
3317 "Configuration file to read\n"
3318 "Apply to current configuration\n")
3319{
3320 int ret;
3321 const char *fname = argv[1]->arg;
3322
77f7b4b0 3323 ret = vtysh_read_config(fname, true);
874f579d
MS
3324
3325 /* Return to enable mode - the 'read_config' api leaves us up a level */
3326 vtysh_execute_no_pager("enable");
3327
3328 return ret;
3329}
3330
76fd5262
DL
3331DEFUN (vtysh_terminal_paginate,
3332 vtysh_terminal_paginate_cmd,
3333 "[no] terminal paginate",
3334 NO_STR
3335 "Set terminal line parameters\n"
3336 "Use pager for output scrolling\n")
3337{
3338 free(vtysh_pager_name);
3339 vtysh_pager_name = NULL;
3340
3341 if (strcmp(argv[0]->text, "no"))
1569f224 3342 vtysh_pager_envdef(true);
76fd5262
DL
3343 return CMD_SUCCESS;
3344}
3345
34553cc3 3346DEFUN (vtysh_terminal_length,
3347 vtysh_terminal_length_cmd,
76fd5262
DL
3348 "[no] terminal length (0-4294967295)",
3349 NO_STR
34553cc3 3350 "Set terminal line parameters\n"
3351 "Set number of lines on a screen\n"
76fd5262 3352 "Number of lines on screen (0 for no pausing, nonzero to use pager)\n")
34553cc3 3353{
d62a17ae 3354 int idx_number = 2;
76fd5262 3355 unsigned long lines;
34553cc3 3356
76fd5262
DL
3357 free(vtysh_pager_name);
3358 vtysh_pager_name = NULL;
34553cc3 3359
76fd5262
DL
3360 if (!strcmp(argv[0]->text, "no") || !strcmp(argv[1]->text, "no")) {
3361 /* "terminal no length" = use VTYSH_PAGER */
1569f224 3362 vtysh_pager_envdef(true);
76fd5262 3363 return CMD_SUCCESS;
d62a17ae 3364 }
34553cc3 3365
76fd5262 3366 lines = strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 3367 if (lines != 0) {
76fd5262
DL
3368 vty_out(vty,
3369 "%% The \"terminal length\" command is deprecated and its value is ignored.\n"
3370 "%% Please use \"terminal paginate\" instead with OS TTY length handling.\n");
1569f224 3371 vtysh_pager_envdef(true);
d62a17ae 3372 }
34553cc3 3373
d62a17ae 3374 return CMD_SUCCESS;
34553cc3 3375}
3376
76fd5262 3377ALIAS_DEPRECATED(vtysh_terminal_length,
34553cc3 3378 vtysh_terminal_no_length_cmd,
3379 "terminal no length",
3380 "Set terminal line parameters\n"
3381 NO_STR
3382 "Set number of lines on a screen\n")
34553cc3 3383
f2799e69 3384DEFUN (vtysh_show_daemons,
3385 vtysh_show_daemons_cmd,
3386 "show daemons",
e7168df4 3387 SHOW_STR
3388 "Show list of running daemons\n")
3389{
d7c0a89a 3390 unsigned int i;
b1aa147d 3391
d62a17ae 3392 for (i = 0; i < array_size(vtysh_client); i++)
3393 if (vtysh_client[i].fd >= 0)
2cddf2ff
QY
3394 vty_out(vty, " %s", vtysh_client[i].name);
3395 vty_out(vty, "\n");
e7168df4 3396
d62a17ae 3397 return CMD_SUCCESS;
e7168df4 3398}
3399
718e3744 3400/* Execute command in child process. */
996c9314
LB
3401static void execute_command(const char *command, int argc, const char *arg1,
3402 const char *arg2)
d62a17ae 3403{
3404 pid_t pid;
3405 int status;
3406
3407 /* Call fork(). */
3408 pid = fork();
3409
3410 if (pid < 0) {
3411 /* Failure of fork(). */
3412 fprintf(stderr, "Can't fork: %s\n", safe_strerror(errno));
3413 exit(1);
3414 } else if (pid == 0) {
3415 /* This is child process. */
3416 switch (argc) {
3417 case 0:
3418 execlp(command, command, (const char *)NULL);
3419 break;
3420 case 1:
3421 execlp(command, command, arg1, (const char *)NULL);
3422 break;
3423 case 2:
3424 execlp(command, command, arg1, arg2,
3425 (const char *)NULL);
3426 break;
3427 }
718e3744 3428
d62a17ae 3429 /* When execlp suceed, this part is not executed. */
3430 fprintf(stderr, "Can't execute %s: %s\n", command,
3431 safe_strerror(errno));
3432 exit(1);
3433 } else {
3434 /* This is parent. */
3435 execute_flag = 1;
3436 wait4(pid, &status, 0, NULL);
3437 execute_flag = 0;
3438 }
718e3744 3439}
3440
3441DEFUN (vtysh_ping,
3442 vtysh_ping_cmd,
3443 "ping WORD",
4eeccf18 3444 "Send echo messages\n"
718e3744 3445 "Ping destination address or hostname\n")
3446{
137a1684
DS
3447 int idx = 1;
3448
3449 argv_find(argv, argc, "WORD", &idx);
3450 execute_command("ping", 1, argv[idx]->arg, NULL);
d62a17ae 3451 return CMD_SUCCESS;
718e3744 3452}
3453
d62a17ae 3454ALIAS(vtysh_ping, vtysh_ping_ip_cmd, "ping ip WORD",
3455 "Send echo messages\n"
3456 "IP echo\n"
3457 "Ping destination address or hostname\n")
4eeccf18 3458
718e3744 3459DEFUN (vtysh_traceroute,
3460 vtysh_traceroute_cmd,
3461 "traceroute WORD",
3462 "Trace route to destination\n"
3463 "Trace route to destination address or hostname\n")
3464{
137a1684
DS
3465 int idx = 1;
3466
3467 argv_find(argv, argc, "WORD", &idx);
3468 execute_command("traceroute", 1, argv[idx]->arg, NULL);
d62a17ae 3469 return CMD_SUCCESS;
718e3744 3470}
3471
d62a17ae 3472ALIAS(vtysh_traceroute, vtysh_traceroute_ip_cmd, "traceroute ip WORD",
3473 "Trace route to destination\n"
3474 "IP trace\n"
3475 "Trace route to destination address or hostname\n")
4eeccf18 3476
4d9ad5dc
MS
3477DEFUN (vtysh_mtrace,
3478 vtysh_mtrace_cmd,
71e55fb2 3479 "mtrace WORD [WORD]",
4d9ad5dc 3480 "Multicast trace route to multicast source\n"
71e55fb2
MS
3481 "Multicast trace route to multicast source address\n"
3482 "Multicast trace route for multicast group address\n")
4d9ad5dc 3483{
71e55fb2
MS
3484 if (argc == 2)
3485 execute_command("mtracebis", 1, argv[1]->arg, NULL);
3486 else
3487 execute_command("mtracebis", 2, argv[1]->arg, argv[2]->arg);
4d9ad5dc
MS
3488 return CMD_SUCCESS;
3489}
3490
4eeccf18 3491DEFUN (vtysh_ping6,
3492 vtysh_ping6_cmd,
3493 "ping ipv6 WORD",
3494 "Send echo messages\n"
3495 "IPv6 echo\n"
3496 "Ping destination address or hostname\n")
3497{
137a1684 3498 execute_command("ping6", 1, argv[2]->arg, NULL);
d62a17ae 3499 return CMD_SUCCESS;
4eeccf18 3500}
3501
3502DEFUN (vtysh_traceroute6,
3503 vtysh_traceroute6_cmd,
3504 "traceroute ipv6 WORD",
3505 "Trace route to destination\n"
3506 "IPv6 trace\n"
3507 "Trace route to destination address or hostname\n")
3508{
137a1684 3509 execute_command("traceroute6", 1, argv[2]->arg, NULL);
d62a17ae 3510 return CMD_SUCCESS;
4eeccf18 3511}
4eeccf18 3512
576b6b5d 3513#if defined(HAVE_SHELL_ACCESS)
718e3744 3514DEFUN (vtysh_telnet,
3515 vtysh_telnet_cmd,
3516 "telnet WORD",
3517 "Open a telnet connection\n"
3518 "IP address or hostname of a remote system\n")
3519{
137a1684 3520 execute_command("telnet", 1, argv[1]->arg, NULL);
d62a17ae 3521 return CMD_SUCCESS;
718e3744 3522}
3523
3524DEFUN (vtysh_telnet_port,
3525 vtysh_telnet_port_cmd,
3526 "telnet WORD PORT",
3527 "Open a telnet connection\n"
3528 "IP address or hostname of a remote system\n"
3529 "TCP Port number\n")
3530{
137a1684 3531 execute_command("telnet", 2, argv[1]->arg, argv[2]->arg);
d62a17ae 3532 return CMD_SUCCESS;
718e3744 3533}
3534
5087df56 3535DEFUN (vtysh_ssh,
3536 vtysh_ssh_cmd,
3537 "ssh WORD",
3538 "Open an ssh connection\n"
3539 "[user@]host\n")
3540{
137a1684 3541 execute_command("ssh", 1, argv[1]->arg, NULL);
d62a17ae 3542 return CMD_SUCCESS;
5087df56 3543}
3544
718e3744 3545DEFUN (vtysh_start_shell,
3546 vtysh_start_shell_cmd,
3547 "start-shell",
3548 "Start UNIX shell\n")
3549{
d62a17ae 3550 execute_command("sh", 0, NULL, NULL);
3551 return CMD_SUCCESS;
718e3744 3552}
3553
3554DEFUN (vtysh_start_bash,
3555 vtysh_start_bash_cmd,
3556 "start-shell bash",
3557 "Start UNIX shell\n"
3558 "Start bash\n")
3559{
d62a17ae 3560 execute_command("bash", 0, NULL, NULL);
3561 return CMD_SUCCESS;
718e3744 3562}
3563
3564DEFUN (vtysh_start_zsh,
3565 vtysh_start_zsh_cmd,
3566 "start-shell zsh",
3567 "Start UNIX shell\n"
3568 "Start Z shell\n")
3569{
d62a17ae 3570 execute_command("zsh", 0, NULL, NULL);
3571 return CMD_SUCCESS;
718e3744 3572}
576b6b5d 3573#endif
b094d260 3574
0b84f294
DL
3575DEFUN (config_list,
3576 config_list_cmd,
3577 "list [permutations]",
3578 "Print command list\n"
3579 "Print all possible command permutations\n")
3580{
d62a17ae 3581 return cmd_list_cmds(vty, argc == 2);
0b84f294
DL
3582}
3583
193a5a95
QY
3584DEFUN (vtysh_output_file,
3585 vtysh_output_file_cmd,
3586 "output file FILE",
3587 "Direct vtysh output to file\n"
3588 "Direct vtysh output to file\n"
3589 "Path to dump output to\n")
3590{
3591 const char *path = argv[argc - 1]->arg;
2cddf2ff
QY
3592 vty->of = fopen(path, "a");
3593 if (!vty->of) {
3594 vty_out(vty, "Failed to open file '%s': %s\n", path,
193a5a95 3595 safe_strerror(errno));
2cddf2ff 3596 vty->of = stdout;
193a5a95
QY
3597 }
3598 return CMD_SUCCESS;
3599}
3600
3601DEFUN (no_vtysh_output_file,
3602 no_vtysh_output_file_cmd,
3603 "no output file [FILE]",
3604 NO_STR
3605 "Direct vtysh output to file\n"
3606 "Direct vtysh output to file\n"
3607 "Path to dump output to\n")
3608{
2cddf2ff
QY
3609 if (vty->of != stdout) {
3610 fclose(vty->of);
3611 vty->of = stdout;
193a5a95
QY
3612 }
3613 return CMD_SUCCESS;
3614}
3615
cf6c83e7
QY
3616DEFUN(find,
3617 find_cmd,
767f67a4 3618 "find REGEX...",
68912a20
QY
3619 "Find CLI command matching a regular expression\n"
3620 "Search pattern (POSIX regex)\n")
cf6c83e7 3621{
cf6c83e7
QY
3622 const struct cmd_node *node;
3623 const struct cmd_element *cli;
3624 vector clis;
68912a20 3625 regex_t exp = {};
767f67a4 3626 char *pattern = argv_concat(argv, argc, 1);
68912a20
QY
3627 int cr = regcomp(&exp, pattern, REG_NOSUB | REG_EXTENDED);
3628
767f67a4
QY
3629 XFREE(MTYPE_TMP, pattern);
3630
68912a20
QY
3631 if (cr != 0) {
3632 switch (cr) {
3633 case REG_BADBR:
3634 vty_out(vty, "%% Invalid \\{...\\} expression\n");
3635 break;
3636 case REG_BADRPT:
3637 vty_out(vty, "%% Bad repetition operator\n");
3638 break;
3639 case REG_BADPAT:
3640 vty_out(vty, "%% Regex syntax error\n");
3641 break;
3642 case REG_ECOLLATE:
3643 vty_out(vty, "%% Invalid collating element\n");
3644 break;
3645 case REG_ECTYPE:
3646 vty_out(vty, "%% Invalid character class name\n");
3647 break;
3648 case REG_EESCAPE:
3649 vty_out(vty,
3650 "%% Regex ended with escape character (\\)\n");
3651 break;
3652 case REG_ESUBREG:
3653 vty_out(vty,
3654 "%% Invalid number in \\digit construction\n");
3655 break;
3656 case REG_EBRACK:
3657 vty_out(vty, "%% Unbalanced square brackets\n");
3658 break;
3659 case REG_EPAREN:
3660 vty_out(vty, "%% Unbalanced parentheses\n");
3661 break;
3662 case REG_EBRACE:
3663 vty_out(vty, "%% Unbalanced braces\n");
3664 break;
3665 case REG_ERANGE:
3666 vty_out(vty,
3667 "%% Invalid endpoint in range expression\n");
3668 break;
3669 case REG_ESPACE:
3670 vty_out(vty, "%% Failed to compile (out of memory)\n");
3671 break;
3672 }
3673
3674 goto done;
3675 }
3676
3677
cf6c83e7
QY
3678 for (unsigned int i = 0; i < vector_active(cmdvec); i++) {
3679 node = vector_slot(cmdvec, i);
3680 if (!node)
3681 continue;
3682 clis = node->cmd_vector;
3683 for (unsigned int j = 0; j < vector_active(clis); j++) {
3684 cli = vector_slot(clis, j);
68912a20
QY
3685
3686 if (regexec(&exp, cli->string, 0, NULL, 0) == 0)
2cddf2ff 3687 vty_out(vty, " (%s) %s\n",
f4b8291f 3688 node->name, cli->string);
cf6c83e7
QY
3689 }
3690 }
3691
68912a20
QY
3692done:
3693 regfree(&exp);
cf6c83e7
QY
3694 return CMD_SUCCESS;
3695}
3696
26fbe472
QY
3697DEFUN_HIDDEN(show_cli_graph_vtysh,
3698 show_cli_graph_vtysh_cmd,
3699 "show cli graph",
3700 SHOW_STR
3701 "CLI reflection\n"
3702 "Dump current command space as DOT graph\n")
3703{
3704 struct cmd_node *cn = vector_slot(cmdvec, vty->node);
3705 char *dot = cmd_graph_dump_dot(cn->cmdgraph);
3706
3707 vty_out(vty, "%s\n", dot);
3708 XFREE(MTYPE_TMP, dot);
3709 return CMD_SUCCESS;
3710}
3711
d62a17ae 3712static void vtysh_install_default(enum node_type node)
718e3744 3713{
01485adb
DL
3714 _install_element(node, &config_list_cmd);
3715 _install_element(node, &find_cmd);
3716 _install_element(node, &show_cli_graph_vtysh_cmd);
3717 _install_element(node, &vtysh_output_file_cmd);
3718 _install_element(node, &no_vtysh_output_file_cmd);
718e3744 3719}
3720
3721/* Making connection to protocol daemon. */
d62a17ae 3722static int vtysh_connect(struct vtysh_client *vclient)
3723{
3724 int ret;
3725 int sock, len;
3726 struct sockaddr_un addr;
3727 struct stat s_stat;
3728 const char *path;
3729
3730 if (!vclient->path[0])
3731 snprintf(vclient->path, sizeof(vclient->path), "%s/%s.vty",
9b8a8249 3732 vtydir, vclient->name);
d62a17ae 3733 path = vclient->path;
3734
3735 /* Stat socket to see if we have permission to access it. */
3736 ret = stat(path, &s_stat);
3737 if (ret < 0 && errno != ENOENT) {
3738 fprintf(stderr, "vtysh_connect(%s): stat = %s\n", path,
3739 safe_strerror(errno));
3740 exit(1);
3741 }
3742
3743 if (ret >= 0) {
3744 if (!S_ISSOCK(s_stat.st_mode)) {
3745 fprintf(stderr, "vtysh_connect(%s): Not a socket\n",
3746 path);
3747 exit(1);
3748 }
718e3744 3749 }
718e3744 3750
d62a17ae 3751 sock = socket(AF_UNIX, SOCK_STREAM, 0);
3752 if (sock < 0) {
718e3744 3753#ifdef DEBUG
d62a17ae 3754 fprintf(stderr, "vtysh_connect(%s): socket = %s\n", path,
3755 safe_strerror(errno));
718e3744 3756#endif /* DEBUG */
d62a17ae 3757 return -1;
3758 }
718e3744 3759
d62a17ae 3760 memset(&addr, 0, sizeof(struct sockaddr_un));
3761 addr.sun_family = AF_UNIX;
3762 strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
6f0e3f6e 3763#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
d62a17ae 3764 len = addr.sun_len = SUN_LEN(&addr);
718e3744 3765#else
d62a17ae 3766 len = sizeof(addr.sun_family) + strlen(addr.sun_path);
6f0e3f6e 3767#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
718e3744 3768
d62a17ae 3769 ret = connect(sock, (struct sockaddr *)&addr, len);
3770 if (ret < 0) {
718e3744 3771#ifdef DEBUG
d62a17ae 3772 fprintf(stderr, "vtysh_connect(%s): connect = %s\n", path,
3773 safe_strerror(errno));
718e3744 3774#endif /* DEBUG */
d62a17ae 3775 close(sock);
3776 return -1;
3777 }
3778 vclient->fd = sock;
718e3744 3779
d62a17ae 3780 return 0;
718e3744 3781}
3782
67736451
MS
3783static int vtysh_reconnect(struct vtysh_client *vclient)
3784{
3785 int ret;
3786
3787 fprintf(stderr, "Warning: connecting to %s...", vclient->name);
3788 ret = vtysh_connect(vclient);
3789 if (ret < 0) {
3790 fprintf(stderr, "failed!\n");
3791 return ret;
3792 }
3793 fprintf(stderr, "success!\n");
2cddf2ff 3794 if (vtysh_client_execute(vclient, "enable") < 0)
67736451
MS
3795 return -1;
3796 return vtysh_execute_no_pager("end");
3797}
3798
7c8ff89e 3799/* Return true if str ends with suffix, else return false */
d62a17ae 3800static int ends_with(const char *str, const char *suffix)
7c8ff89e 3801{
d62a17ae 3802 if (!str || !suffix)
3803 return 0;
3804 size_t lenstr = strlen(str);
3805 size_t lensuffix = strlen(suffix);
3806 if (lensuffix > lenstr)
3807 return 0;
3808 return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
7c8ff89e
DS
3809}
3810
d62a17ae 3811static void vtysh_client_sorted_insert(struct vtysh_client *head_client,
3812 struct vtysh_client *client)
7c8ff89e 3813{
d62a17ae 3814 struct vtysh_client *prev_node, *current_node;
7c8ff89e 3815
d62a17ae 3816 prev_node = head_client;
3817 current_node = head_client->next;
3818 while (current_node) {
3819 if (strcmp(current_node->path, client->path) > 0)
3820 break;
7c8ff89e 3821
d62a17ae 3822 prev_node = current_node;
3823 current_node = current_node->next;
3824 }
3825 client->next = current_node;
3826 prev_node->next = client;
7c8ff89e
DS
3827}
3828
3829#define MAXIMUM_INSTANCES 10
3830
462ea14a 3831static void vtysh_update_all_instances(struct vtysh_client *head_client)
d62a17ae 3832{
3833 struct vtysh_client *client;
3834 DIR *dir;
3835 struct dirent *file;
3836 int n = 0;
3837
3838 if (head_client->flag != VTYSH_OSPFD)
3839 return;
3840
3841 /* ls vty_sock_dir and look for all files ending in .vty */
9b8a8249 3842 dir = opendir(vtydir);
d62a17ae 3843 if (dir) {
3844 while ((file = readdir(dir)) != NULL) {
90cf59ec 3845 if (frrstr_startswith(file->d_name, "ospfd-")
d62a17ae 3846 && ends_with(file->d_name, ".vty")) {
3847 if (n == MAXIMUM_INSTANCES) {
3848 fprintf(stderr,
3849 "Parsing %s, client limit(%d) reached!\n",
9b8a8249 3850 vtydir, n);
d62a17ae 3851 break;
3852 }
3853 client = (struct vtysh_client *)malloc(
3854 sizeof(struct vtysh_client));
3855 client->fd = -1;
3856 client->name = "ospfd";
3857 client->flag = VTYSH_OSPFD;
3858 snprintf(client->path, sizeof(client->path),
9b8a8249 3859 "%s/%s", vtydir, file->d_name);
d62a17ae 3860 client->next = NULL;
3861 vtysh_client_sorted_insert(head_client, client);
3862 n++;
3863 }
3864 }
3865 closedir(dir);
3866 }
3867}
3868
3869static int vtysh_connect_all_instances(struct vtysh_client *head_client)
3870{
3871 struct vtysh_client *client;
3872 int rc = 0;
3873
462ea14a 3874 vtysh_update_all_instances(head_client);
d62a17ae 3875
3876 client = head_client->next;
3877 while (client) {
3878 if (vtysh_connect(client) == 0)
3879 rc++;
3880 client = client->next;
3881 }
3882
3883 return rc;
3884}
3885
3886int vtysh_connect_all(const char *daemon_name)
3887{
d7c0a89a 3888 unsigned int i;
d62a17ae 3889 int rc = 0;
3890 int matches = 0;
3891
3892 for (i = 0; i < array_size(vtysh_client); i++) {
3893 if (!daemon_name
3894 || !strcmp(daemon_name, vtysh_client[i].name)) {
3895 matches++;
3896 if (vtysh_connect(&vtysh_client[i]) == 0)
3897 rc++;
3898
3899 rc += vtysh_connect_all_instances(&vtysh_client[i]);
3900 }
3901 }
3902 if (!matches)
3903 fprintf(stderr, "Error: no daemons match name %s!\n",
3904 daemon_name);
3905 return rc;
718e3744 3906}
3907
95e735b5 3908/* To disable readline's filename completion. */
d62a17ae 3909static char *vtysh_completion_entry_function(const char *ignore,
3910 int invoking_key)
718e3744 3911{
d62a17ae 3912 return NULL;
718e3744 3913}
3914
d62a17ae 3915void vtysh_readline_init(void)
718e3744 3916{
d62a17ae 3917 /* readline related settings. */
dab6893f
QY
3918 char *disable_bracketed_paste =
3919 XSTRDUP(MTYPE_TMP, "set enable-bracketed-paste off");
3920
d62a17ae 3921 rl_initialize();
dab6893f 3922 rl_parse_and_bind(disable_bracketed_paste);
d62a17ae 3923 rl_bind_key('?', (rl_command_func_t *)vtysh_rl_describe);
3924 rl_completion_entry_function = vtysh_completion_entry_function;
7c70dc57 3925 rl_attempted_completion_function = new_completion;
dab6893f
QY
3926
3927 XFREE(MTYPE_TMP, disable_bracketed_paste);
718e3744 3928}
3929
d62a17ae 3930char *vtysh_prompt(void)
718e3744 3931{
63e653a2 3932 static char buf[512];
718e3744 3933
0d6f7fd6 3934 snprintf(buf, sizeof(buf), cmd_prompt(vty->node), cmd_hostname_get());
d62a17ae 3935 return buf;
718e3744 3936}
3937
7f059ea6
DL
3938static void vtysh_ac_line(void *arg, const char *line)
3939{
d62a17ae 3940 vector comps = arg;
3941 size_t i;
3942 for (i = 0; i < vector_active(comps); i++)
3943 if (!strcmp(line, (char *)vector_slot(comps, i)))
3944 return;
3945 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, line));
7f059ea6
DL
3946}
3947
3948static void vtysh_autocomplete(vector comps, struct cmd_token *token)
3949{
d62a17ae 3950 char accmd[256];
3951 size_t i;
7f059ea6 3952
d62a17ae 3953 snprintf(accmd, sizeof(accmd), "autocomplete %d %s %s", token->type,
3954 token->text, token->varname ? token->varname : "-");
7f059ea6 3955
8d70e7fe
QY
3956 vty->of_saved = vty->of;
3957 vty->of = NULL;
d62a17ae 3958 for (i = 0; i < array_size(vtysh_client); i++)
2cddf2ff
QY
3959 vtysh_client_run_all(&vtysh_client[i], accmd, 1, vtysh_ac_line,
3960 comps);
8d70e7fe 3961 vty->of = vty->of_saved;
7f059ea6
DL
3962}
3963
1d6664e0 3964static const struct cmd_variable_handler vtysh_var_handler[] = {
d62a17ae 3965 {/* match all */
3966 .tokenname = NULL,
3967 .varname = NULL,
3968 .completions = vtysh_autocomplete},
3969 {.completions = NULL}};
3970
4d762f26 3971void vtysh_uninit(void)
193a5a95 3972{
2cddf2ff
QY
3973 if (vty->of != stdout)
3974 fclose(vty->of);
193a5a95
QY
3975}
3976
d62a17ae 3977void vtysh_init_vty(void)
3978{
3979 /* Make vty structure. */
3980 vty = vty_new();
3981 vty->type = VTY_SHELL;
3982 vty->node = VIEW_NODE;
3983
193a5a95 3984 /* set default output */
2cddf2ff 3985 vty->of = stdout;
1569f224 3986 vtysh_pager_envdef(false);
193a5a95 3987
d62a17ae 3988 /* Initialize commands. */
3989 cmd_init(0);
3990 cmd_variable_handler_register(vtysh_var_handler);
3991
5d574646 3992 /* bgpd */
0eb5751d 3993#ifdef HAVE_BGPD
612c2c15 3994 install_node(&bgp_node);
5d574646
IR
3995 install_element(CONFIG_NODE, &router_bgp_cmd);
3996 install_element(BGP_NODE, &vtysh_exit_bgpd_cmd);
3997 install_element(BGP_NODE, &vtysh_quit_bgpd_cmd);
3998 install_element(BGP_NODE, &vtysh_end_all_cmd);
3999
612c2c15 4000 install_node(&bgp_vpnv4_node);
5d574646
IR
4001 install_element(BGP_NODE, &address_family_ipv4_vpn_cmd);
4002#ifdef KEEP_OLD_VPN_COMMANDS
4003 install_element(BGP_NODE, &address_family_vpnv4_cmd);
4004#endif /* KEEP_OLD_VPN_COMMANDS */
4005 install_element(BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd);
4006 install_element(BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd);
4007 install_element(BGP_VPNV4_NODE, &vtysh_end_all_cmd);
4008 install_element(BGP_VPNV4_NODE, &exit_address_family_cmd);
4009
612c2c15 4010 install_node(&bgp_vpnv6_node);
5d574646
IR
4011 install_element(BGP_NODE, &address_family_ipv6_vpn_cmd);
4012#ifdef KEEP_OLD_VPN_COMMANDS
4013 install_element(BGP_NODE, &address_family_vpnv6_cmd);
4014#endif /* KEEP_OLD_VPN_COMMANDS */
4015 install_element(BGP_VPNV6_NODE, &vtysh_exit_bgpd_cmd);
4016 install_element(BGP_VPNV6_NODE, &vtysh_quit_bgpd_cmd);
4017 install_element(BGP_VPNV6_NODE, &vtysh_end_all_cmd);
4018 install_element(BGP_VPNV6_NODE, &exit_address_family_cmd);
4019
612c2c15 4020 install_node(&bgp_flowspecv4_node);
5d574646
IR
4021 install_element(BGP_NODE, &address_family_flowspecv4_cmd);
4022 install_element(BGP_FLOWSPECV4_NODE, &vtysh_exit_bgpd_cmd);
4023 install_element(BGP_FLOWSPECV4_NODE, &vtysh_quit_bgpd_cmd);
4024 install_element(BGP_FLOWSPECV4_NODE, &vtysh_end_all_cmd);
4025 install_element(BGP_FLOWSPECV4_NODE, &exit_address_family_cmd);
4026
612c2c15 4027 install_node(&bgp_flowspecv6_node);
5d574646
IR
4028 install_element(BGP_NODE, &address_family_flowspecv6_cmd);
4029 install_element(BGP_FLOWSPECV6_NODE, &vtysh_exit_bgpd_cmd);
4030 install_element(BGP_FLOWSPECV6_NODE, &vtysh_quit_bgpd_cmd);
4031 install_element(BGP_FLOWSPECV6_NODE, &vtysh_end_all_cmd);
4032 install_element(BGP_FLOWSPECV6_NODE, &exit_address_family_cmd);
4033
612c2c15 4034 install_node(&bgp_ipv4_node);
5d574646
IR
4035 install_element(BGP_NODE, &address_family_ipv4_cmd);
4036 install_element(BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd);
4037 install_element(BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd);
4038 install_element(BGP_IPV4_NODE, &vtysh_end_all_cmd);
4039 install_element(BGP_IPV4_NODE, &exit_address_family_cmd);
4040
612c2c15 4041 install_node(&bgp_ipv4m_node);
5d574646
IR
4042 install_element(BGP_NODE, &address_family_ipv4_multicast_cmd);
4043 install_element(BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd);
4044 install_element(BGP_IPV4M_NODE, &vtysh_quit_bgpd_cmd);
4045 install_element(BGP_IPV4M_NODE, &vtysh_end_all_cmd);
4046 install_element(BGP_IPV4M_NODE, &exit_address_family_cmd);
4047
612c2c15 4048 install_node(&bgp_ipv4l_node);
5d574646
IR
4049 install_element(BGP_NODE, &address_family_ipv4_labeled_unicast_cmd);
4050 install_element(BGP_IPV4L_NODE, &vtysh_exit_bgpd_cmd);
4051 install_element(BGP_IPV4L_NODE, &vtysh_quit_bgpd_cmd);
4052 install_element(BGP_IPV4L_NODE, &vtysh_end_all_cmd);
4053 install_element(BGP_IPV4L_NODE, &exit_address_family_cmd);
4054
612c2c15 4055 install_node(&bgp_ipv6_node);
5d574646
IR
4056 install_element(BGP_NODE, &address_family_ipv6_cmd);
4057 install_element(BGP_IPV6_NODE, &vtysh_exit_bgpd_cmd);
4058 install_element(BGP_IPV6_NODE, &vtysh_quit_bgpd_cmd);
4059 install_element(BGP_IPV6_NODE, &vtysh_end_all_cmd);
4060 install_element(BGP_IPV6_NODE, &exit_address_family_cmd);
4061
612c2c15 4062 install_node(&bgp_ipv6m_node);
5d574646
IR
4063 install_element(BGP_NODE, &address_family_ipv6_multicast_cmd);
4064 install_element(BGP_IPV6M_NODE, &vtysh_exit_bgpd_cmd);
4065 install_element(BGP_IPV6M_NODE, &vtysh_quit_bgpd_cmd);
4066 install_element(BGP_IPV6M_NODE, &vtysh_end_all_cmd);
4067 install_element(BGP_IPV6M_NODE, &exit_address_family_cmd);
4068
612c2c15 4069 install_node(&bgp_ipv6l_node);
5d574646
IR
4070 install_element(BGP_NODE, &address_family_ipv6_labeled_unicast_cmd);
4071 install_element(BGP_IPV6L_NODE, &vtysh_exit_bgpd_cmd);
4072 install_element(BGP_IPV6L_NODE, &vtysh_quit_bgpd_cmd);
4073 install_element(BGP_IPV6L_NODE, &vtysh_end_all_cmd);
4074 install_element(BGP_IPV6L_NODE, &exit_address_family_cmd);
4075
4076#if defined(ENABLE_BGP_VNC)
612c2c15 4077 install_node(&bgp_vrf_policy_node);
5d574646
IR
4078 install_element(BGP_NODE, &vnc_vrf_policy_cmd);
4079 install_element(BGP_VRF_POLICY_NODE, &vtysh_exit_bgpd_cmd);
4080 install_element(BGP_VRF_POLICY_NODE, &vtysh_quit_bgpd_cmd);
4081 install_element(BGP_VRF_POLICY_NODE, &vtysh_end_all_cmd);
4082 install_element(BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd);
4083
612c2c15 4084 install_node(&bgp_vnc_defaults_node);
5d574646
IR
4085 install_element(BGP_NODE, &vnc_defaults_cmd);
4086 install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_exit_bgpd_cmd);
4087 install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_quit_bgpd_cmd);
4088 install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_end_all_cmd);
4089 install_element(BGP_VNC_DEFAULTS_NODE, &exit_vnc_config_cmd);
4090
612c2c15 4091 install_node(&bgp_vnc_nve_group_node);
5d574646
IR
4092 install_element(BGP_NODE, &vnc_nve_group_cmd);
4093 install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_exit_bgpd_cmd);
4094 install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_quit_bgpd_cmd);
4095 install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_end_all_cmd);
4096 install_element(BGP_VNC_NVE_GROUP_NODE, &exit_vnc_config_cmd);
4097
612c2c15 4098 install_node(&bgp_vnc_l2_group_node);
5d574646
IR
4099 install_element(BGP_NODE, &vnc_l2_group_cmd);
4100 install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_exit_bgpd_cmd);
4101 install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_quit_bgpd_cmd);
4102 install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_end_all_cmd);
4103 install_element(BGP_VNC_L2_GROUP_NODE, &exit_vnc_config_cmd);
4104#endif
d62a17ae 4105
5d574646
IR
4106 install_node(&bgp_evpn_node);
4107 install_element(BGP_NODE, &address_family_evpn_cmd);
4108#if defined(HAVE_CUMULUS)
4109 install_element(BGP_NODE, &address_family_evpn2_cmd);
4110#endif
4111 install_element(BGP_EVPN_NODE, &vtysh_quit_bgpd_cmd);
4112 install_element(BGP_EVPN_NODE, &vtysh_exit_bgpd_cmd);
4113 install_element(BGP_EVPN_NODE, &vtysh_end_all_cmd);
4114 install_element(BGP_EVPN_NODE, &exit_address_family_cmd);
d62a17ae 4115
5d574646
IR
4116 install_node(&bgp_evpn_vni_node);
4117 install_element(BGP_EVPN_NODE, &bgp_evpn_vni_cmd);
4118 install_element(BGP_EVPN_VNI_NODE, &vtysh_exit_bgpd_cmd);
4119 install_element(BGP_EVPN_VNI_NODE, &vtysh_quit_bgpd_cmd);
4120 install_element(BGP_EVPN_VNI_NODE, &vtysh_end_all_cmd);
4121 install_element(BGP_EVPN_VNI_NODE, &exit_vni_cmd);
d62a17ae 4122
5d574646
IR
4123 install_node(&rpki_node);
4124 install_element(CONFIG_NODE, &rpki_cmd);
4125 install_element(RPKI_NODE, &rpki_exit_cmd);
4126 install_element(RPKI_NODE, &rpki_quit_cmd);
4127 install_element(RPKI_NODE, &vtysh_end_all_cmd);
4128
4129 install_node(&bmp_node);
4130 install_element(BGP_NODE, &bmp_targets_cmd);
4131 install_element(BMP_NODE, &bmp_exit_cmd);
4132 install_element(BMP_NODE, &bmp_quit_cmd);
4133 install_element(BMP_NODE, &vtysh_end_all_cmd);
0eb5751d 4134#endif /* HAVE_BGPD */
5d574646
IR
4135
4136 /* ripd */
4137 install_node(&rip_node);
0eb5751d 4138#ifdef HAVE_RIPD
5d574646 4139 install_element(CONFIG_NODE, &router_rip_cmd);
d62a17ae 4140 install_element(RIP_NODE, &vtysh_exit_ripd_cmd);
4141 install_element(RIP_NODE, &vtysh_quit_ripd_cmd);
5d574646 4142 install_element(RIP_NODE, &vtysh_end_all_cmd);
0eb5751d 4143#endif /* HAVE_RIPD */
5d574646
IR
4144
4145 /* ripngd */
4146 install_node(&ripng_node);
0eb5751d 4147#ifdef HAVE_RIPNGD
5d574646 4148 install_element(CONFIG_NODE, &router_ripng_cmd);
d62a17ae 4149 install_element(RIPNG_NODE, &vtysh_exit_ripngd_cmd);
4150 install_element(RIPNG_NODE, &vtysh_quit_ripngd_cmd);
5d574646 4151 install_element(RIPNG_NODE, &vtysh_end_all_cmd);
0eb5751d 4152#endif /* HAVE_RIPNGD */
5d574646
IR
4153
4154 /* ospfd */
0eb5751d 4155#ifdef HAVE_OSPFD
5d574646
IR
4156 install_node(&ospf_node);
4157 install_element(CONFIG_NODE, &router_ospf_cmd);
d62a17ae 4158 install_element(OSPF_NODE, &vtysh_exit_ospfd_cmd);
4159 install_element(OSPF_NODE, &vtysh_quit_ospfd_cmd);
5d574646 4160 install_element(OSPF_NODE, &vtysh_end_all_cmd);
0eb5751d 4161#endif /* HAVE_OSPFD */
5d574646
IR
4162
4163 /* ospf6d */
0eb5751d 4164#ifdef HAVE_OSPF6D
5d574646
IR
4165 install_node(&ospf6_node);
4166 install_element(CONFIG_NODE, &router_ospf6_cmd);
d62a17ae 4167 install_element(OSPF6_NODE, &vtysh_exit_ospf6d_cmd);
4168 install_element(OSPF6_NODE, &vtysh_quit_ospf6d_cmd);
5d574646 4169 install_element(OSPF6_NODE, &vtysh_end_all_cmd);
0eb5751d 4170#endif /* HAVE_OSPF6D */
5d574646
IR
4171
4172 /* ldpd */
d62a17ae 4173#if defined(HAVE_LDPD)
5d574646
IR
4174 install_node(&ldp_node);
4175 install_element(CONFIG_NODE, &ldp_mpls_ldp_cmd);
d62a17ae 4176 install_element(LDP_NODE, &vtysh_exit_ldpd_cmd);
4177 install_element(LDP_NODE, &vtysh_quit_ldpd_cmd);
5d574646
IR
4178 install_element(LDP_NODE, &vtysh_end_all_cmd);
4179
4180 install_node(&ldp_ipv4_node);
4181 install_element(LDP_NODE, &ldp_address_family_ipv4_cmd);
d62a17ae 4182 install_element(LDP_IPV4_NODE, &vtysh_exit_ldpd_cmd);
4183 install_element(LDP_IPV4_NODE, &vtysh_quit_ldpd_cmd);
983bd6f7 4184 install_element(LDP_IPV4_NODE, &ldp_exit_address_family_cmd);
5d574646
IR
4185 install_element(LDP_IPV4_NODE, &vtysh_end_all_cmd);
4186
4187 install_node(&ldp_ipv6_node);
4188 install_element(LDP_NODE, &ldp_address_family_ipv6_cmd);
d62a17ae 4189 install_element(LDP_IPV6_NODE, &vtysh_exit_ldpd_cmd);
4190 install_element(LDP_IPV6_NODE, &vtysh_quit_ldpd_cmd);
983bd6f7 4191 install_element(LDP_IPV6_NODE, &ldp_exit_address_family_cmd);
5d574646
IR
4192 install_element(LDP_IPV6_NODE, &vtysh_end_all_cmd);
4193
4194 install_node(&ldp_ipv4_iface_node);
4195 install_element(LDP_IPV4_NODE, &ldp_interface_ifname_cmd);
d62a17ae 4196 install_element(LDP_IPV4_IFACE_NODE, &vtysh_exit_ldpd_cmd);
4197 install_element(LDP_IPV4_IFACE_NODE, &vtysh_quit_ldpd_cmd);
5d574646
IR
4198 install_element(LDP_IPV4_IFACE_NODE, &vtysh_end_all_cmd);
4199
4200 install_node(&ldp_ipv6_iface_node);
4201 install_element(LDP_IPV6_NODE, &ldp_interface_ifname_cmd);
d62a17ae 4202 install_element(LDP_IPV6_IFACE_NODE, &vtysh_exit_ldpd_cmd);
4203 install_element(LDP_IPV6_IFACE_NODE, &vtysh_quit_ldpd_cmd);
5d574646
IR
4204 install_element(LDP_IPV6_IFACE_NODE, &vtysh_end_all_cmd);
4205
4206 install_node(&ldp_l2vpn_node);
4207 install_element(CONFIG_NODE, &ldp_l2vpn_word_type_vpls_cmd);
d62a17ae 4208 install_element(LDP_L2VPN_NODE, &vtysh_exit_ldpd_cmd);
4209 install_element(LDP_L2VPN_NODE, &vtysh_quit_ldpd_cmd);
5d574646
IR
4210 install_element(LDP_L2VPN_NODE, &vtysh_end_all_cmd);
4211
4212 install_node(&ldp_pseudowire_node);
4213 install_element(LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd);
d62a17ae 4214 install_element(LDP_PSEUDOWIRE_NODE, &vtysh_exit_ldpd_cmd);
4215 install_element(LDP_PSEUDOWIRE_NODE, &vtysh_quit_ldpd_cmd);
5d574646 4216 install_element(LDP_PSEUDOWIRE_NODE, &vtysh_end_all_cmd);
87ab4aec 4217#endif
5d574646
IR
4218
4219 /* eigrpd */
0eb5751d 4220#ifdef HAVE_EIGRPD
5d574646
IR
4221 install_node(&eigrp_node);
4222 install_element(CONFIG_NODE, &router_eigrp_cmd);
4223 install_element(EIGRP_NODE, &vtysh_exit_eigrpd_cmd);
4224 install_element(EIGRP_NODE, &vtysh_quit_eigrpd_cmd);
4225 install_element(EIGRP_NODE, &vtysh_end_all_cmd);
0eb5751d 4226#endif /* HAVE_EIGRPD */
5d574646
IR
4227
4228 /* babeld */
0eb5751d 4229#ifdef HAVE_BABELD
5d574646
IR
4230 install_node(&babel_node);
4231 install_element(CONFIG_NODE, &router_babel_cmd);
4232 install_element(BABEL_NODE, &vtysh_exit_babeld_cmd);
4233 install_element(BABEL_NODE, &vtysh_quit_babeld_cmd);
4234 install_element(BABEL_NODE, &vtysh_end_all_cmd);
0eb5751d 4235#endif /* HAVE_BABELD */
5d574646
IR
4236
4237 /* isisd */
0eb5751d 4238#ifdef HAVE_ISISD
5d574646
IR
4239 install_node(&isis_node);
4240 install_element(CONFIG_NODE, &router_isis_cmd);
d62a17ae 4241 install_element(ISIS_NODE, &vtysh_exit_isisd_cmd);
4242 install_element(ISIS_NODE, &vtysh_quit_isisd_cmd);
5d574646 4243 install_element(ISIS_NODE, &vtysh_end_all_cmd);
0eb5751d 4244#endif /* HAVE_ISISD */
5d574646
IR
4245
4246 /* fabricd */
0eb5751d 4247#ifdef HAVE_FABRICD
5d574646
IR
4248 install_node(&openfabric_node);
4249 install_element(CONFIG_NODE, &router_openfabric_cmd);
770ccdf8
CF
4250 install_element(OPENFABRIC_NODE, &vtysh_exit_fabricd_cmd);
4251 install_element(OPENFABRIC_NODE, &vtysh_quit_fabricd_cmd);
5d574646 4252 install_element(OPENFABRIC_NODE, &vtysh_end_all_cmd);
0eb5751d 4253#endif /* HAVE_FABRICD */
5d574646
IR
4254
4255 /* pbrd */
0eb5751d 4256#ifdef HAVE_PBRD
5d574646
IR
4257 install_node(&pbr_map_node);
4258 install_element(CONFIG_NODE, &vtysh_pbr_map_cmd);
4259 install_element(CONFIG_NODE, &vtysh_no_pbr_map_cmd);
e5c83d9b
DS
4260 install_element(PBRMAP_NODE, &vtysh_exit_pbr_map_cmd);
4261 install_element(PBRMAP_NODE, &vtysh_quit_pbr_map_cmd);
5d574646 4262 install_element(PBRMAP_NODE, &vtysh_end_all_cmd);
0eb5751d 4263#endif /* HAVE_PBRD */
5d574646
IR
4264
4265 /* bfdd */
c2f29cf3 4266#if HAVE_BFDD > 0
5d574646 4267 install_node(&bfd_node);
c2f29cf3 4268 install_element(CONFIG_NODE, &bfd_enter_cmd);
c2f29cf3
RZ
4269 install_element(BFD_NODE, &vtysh_exit_bfdd_cmd);
4270 install_element(BFD_NODE, &vtysh_quit_bfdd_cmd);
5d574646
IR
4271 install_element(BFD_NODE, &vtysh_end_all_cmd);
4272
4273 install_node(&bfd_peer_node);
4274 install_element(BFD_NODE, &bfd_peer_enter_cmd);
c2f29cf3
RZ
4275 install_element(BFD_PEER_NODE, &vtysh_exit_bfdd_cmd);
4276 install_element(BFD_PEER_NODE, &vtysh_quit_bfdd_cmd);
5d574646
IR
4277 install_element(BFD_PEER_NODE, &vtysh_end_all_cmd);
4278
4279 install_node(&bfd_profile_node);
4280 install_element(BFD_NODE, &bfd_profile_enter_cmd);
d40d6c22
RZ
4281 install_element(BFD_PROFILE_NODE, &vtysh_exit_bfdd_cmd);
4282 install_element(BFD_PROFILE_NODE, &vtysh_quit_bfdd_cmd);
d40d6c22 4283 install_element(BFD_PROFILE_NODE, &vtysh_end_all_cmd);
c2f29cf3 4284#endif /* HAVE_BFDD */
d62a17ae 4285
4d7b695d
SM
4286#if defined(HAVE_PATHD)
4287 install_node(&segment_routing_node);
4288 install_node(&sr_traffic_eng_node);
4289 install_node(&srte_segment_list_node);
4290 install_node(&srte_policy_node);
4291 install_node(&srte_candidate_dyn_node);
4292
4293 install_element(SEGMENT_ROUTING_NODE, &vtysh_exit_pathd_cmd);
4294 install_element(SEGMENT_ROUTING_NODE, &vtysh_quit_pathd_cmd);
4295 install_element(SR_TRAFFIC_ENG_NODE, &vtysh_exit_pathd_cmd);
4296 install_element(SR_TRAFFIC_ENG_NODE, &vtysh_quit_pathd_cmd);
4297 install_element(SR_SEGMENT_LIST_NODE, &vtysh_exit_pathd_cmd);
4298 install_element(SR_SEGMENT_LIST_NODE, &vtysh_quit_pathd_cmd);
4299 install_element(SR_POLICY_NODE, &vtysh_exit_pathd_cmd);
4300 install_element(SR_POLICY_NODE, &vtysh_quit_pathd_cmd);
4301 install_element(SR_CANDIDATE_DYN_NODE, &vtysh_exit_pathd_cmd);
4302 install_element(SR_CANDIDATE_DYN_NODE, &vtysh_quit_pathd_cmd);
4303
4304 install_element(SEGMENT_ROUTING_NODE, &vtysh_end_all_cmd);
4305 install_element(SR_TRAFFIC_ENG_NODE, &vtysh_end_all_cmd);
4306 install_element(SR_SEGMENT_LIST_NODE, &vtysh_end_all_cmd);
4307 install_element(SR_POLICY_NODE, &vtysh_end_all_cmd);
4308 install_element(SR_CANDIDATE_DYN_NODE, &vtysh_end_all_cmd);
4309
4310 install_element(CONFIG_NODE, &segment_routing_cmd);
4311 install_element(SEGMENT_ROUTING_NODE, &sr_traffic_eng_cmd);
4312 install_element(SR_TRAFFIC_ENG_NODE, &srte_segment_list_cmd);
4313 install_element(SR_TRAFFIC_ENG_NODE, &srte_policy_cmd);
4314 install_element(SR_POLICY_NODE, &srte_policy_candidate_dyn_path_cmd);
efba0985
SM
4315
4316#if defined(HAVE_PATHD_PCEP)
4317 install_node(&pcep_node);
4318 install_node(&pcep_pcc_node);
4319 install_node(&pcep_pce_node);
4320 install_node(&pcep_pce_config_node);
4321
4322 install_element(PCEP_NODE, &vtysh_exit_pathd_cmd);
4323 install_element(PCEP_NODE, &vtysh_quit_pathd_cmd);
4324 install_element(PCEP_PCC_NODE, &vtysh_exit_pathd_cmd);
4325 install_element(PCEP_PCC_NODE, &vtysh_quit_pathd_cmd);
4326 install_element(PCEP_PCE_NODE, &vtysh_exit_pathd_cmd);
4327 install_element(PCEP_PCE_NODE, &vtysh_quit_pathd_cmd);
4328 install_element(PCEP_PCE_CONFIG_NODE, &vtysh_exit_pathd_cmd);
4329 install_element(PCEP_PCE_CONFIG_NODE, &vtysh_quit_pathd_cmd);
4330
4331 install_element(PCEP_NODE, &vtysh_end_all_cmd);
4332 install_element(PCEP_PCC_NODE, &vtysh_end_all_cmd);
4333 install_element(PCEP_PCE_NODE, &vtysh_end_all_cmd);
4334 install_element(PCEP_PCE_CONFIG_NODE, &vtysh_end_all_cmd);
4335
4336 install_element(SR_TRAFFIC_ENG_NODE, &pcep_cmd);
4337 install_element(PCEP_NODE, &pcep_cli_pcc_cmd);
4338 install_element(PCEP_NODE, &pcep_cli_pcep_pce_config_cmd);
4339 install_element(PCEP_NODE, &pcep_cli_pce_cmd);
4340#endif /* HAVE_PATHD_PCEP */
4341
4d7b695d
SM
4342#endif /* HAVE_PATHD */
4343
5d574646
IR
4344 /* keychain */
4345 install_node(&keychain_node);
4346 install_element(CONFIG_NODE, &key_chain_cmd);
4347 install_element(KEYCHAIN_NODE, &key_chain_cmd);
4348 install_element(KEYCHAIN_NODE, &vtysh_exit_keys_cmd);
4349 install_element(KEYCHAIN_NODE, &vtysh_quit_keys_cmd);
d62a17ae 4350 install_element(KEYCHAIN_NODE, &vtysh_end_all_cmd);
5d574646
IR
4351
4352 install_node(&keychain_key_node);
4353 install_element(KEYCHAIN_NODE, &key_cmd);
4354 install_element(KEYCHAIN_KEY_NODE, &key_chain_cmd);
4355 install_element(KEYCHAIN_KEY_NODE, &vtysh_exit_keys_cmd);
4356 install_element(KEYCHAIN_KEY_NODE, &vtysh_quit_keys_cmd);
d62a17ae 4357 install_element(KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd);
d62a17ae 4358
5d574646
IR
4359 /* nexthop-group */
4360 install_node(&nh_group_node);
4361 install_element(CONFIG_NODE, &vtysh_nexthop_group_cmd);
4362 install_element(CONFIG_NODE, &vtysh_no_nexthop_group_cmd);
4363 install_element(NH_GROUP_NODE, &vtysh_end_all_cmd);
4364 install_element(NH_GROUP_NODE, &vtysh_exit_nexthop_group_cmd);
4365 install_element(NH_GROUP_NODE, &vtysh_quit_nexthop_group_cmd);
4366
4367 /* zebra and all */
4368 install_node(&zebra_node);
4369
4370 install_node(&interface_node);
4371 install_element(CONFIG_NODE, &vtysh_interface_cmd);
d62a17ae 4372 install_element(INTERFACE_NODE, &vtysh_end_all_cmd);
4373 install_element(INTERFACE_NODE, &vtysh_exit_interface_cmd);
5d574646
IR
4374 install_element(INTERFACE_NODE, &vtysh_quit_interface_cmd);
4375
4376 install_node(&link_params_node);
4377 install_element(INTERFACE_NODE, &vtysh_link_params_cmd);
d62a17ae 4378 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
4379 install_element(LINK_PARAMS_NODE, &vtysh_end_all_cmd);
4380 install_element(LINK_PARAMS_NODE, &vtysh_exit_interface_cmd);
d62a17ae 4381
5d574646
IR
4382 install_node(&pw_node);
4383 install_element(CONFIG_NODE, &vtysh_pseudowire_cmd);
2dd0d726
RW
4384 install_element(PW_NODE, &vtysh_end_all_cmd);
4385 install_element(PW_NODE, &vtysh_exit_interface_cmd);
4386 install_element(PW_NODE, &vtysh_quit_interface_cmd);
4387
5d574646
IR
4388 install_node(&vrf_node);
4389 install_element(CONFIG_NODE, &vtysh_vrf_cmd);
4390 install_element(VRF_NODE, &vtysh_vrf_netns_cmd);
4391 install_element(VRF_NODE, &vtysh_no_vrf_netns_cmd);
4392 install_element(VRF_NODE, &exit_vrf_config_cmd);
d62a17ae 4393 install_element(VRF_NODE, &vtysh_end_all_cmd);
4394 install_element(VRF_NODE, &vtysh_exit_vrf_cmd);
4395 install_element(VRF_NODE, &vtysh_quit_vrf_cmd);
85dcff6e 4396
5d574646
IR
4397 install_node(&rmap_node);
4398 install_element(CONFIG_NODE, &vtysh_route_map_cmd);
4399 install_element(RMAP_NODE, &vtysh_exit_rmap_cmd);
4400 install_element(RMAP_NODE, &vtysh_quit_rmap_cmd);
4401 install_element(RMAP_NODE, &vtysh_end_all_cmd);
d62a17ae 4402
5d574646
IR
4403 install_node(&vty_node);
4404 install_element(CONFIG_NODE, &vtysh_line_vty_cmd);
4405 install_element(VTY_NODE, &vtysh_exit_line_vty_cmd);
4406 install_element(VTY_NODE, &vtysh_quit_line_vty_cmd);
4407 install_element(VTY_NODE, &vtysh_end_all_cmd);
d62a17ae 4408
ed18356f 4409
5d574646
IR
4410 struct cmd_node *node;
4411 for (unsigned int i = 0; i < vector_active(cmdvec); i++) {
4412 node = vector_slot(cmdvec, i);
4413 if (!node || node->node == VIEW_NODE)
4414 continue;
4415 vtysh_install_default(node->node);
4416 }
dabecd7c 4417
5d574646 4418 /* vtysh */
d62a17ae 4419
5d574646
IR
4420 install_element(VIEW_NODE, &vtysh_enable_cmd);
4421 install_element(ENABLE_NODE, &vtysh_config_terminal_cmd);
4422 install_element(ENABLE_NODE, &vtysh_disable_cmd);
4423
4424 /* "exit" command. */
4425 install_element(VIEW_NODE, &vtysh_exit_all_cmd);
4426 install_element(CONFIG_NODE, &vtysh_exit_all_cmd);
4427 install_element(VIEW_NODE, &vtysh_quit_all_cmd);
4428 install_element(CONFIG_NODE, &vtysh_quit_all_cmd);
4429
4430 /* "end" command. */
4431 install_element(CONFIG_NODE, &vtysh_end_all_cmd);
4432 install_element(ENABLE_NODE, &vtysh_end_all_cmd);
d62a17ae 4433
d62a17ae 4434 install_element(ENABLE_NODE, &vtysh_show_running_config_cmd);
4435 install_element(ENABLE_NODE, &vtysh_copy_running_config_cmd);
874f579d 4436 install_element(ENABLE_NODE, &vtysh_copy_to_running_cmd);
d62a17ae 4437
d62a17ae 4438 /* "write terminal" command. */
4439 install_element(ENABLE_NODE, &vtysh_write_terminal_cmd);
4440
4441 install_element(CONFIG_NODE, &vtysh_integrated_config_cmd);
4442 install_element(CONFIG_NODE, &no_vtysh_integrated_config_cmd);
4443
4444 /* "write memory" command. */
4445 install_element(ENABLE_NODE, &vtysh_write_memory_cmd);
4446
1569f224 4447 install_element(CONFIG_NODE, &vtysh_terminal_paginate_cmd);
76fd5262 4448 install_element(VIEW_NODE, &vtysh_terminal_paginate_cmd);
d62a17ae 4449 install_element(VIEW_NODE, &vtysh_terminal_length_cmd);
4450 install_element(VIEW_NODE, &vtysh_terminal_no_length_cmd);
4451 install_element(VIEW_NODE, &vtysh_show_daemons_cmd);
4452
4453 install_element(VIEW_NODE, &vtysh_ping_cmd);
4454 install_element(VIEW_NODE, &vtysh_ping_ip_cmd);
4455 install_element(VIEW_NODE, &vtysh_traceroute_cmd);
4456 install_element(VIEW_NODE, &vtysh_traceroute_ip_cmd);
4d9ad5dc 4457 install_element(VIEW_NODE, &vtysh_mtrace_cmd);
d62a17ae 4458 install_element(VIEW_NODE, &vtysh_ping6_cmd);
4459 install_element(VIEW_NODE, &vtysh_traceroute6_cmd);
576b6b5d 4460#if defined(HAVE_SHELL_ACCESS)
d62a17ae 4461 install_element(VIEW_NODE, &vtysh_telnet_cmd);
4462 install_element(VIEW_NODE, &vtysh_telnet_port_cmd);
4463 install_element(VIEW_NODE, &vtysh_ssh_cmd);
4eeccf18 4464#endif
576b6b5d 4465#if defined(HAVE_SHELL_ACCESS)
d62a17ae 4466 install_element(ENABLE_NODE, &vtysh_start_shell_cmd);
4467 install_element(ENABLE_NODE, &vtysh_start_bash_cmd);
4468 install_element(ENABLE_NODE, &vtysh_start_zsh_cmd);
576b6b5d
DS
4469#endif
4470
aea03ad6 4471 /* debugging */
7b526b61 4472 install_element(VIEW_NODE, &vtysh_show_error_code_cmd);
dd73744d
IR
4473 install_element(ENABLE_NODE, &vtysh_show_debugging_cmd);
4474 install_element(ENABLE_NODE, &vtysh_show_debugging_hashtable_cmd);
eb68fbc6 4475 install_element(ENABLE_NODE, &vtysh_debug_all_cmd);
aea03ad6 4476 install_element(CONFIG_NODE, &vtysh_debug_all_cmd);
85a6806d
MS
4477 install_element(ENABLE_NODE, &vtysh_debug_memstats_cmd);
4478 install_element(CONFIG_NODE, &vtysh_debug_memstats_cmd);
aea03ad6 4479
4ad77140 4480 /* northbound */
bcbe60d4 4481 install_element(ENABLE_NODE, &show_config_running_cmd);
88c71200 4482 install_element(ENABLE_NODE, &show_yang_operational_data_cmd);
3bb513c3
CH
4483 install_element(ENABLE_NODE, &show_yang_module_cmd);
4484 install_element(ENABLE_NODE, &show_yang_module_detail_cmd);
4ad77140
RW
4485 install_element(ENABLE_NODE, &debug_nb_cmd);
4486 install_element(CONFIG_NODE, &debug_nb_cmd);
4487
aea03ad6 4488 /* misc lib show commands */
a65f4b5d 4489 install_element(VIEW_NODE, &vtysh_show_history_cmd);
d62a17ae 4490 install_element(VIEW_NODE, &vtysh_show_memory_cmd);
4491 install_element(VIEW_NODE, &vtysh_show_modules_cmd);
d62a17ae 4492 install_element(VIEW_NODE, &vtysh_show_work_queues_cmd);
4493 install_element(VIEW_NODE, &vtysh_show_work_queues_daemon_cmd);
f75e802d 4494#ifndef EXCLUDE_CPU_TIME
d62a17ae 4495 install_element(VIEW_NODE, &vtysh_show_thread_cmd);
f75e802d 4496#endif
8872626b 4497 install_element(VIEW_NODE, &vtysh_show_poll_cmd);
d62a17ae 4498
4499 /* Logging */
4500 install_element(VIEW_NODE, &vtysh_show_logging_cmd);
d62a17ae 4501
4502 install_element(CONFIG_NODE, &vtysh_service_password_encrypt_cmd);
4503 install_element(CONFIG_NODE, &no_vtysh_service_password_encrypt_cmd);
4504
4505 install_element(CONFIG_NODE, &vtysh_password_cmd);
322e2d5c 4506 install_element(CONFIG_NODE, &no_vtysh_password_cmd);
d62a17ae 4507 install_element(CONFIG_NODE, &vtysh_enable_password_cmd);
4508 install_element(CONFIG_NODE, &no_vtysh_enable_password_cmd);
718e3744 4509}