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