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