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