]> git.proxmox.com Git - mirror_frr.git/blame - vtysh/vtysh.c
Merge pull request #12837 from donaldsharp/unlikely_routemap
[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};
0eb5751d 1178#endif /* HAVE_ISISD */
c25e458a 1179
0eb5751d 1180#ifdef HAVE_FABRICD
770ccdf8 1181static struct cmd_node openfabric_node = {
f4b8291f 1182 .name = "openfabric",
62b346ee 1183 .node = OPENFABRIC_NODE,
24389580 1184 .parent_node = CONFIG_NODE,
62b346ee 1185 .prompt = "%s(config-router)# ",
770ccdf8 1186};
0eb5751d 1187#endif /* HAVE_FABRICD */
770ccdf8 1188
d62a17ae 1189static struct cmd_node interface_node = {
f4b8291f 1190 .name = "interface",
62b346ee 1191 .node = INTERFACE_NODE,
24389580 1192 .parent_node = CONFIG_NODE,
62b346ee 1193 .prompt = "%s(config-if)# ",
718e3744 1194};
1195
2dd0d726 1196static struct cmd_node pw_node = {
f4b8291f 1197 .name = "pw",
62b346ee 1198 .node = PW_NODE,
24389580 1199 .parent_node = CONFIG_NODE,
62b346ee 1200 .prompt = "%s(config-pw)# ",
2dd0d726
RW
1201};
1202
4d7b695d
SM
1203static struct cmd_node segment_routing_node = {
1204 .name = "segment-routing",
1205 .node = SEGMENT_ROUTING_NODE,
1206 .parent_node = CONFIG_NODE,
1207 .prompt = "%s(config-sr)# ",
1208};
1209
5df73b05 1210#if defined(HAVE_PATHD)
4d7b695d
SM
1211static struct cmd_node sr_traffic_eng_node = {
1212 .name = "sr traffic-eng",
1213 .node = SR_TRAFFIC_ENG_NODE,
1214 .parent_node = SEGMENT_ROUTING_NODE,
1215 .prompt = "%s(config-sr-te)# ",
1216};
1217
1218static struct cmd_node srte_segment_list_node = {
1219 .name = "srte segment-list",
1220 .node = SR_SEGMENT_LIST_NODE,
1221 .parent_node = SR_TRAFFIC_ENG_NODE,
1222 .prompt = "%s(config-sr-te-segment-list)# ",
1223};
1224
1225static struct cmd_node srte_policy_node = {
1226 .name = "srte policy",
1227 .node = SR_POLICY_NODE,
1228 .parent_node = SR_TRAFFIC_ENG_NODE,
1229 .prompt = "%s(config-sr-te-policy)# ",
1230};
1231
1232static struct cmd_node srte_candidate_dyn_node = {
1233 .name = "srte candidate-dyn",
1234 .node = SR_CANDIDATE_DYN_NODE,
1235 .parent_node = SR_POLICY_NODE,
1236 .prompt = "%s(config-sr-te-candidate)# ",
1237};
1238
efba0985
SM
1239static struct cmd_node pcep_node = {
1240 .name = "srte pcep",
1241 .node = PCEP_NODE,
1242 .parent_node = SR_TRAFFIC_ENG_NODE,
1243 .prompt = "%s(config-sr-te-pcep)# "
1244};
1245
1246static struct cmd_node pcep_pcc_node = {
1247 .name = "srte pcep pcc",
1248 .node = PCEP_PCC_NODE,
1249 .parent_node = PCEP_NODE,
1250 .prompt = "%s(config-sr-te-pcep-pcc)# ",
1251};
1252
1253static struct cmd_node pcep_pce_node = {
1254 .name = "srte pcep pce-peer",
1255 .node = PCEP_PCE_NODE,
1256 .parent_node = PCEP_NODE,
1257 .prompt = "%s(config-sr-te-pcep-pce-peer)# ",
1258};
1259
1260static struct cmd_node pcep_pce_config_node = {
1261 .name = "srte pcep pce-config",
1262 .node = PCEP_PCE_CONFIG_NODE,
1263 .parent_node = PCEP_NODE,
1264 .prompt = "%s(pcep-sr-te-pcep-pce-config)# ",
1265};
f7f6a796 1266#endif /* HAVE_PATHD */
efba0985 1267
d62a17ae 1268static struct cmd_node vrf_node = {
f4b8291f 1269 .name = "vrf",
62b346ee 1270 .node = VRF_NODE,
24389580 1271 .parent_node = CONFIG_NODE,
62b346ee 1272 .prompt = "%s(config-vrf)# ",
e9d94ea7
DS
1273};
1274
e5c83d9b 1275static struct cmd_node nh_group_node = {
f4b8291f 1276 .name = "nexthop-group",
62b346ee 1277 .node = NH_GROUP_NODE,
24389580 1278 .parent_node = CONFIG_NODE,
62b346ee 1279 .prompt = "%s(config-nh-group)# ",
e5c83d9b
DS
1280};
1281
62b346ee 1282static struct cmd_node rmap_node = {
f4b8291f 1283 .name = "routemap",
62b346ee 1284 .node = RMAP_NODE,
24389580 1285 .parent_node = CONFIG_NODE,
62b346ee
DL
1286 .prompt = "%s(config-route-map)# ",
1287};
95e735b5 1288
6c0a7c09
HS
1289static struct cmd_node srv6_node = {
1290 .name = "srv6",
1291 .node = SRV6_NODE,
1292 .parent_node = SEGMENT_ROUTING_NODE,
1293 .prompt = "%s(config-srv6)# ",
1294};
1295
1296static struct cmd_node srv6_locs_node = {
1297 .name = "srv6-locators",
1298 .node = SRV6_LOCS_NODE,
1299 .parent_node = SRV6_NODE,
1300 .prompt = "%s(config-srv6-locators)# ",
1301};
1302
1303static struct cmd_node srv6_loc_node = {
1304 .name = "srv6-locator",
1305 .node = SRV6_LOC_NODE,
1306 .parent_node = SRV6_LOCS_NODE,
1307 .prompt = "%s(config-srv6-locator)# ",
1308};
1309
0eb5751d 1310#ifdef HAVE_PBRD
62b346ee 1311static struct cmd_node pbr_map_node = {
f4b8291f 1312 .name = "pbr-map",
62b346ee 1313 .node = PBRMAP_NODE,
24389580 1314 .parent_node = CONFIG_NODE,
62b346ee
DL
1315 .prompt = "%s(config-pbr-map)# ",
1316};
0eb5751d 1317#endif /* HAVE_PBRD */
e5c83d9b 1318
62b346ee 1319static struct cmd_node zebra_node = {
f4b8291f 1320 .name = "zebra",
62b346ee 1321 .node = ZEBRA_NODE,
24389580 1322 .parent_node = CONFIG_NODE,
62b346ee
DL
1323 .prompt = "%s(config-router)# ",
1324};
95e735b5 1325
0eb5751d 1326#ifdef HAVE_BGPD
62b346ee 1327static struct cmd_node bgp_vpnv4_node = {
f4b8291f 1328 .name = "bgp vpnv4",
62b346ee 1329 .node = BGP_VPNV4_NODE,
24389580 1330 .parent_node = BGP_NODE,
62b346ee 1331 .prompt = "%s(config-router-af)# ",
dd2c81b8 1332 .no_xpath = true,
62b346ee 1333};
95e735b5 1334
62b346ee 1335static struct cmd_node bgp_vpnv6_node = {
f4b8291f 1336 .name = "bgp vpnv6",
62b346ee 1337 .node = BGP_VPNV6_NODE,
24389580 1338 .parent_node = BGP_NODE,
62b346ee 1339 .prompt = "%s(config-router-af)# ",
dd2c81b8 1340 .no_xpath = true,
62b346ee 1341};
8ecd3266 1342
62b346ee 1343static struct cmd_node bgp_flowspecv4_node = {
f4b8291f 1344 .name = "bgp ipv4 flowspec",
62b346ee 1345 .node = BGP_FLOWSPECV4_NODE,
24389580 1346 .parent_node = BGP_NODE,
62b346ee 1347 .prompt = "%s(config-router-af)# ",
dd2c81b8 1348 .no_xpath = true,
62b346ee 1349};
e7d78d0f 1350
62b346ee 1351static struct cmd_node bgp_flowspecv6_node = {
f4b8291f 1352 .name = "bgp ipv6 flowspec",
62b346ee 1353 .node = BGP_FLOWSPECV6_NODE,
24389580 1354 .parent_node = BGP_NODE,
62b346ee 1355 .prompt = "%s(config-router-af)# ",
dd2c81b8 1356 .no_xpath = true,
62b346ee 1357};
e7d78d0f 1358
62b346ee 1359static struct cmd_node bgp_ipv4_node = {
f4b8291f 1360 .name = "bgp ipv4 unicast",
62b346ee 1361 .node = BGP_IPV4_NODE,
24389580 1362 .parent_node = BGP_NODE,
62b346ee 1363 .prompt = "%s(config-router-af)# ",
dd2c81b8 1364 .no_xpath = true,
62b346ee 1365};
95e735b5 1366
62b346ee 1367static struct cmd_node bgp_ipv4m_node = {
f4b8291f 1368 .name = "bgp ipv4 multicast",
62b346ee 1369 .node = BGP_IPV4M_NODE,
24389580 1370 .parent_node = BGP_NODE,
62b346ee 1371 .prompt = "%s(config-router-af)# ",
dd2c81b8 1372 .no_xpath = true,
62b346ee 1373};
95e735b5 1374
62b346ee 1375static struct cmd_node bgp_ipv4l_node = {
f4b8291f 1376 .name = "bgp ipv4 labeled unicast",
62b346ee 1377 .node = BGP_IPV4L_NODE,
24389580 1378 .parent_node = BGP_NODE,
62b346ee 1379 .prompt = "%s(config-router-af)# ",
dd2c81b8 1380 .no_xpath = true,
62b346ee 1381};
f51bae9c 1382
62b346ee 1383static struct cmd_node bgp_ipv6_node = {
f4b8291f 1384 .name = "bgp ipv6",
62b346ee 1385 .node = BGP_IPV6_NODE,
24389580 1386 .parent_node = BGP_NODE,
62b346ee 1387 .prompt = "%s(config-router-af)# ",
dd2c81b8 1388 .no_xpath = true,
62b346ee 1389};
95e735b5 1390
62b346ee 1391static struct cmd_node bgp_ipv6m_node = {
f4b8291f 1392 .name = "bgp ipv6 multicast",
62b346ee 1393 .node = BGP_IPV6M_NODE,
24389580 1394 .parent_node = BGP_NODE,
62b346ee 1395 .prompt = "%s(config-router-af)# ",
dd2c81b8 1396 .no_xpath = true,
62b346ee 1397};
57b5b7ed 1398
62b346ee 1399static struct cmd_node bgp_evpn_node = {
f4b8291f 1400 .name = "bgp evpn",
62b346ee 1401 .node = BGP_EVPN_NODE,
24389580 1402 .parent_node = BGP_NODE,
62b346ee 1403 .prompt = "%s(config-router-af)# ",
dd2c81b8 1404 .no_xpath = true,
62b346ee 1405};
14a227b8 1406
62b346ee 1407static struct cmd_node bgp_evpn_vni_node = {
f4b8291f 1408 .name = "bgp evpn vni",
62b346ee 1409 .node = BGP_EVPN_VNI_NODE,
24389580 1410 .parent_node = BGP_EVPN_NODE,
62b346ee
DL
1411 .prompt = "%s(config-router-af-vni)# ",
1412};
90e60aa7 1413
62b346ee 1414static struct cmd_node bgp_ipv6l_node = {
f4b8291f 1415 .name = "bgp ipv6 labeled unicast",
62b346ee 1416 .node = BGP_IPV6L_NODE,
24389580 1417 .parent_node = BGP_NODE,
62b346ee 1418 .prompt = "%s(config-router-af)# ",
dd2c81b8 1419 .no_xpath = true,
62b346ee 1420};
f51bae9c 1421
0eb5751d 1422#ifdef ENABLE_BGP_VNC
d62a17ae 1423static struct cmd_node bgp_vnc_defaults_node = {
f4b8291f 1424 .name = "bgp vnc defaults",
62b346ee 1425 .node = BGP_VNC_DEFAULTS_NODE,
24389580 1426 .parent_node = BGP_NODE,
62b346ee
DL
1427 .prompt = "%s(config-router-vnc-defaults)# ",
1428};
65efcfce 1429
d62a17ae 1430static struct cmd_node bgp_vnc_nve_group_node = {
f4b8291f 1431 .name = "bgp vnc nve",
62b346ee 1432 .node = BGP_VNC_NVE_GROUP_NODE,
24389580 1433 .parent_node = BGP_NODE,
62b346ee
DL
1434 .prompt = "%s(config-router-vnc-nve-group)# ",
1435};
65efcfce 1436
62b346ee 1437static struct cmd_node bgp_vrf_policy_node = {
f4b8291f 1438 .name = "bgp vrf policy",
62b346ee 1439 .node = BGP_VRF_POLICY_NODE,
24389580 1440 .parent_node = BGP_NODE,
62b346ee
DL
1441 .prompt = "%s(config-router-vrf-policy)# ",
1442};
5ff06872 1443
d62a17ae 1444static struct cmd_node bgp_vnc_l2_group_node = {
f4b8291f 1445 .name = "bgp vnc l2",
62b346ee 1446 .node = BGP_VNC_L2_GROUP_NODE,
24389580 1447 .parent_node = BGP_NODE,
62b346ee
DL
1448 .prompt = "%s(config-router-vnc-l2-group)# ",
1449};
0eb5751d 1450#endif /* ENABLE_BGP_VNC */
65efcfce 1451
62b346ee 1452static struct cmd_node bmp_node = {
f4b8291f 1453 .name = "bmp",
62b346ee 1454 .node = BMP_NODE,
24389580 1455 .parent_node = BGP_NODE,
62b346ee
DL
1456 .prompt = "%s(config-bgp-bmp)# "
1457};
bfaab44d
HS
1458
1459static struct cmd_node bgp_srv6_node = {
1460 .name = "bgp srv6",
1461 .node = BGP_SRV6_NODE,
1462 .parent_node = BGP_NODE,
1463 .prompt = "%s(config-router-srv6)# ",
1464};
0eb5751d 1465#endif /* HAVE_BGPD */
ed18356f 1466
0eb5751d 1467#ifdef HAVE_OSPFD
62b346ee 1468static struct cmd_node ospf_node = {
f4b8291f 1469 .name = "ospf",
62b346ee 1470 .node = OSPF_NODE,
24389580 1471 .parent_node = CONFIG_NODE,
62b346ee
DL
1472 .prompt = "%s(config-router)# ",
1473};
0eb5751d 1474#endif /* HAVE_OSPFD */
d62a17ae 1475
0eb5751d 1476#ifdef HAVE_EIGRPD
62b346ee 1477static struct cmd_node eigrp_node = {
f4b8291f 1478 .name = "eigrp",
62b346ee 1479 .node = EIGRP_NODE,
24389580 1480 .parent_node = CONFIG_NODE,
62b346ee
DL
1481 .prompt = "%s(config-router)# ",
1482};
0eb5751d 1483#endif /* HAVE_EIGRPD */
d62a17ae 1484
0eb5751d 1485#ifdef HAVE_BABELD
62b346ee 1486static struct cmd_node babel_node = {
f4b8291f 1487 .name = "babel",
62b346ee 1488 .node = BABEL_NODE,
24389580 1489 .parent_node = CONFIG_NODE,
62b346ee
DL
1490 .prompt = "%s(config-router)# ",
1491};
0eb5751d 1492#endif /* HAVE_BABELD */
d62a17ae 1493
62b346ee 1494static struct cmd_node ripng_node = {
f4b8291f 1495 .name = "ripng",
62b346ee 1496 .node = RIPNG_NODE,
24389580 1497 .parent_node = CONFIG_NODE,
62b346ee
DL
1498 .prompt = "%s(config-router)# ",
1499};
d62a17ae 1500
0eb5751d 1501#ifdef HAVE_OSPF6D
62b346ee 1502static struct cmd_node ospf6_node = {
f4b8291f 1503 .name = "ospf6",
62b346ee 1504 .node = OSPF6_NODE,
24389580 1505 .parent_node = CONFIG_NODE,
62b346ee
DL
1506 .prompt = "%s(config-ospf6)# ",
1507};
0eb5751d 1508#endif /* HAVE_OSPF6D */
d62a17ae 1509
0eb5751d 1510#ifdef HAVE_LDPD
62b346ee 1511static struct cmd_node ldp_node = {
f4b8291f 1512 .name = "ldp",
62b346ee 1513 .node = LDP_NODE,
24389580 1514 .parent_node = CONFIG_NODE,
62b346ee
DL
1515 .prompt = "%s(config-ldp)# ",
1516};
d62a17ae 1517
62b346ee 1518static struct cmd_node ldp_ipv4_node = {
f4b8291f 1519 .name = "ldp ipv4",
62b346ee 1520 .node = LDP_IPV4_NODE,
24389580 1521 .parent_node = LDP_NODE,
62b346ee
DL
1522 .prompt = "%s(config-ldp-af)# ",
1523};
d62a17ae 1524
62b346ee 1525static struct cmd_node ldp_ipv6_node = {
f4b8291f 1526 .name = "ldp ipv6",
62b346ee 1527 .node = LDP_IPV6_NODE,
24389580 1528 .parent_node = LDP_NODE,
62b346ee
DL
1529 .prompt = "%s(config-ldp-af)# ",
1530};
d62a17ae 1531
62b346ee 1532static struct cmd_node ldp_ipv4_iface_node = {
f4b8291f 1533 .name = "ldp ipv4 interface",
62b346ee 1534 .node = LDP_IPV4_IFACE_NODE,
24389580 1535 .parent_node = LDP_IPV4_NODE,
62b346ee
DL
1536 .prompt = "%s(config-ldp-af-if)# ",
1537};
d62a17ae 1538
62b346ee 1539static struct cmd_node ldp_ipv6_iface_node = {
f4b8291f 1540 .name = "ldp ipv6 interface",
62b346ee 1541 .node = LDP_IPV6_IFACE_NODE,
24389580 1542 .parent_node = LDP_IPV6_NODE,
62b346ee
DL
1543 .prompt = "%s(config-ldp-af-if)# ",
1544};
d62a17ae 1545
62b346ee 1546static struct cmd_node ldp_l2vpn_node = {
f4b8291f 1547 .name = "ldp l2vpn",
62b346ee 1548 .node = LDP_L2VPN_NODE,
24389580 1549 .parent_node = CONFIG_NODE,
62b346ee
DL
1550 .prompt = "%s(config-l2vpn)# ",
1551};
d62a17ae 1552
62b346ee 1553static struct cmd_node ldp_pseudowire_node = {
f4b8291f 1554 .name = "ldp",
62b346ee 1555 .node = LDP_PSEUDOWIRE_NODE,
24389580 1556 .parent_node = LDP_L2VPN_NODE,
62b346ee
DL
1557 .prompt = "%s(config-l2vpn-pw)# ",
1558};
0eb5751d 1559#endif /* HAVE_LDPD */
d62a17ae 1560
62b346ee 1561static struct cmd_node keychain_node = {
f4b8291f 1562 .name = "keychain",
62b346ee 1563 .node = KEYCHAIN_NODE,
24389580 1564 .parent_node = CONFIG_NODE,
62b346ee
DL
1565 .prompt = "%s(config-keychain)# ",
1566};
d62a17ae 1567
62b346ee 1568static struct cmd_node keychain_key_node = {
f4b8291f 1569 .name = "keychain key",
62b346ee 1570 .node = KEYCHAIN_KEY_NODE,
24389580 1571 .parent_node = KEYCHAIN_NODE,
62b346ee
DL
1572 .prompt = "%s(config-keychain-key)# ",
1573};
d62a17ae 1574
1575struct cmd_node link_params_node = {
f4b8291f 1576 .name = "link-params",
62b346ee 1577 .node = LINK_PARAMS_NODE,
24389580 1578 .parent_node = INTERFACE_NODE,
62b346ee 1579 .prompt = "%s(config-link-params)# ",
dd2c81b8 1580 .no_xpath = true,
95e735b5 1581};
1582
0eb5751d 1583#ifdef HAVE_BGPD
62b346ee 1584static struct cmd_node rpki_node = {
f4b8291f 1585 .name = "rpki",
62b346ee 1586 .node = RPKI_NODE,
24389580 1587 .parent_node = CONFIG_NODE,
62b346ee 1588 .prompt = "%s(config-rpki)# ",
62b346ee 1589};
0eb5751d 1590#endif /* HAVE_BGPD */
dabecd7c 1591
c2f29cf3
RZ
1592#if HAVE_BFDD > 0
1593static struct cmd_node bfd_node = {
f4b8291f 1594 .name = "bfd",
62b346ee 1595 .node = BFD_NODE,
24389580 1596 .parent_node = CONFIG_NODE,
62b346ee 1597 .prompt = "%s(config-bfd)# ",
c2f29cf3
RZ
1598};
1599
1600static struct cmd_node bfd_peer_node = {
f4b8291f 1601 .name = "bfd peer",
62b346ee 1602 .node = BFD_PEER_NODE,
24389580 1603 .parent_node = BFD_NODE,
62b346ee 1604 .prompt = "%s(config-bfd-peer)# ",
c2f29cf3 1605};
d40d6c22
RZ
1606
1607static struct cmd_node bfd_profile_node = {
1608 .name = "bfd profile",
1609 .node = BFD_PROFILE_NODE,
1610 .parent_node = BFD_NODE,
1611 .prompt = "%s(config-bfd-profile)# ",
1612};
c2f29cf3
RZ
1613#endif /* HAVE_BFDD */
1614
d62a17ae 1615/* Defined in lib/vty.c */
1616extern struct cmd_node vty_node;
1617
1618/* When '^Z' is received from vty, move down to the enable mode. */
1619static int vtysh_end(void)
1620{
1621 switch (vty->node) {
1622 case VIEW_NODE:
1623 case ENABLE_NODE:
1624 /* Nothing to do. */
1625 break;
1626 default:
1627 vty->node = ENABLE_NODE;
1628 break;
1629 }
1630 return CMD_SUCCESS;
1631}
1632
bec667a6
DL
1633#include "vtysh/vtysh_clippy.c"
1634
d62a17ae 1635DEFUNSH(VTYSH_REALLYALL, vtysh_end_all, vtysh_end_all_cmd, "end",
1636 "End current mode and change to enable mode\n")
7f57883e 1637{
d62a17ae 1638 return vtysh_end();
1639}
7f57883e 1640
ee785340 1641DEFUNSH(VTYSH_ZEBRA, srv6, srv6_cmd,
6c0a7c09 1642 "srv6",
11743d10 1643 "Segment-Routing SRv6 configuration\n")
6c0a7c09
HS
1644{
1645 vty->node = SRV6_NODE;
1646 return CMD_SUCCESS;
1647}
1648
ee785340 1649DEFUNSH(VTYSH_ZEBRA, srv6_locators, srv6_locators_cmd,
6c0a7c09 1650 "locators",
11743d10 1651 "Segment-Routing SRv6 locators configuration\n")
6c0a7c09
HS
1652{
1653 vty->node = SRV6_LOCS_NODE;
1654 return CMD_SUCCESS;
1655}
1656
ee785340 1657DEFUNSH(VTYSH_ZEBRA, srv6_locator, srv6_locator_cmd,
6c0a7c09
HS
1658 "locator WORD",
1659 "Segment Routing SRv6 locator\n"
1660 "Specify locator-name\n")
1661{
1662 vty->node = SRV6_LOC_NODE;
1663 return CMD_SUCCESS;
1664}
1665
0eb5751d 1666#ifdef HAVE_BGPD
d62a17ae 1667DEFUNSH(VTYSH_BGPD, router_bgp, router_bgp_cmd,
e55b0883 1668 "router bgp [ASNUM [<view|vrf> VIEWVRFNAME] [as-notation <dot|dot+|plain>]]",
d62a17ae 1669 ROUTER_STR BGP_STR AS_STR
1670 "BGP view\nBGP VRF\n"
e55b0883
PG
1671 "View/VRF name\n"
1672 "Force the AS notation output\n"
1673 "use 'AA.BB' format for AS 4 byte values\n"
1674 "use 'AA.BB' format for all AS values\n"
1675 "use plain format for all AS values\n")
a616ea5f 1676{
d62a17ae 1677 vty->node = BGP_NODE;
1678 return CMD_SUCCESS;
1679}
a616ea5f 1680
64e4a6c5 1681#ifdef KEEP_OLD_VPN_COMMANDS
d62a17ae 1682DEFUNSH(VTYSH_BGPD, address_family_vpnv4, address_family_vpnv4_cmd,
1683 "address-family vpnv4 [unicast]",
1684 "Enter Address Family command mode\n"
00e6edb9
DA
1685 BGP_AF_STR
1686 BGP_AF_MODIFIER_STR)
95e735b5 1687{
d62a17ae 1688 vty->node = BGP_VPNV4_NODE;
1689 return CMD_SUCCESS;
1690}
95e735b5 1691
d62a17ae 1692DEFUNSH(VTYSH_BGPD, address_family_vpnv6, address_family_vpnv6_cmd,
1693 "address-family vpnv6 [unicast]",
1694 "Enter Address Family command mode\n"
00e6edb9
DA
1695 BGP_AF_STR
1696 BGP_AF_MODIFIER_STR)
95e735b5 1697{
d62a17ae 1698 vty->node = BGP_VPNV6_NODE;
1699 return CMD_SUCCESS;
1700}
64e4a6c5 1701#endif /* KEEP_OLD_VPN_COMMANDS */
95e735b5 1702
d62a17ae 1703DEFUNSH(VTYSH_BGPD, address_family_ipv4, address_family_ipv4_cmd,
1704 "address-family ipv4 [unicast]",
1705 "Enter Address Family command mode\n"
00e6edb9
DA
1706 BGP_AF_STR
1707 BGP_AF_MODIFIER_STR)
4fcbf6e2 1708{
d62a17ae 1709 vty->node = BGP_IPV4_NODE;
1710 return CMD_SUCCESS;
1711}
4fcbf6e2 1712
e7d78d0f
PG
1713DEFUNSH(VTYSH_BGPD, address_family_flowspecv4, address_family_flowspecv4_cmd,
1714 "address-family ipv4 flowspec",
1715 "Enter Address Family command mode\n"
00e6edb9
DA
1716 BGP_AF_STR
1717 BGP_AF_MODIFIER_STR)
e7d78d0f
PG
1718{
1719 vty->node = BGP_FLOWSPECV4_NODE;
1720 return CMD_SUCCESS;
1721}
1722
1723DEFUNSH(VTYSH_BGPD, address_family_flowspecv6, address_family_flowspecv6_cmd,
1724 "address-family ipv6 flowspec",
1725 "Enter Address Family command mode\n"
00e6edb9
DA
1726 BGP_AF_STR
1727 BGP_AF_MODIFIER_STR)
e7d78d0f
PG
1728{
1729 vty->node = BGP_FLOWSPECV6_NODE;
1730 return CMD_SUCCESS;
1731}
1732
d62a17ae 1733DEFUNSH(VTYSH_BGPD, address_family_ipv4_multicast,
1734 address_family_ipv4_multicast_cmd, "address-family ipv4 multicast",
1735 "Enter Address Family command mode\n"
00e6edb9
DA
1736 BGP_AF_STR
1737 BGP_AF_MODIFIER_STR)
4fcbf6e2 1738{
d62a17ae 1739 vty->node = BGP_IPV4M_NODE;
1740 return CMD_SUCCESS;
1741}
4fcbf6e2 1742
d62a17ae 1743DEFUNSH(VTYSH_BGPD, address_family_ipv4_vpn, address_family_ipv4_vpn_cmd,
1744 "address-family ipv4 vpn",
1745 "Enter Address Family command mode\n"
00e6edb9
DA
1746 BGP_AF_STR
1747 BGP_AF_MODIFIER_STR)
4fcbf6e2 1748{
d62a17ae 1749 vty->node = BGP_VPNV4_NODE;
1750 return CMD_SUCCESS;
1751}
4fcbf6e2 1752
d62a17ae 1753DEFUNSH(VTYSH_BGPD, address_family_ipv4_labeled_unicast,
1754 address_family_ipv4_labeled_unicast_cmd,
1755 "address-family ipv4 labeled-unicast",
1756 "Enter Address Family command mode\n"
00e6edb9
DA
1757 BGP_AF_STR
1758 BGP_AF_MODIFIER_STR)
4fcbf6e2 1759{
d62a17ae 1760 vty->node = BGP_IPV4L_NODE;
1761 return CMD_SUCCESS;
1762}
4fcbf6e2 1763
d62a17ae 1764DEFUNSH(VTYSH_BGPD, address_family_ipv6, address_family_ipv6_cmd,
1765 "address-family ipv6 [unicast]",
1766 "Enter Address Family command mode\n"
00e6edb9
DA
1767 BGP_AF_STR
1768 BGP_AF_MODIFIER_STR)
4fcbf6e2 1769{
d62a17ae 1770 vty->node = BGP_IPV6_NODE;
1771 return CMD_SUCCESS;
1772}
4fcbf6e2 1773
d62a17ae 1774DEFUNSH(VTYSH_BGPD, address_family_ipv6_multicast,
1775 address_family_ipv6_multicast_cmd, "address-family ipv6 multicast",
1776 "Enter Address Family command mode\n"
00e6edb9
DA
1777 BGP_AF_STR
1778 BGP_AF_MODIFIER_STR)
4fcbf6e2 1779{
d62a17ae 1780 vty->node = BGP_IPV6M_NODE;
1781 return CMD_SUCCESS;
1782}
4fcbf6e2 1783
d62a17ae 1784DEFUNSH(VTYSH_BGPD, address_family_ipv6_vpn, address_family_ipv6_vpn_cmd,
1785 "address-family ipv6 vpn",
1786 "Enter Address Family command mode\n"
00e6edb9
DA
1787 BGP_AF_STR
1788 BGP_AF_MODIFIER_STR)
4fcbf6e2 1789{
d62a17ae 1790 vty->node = BGP_VPNV6_NODE;
1791 return CMD_SUCCESS;
1792}
4fcbf6e2 1793
d62a17ae 1794DEFUNSH(VTYSH_BGPD, address_family_ipv6_labeled_unicast,
1795 address_family_ipv6_labeled_unicast_cmd,
1796 "address-family ipv6 labeled-unicast",
1797 "Enter Address Family command mode\n"
00e6edb9
DA
1798 BGP_AF_STR
1799 BGP_AF_MODIFIER_STR)
95e735b5 1800{
d62a17ae 1801 vty->node = BGP_IPV6L_NODE;
1802 return CMD_SUCCESS;
1803}
95e735b5 1804
b86543b8
LB
1805DEFUNSH(VTYSH_BGPD,
1806 rpki,
1807 rpki_cmd,
1808 "rpki",
dabecd7c
MR
1809 "Enable rpki and enter rpki configuration mode\n")
1810{
1811 vty->node = RPKI_NODE;
1812 return CMD_SUCCESS;
1813}
1814
ed18356f
DL
1815DEFUNSH(VTYSH_BGPD,
1816 bmp_targets,
1817 bmp_targets_cmd,
1818 "bmp targets BMPTARGETS",
1819 "BGP Monitoring Protocol\n"
1820 "Create BMP target group\n"
1821 "Name of the BMP target group\n")
1822{
1823 vty->node = BMP_NODE;
1824 return CMD_SUCCESS;
1825}
1826
bfaab44d
HS
1827DEFUNSH(VTYSH_BGPD,
1828 bgp_srv6,
1829 bgp_srv6_cmd,
1830 "segment-routing srv6",
1831 "Segment-Routing configuration\n"
1832 "Segment-Routing SRv6 configuration\n")
1833{
1834 vty->node = BGP_SRV6_NODE;
1835 return CMD_SUCCESS;
1836}
1837
1838DEFUNSH(VTYSH_BGPD,
1839 exit_bgp_srv6,
1840 exit_bgp_srv6_cmd,
1841 "exit",
1842 "exit Segment-Routing SRv6 configuration\n")
1843{
1844 if (vty->node == BGP_SRV6_NODE)
1845 vty->node = BGP_NODE;
1846 return CMD_SUCCESS;
1847}
1848
1849DEFUNSH(VTYSH_BGPD,
1850 quit_bgp_srv6,
1851 quit_bgp_srv6_cmd,
1852 "quit",
1853 "quit Segment-Routing SRv6 configuration\n")
1854{
1855 if (vty->node == BGP_SRV6_NODE)
1856 vty->node = BGP_NODE;
1857 return CMD_SUCCESS;
1858}
1859
d62a17ae 1860DEFUNSH(VTYSH_BGPD, address_family_evpn, address_family_evpn_cmd,
1861 "address-family <l2vpn evpn>",
1862 "Enter Address Family command mode\n"
00e6edb9
DA
1863 BGP_AF_STR
1864 BGP_AF_MODIFIER_STR)
95e735b5 1865{
d62a17ae 1866 vty->node = BGP_EVPN_NODE;
1867 return CMD_SUCCESS;
1868}
95e735b5 1869
093e3f23 1870DEFUNSH(VTYSH_BGPD, bgp_evpn_vni, bgp_evpn_vni_cmd, "vni " CMD_VNI_RANGE,
d62a17ae 1871 "VXLAN Network Identifier\n"
1872 "VNI number\n")
1873{
1874 vty->node = BGP_EVPN_VNI_NODE;
1875 return CMD_SUCCESS;
1876}
e7168df4 1877
d62a17ae 1878#if defined(ENABLE_BGP_VNC)
1879DEFUNSH(VTYSH_BGPD, vnc_defaults, vnc_defaults_cmd, "vnc defaults",
1880 "VNC/RFP related configuration\n"
1881 "Configure default NVE group\n")
718e3744 1882{
d62a17ae 1883 vty->node = BGP_VNC_DEFAULTS_NODE;
1884 return CMD_SUCCESS;
1885}
1886
1887DEFUNSH(VTYSH_BGPD, vnc_nve_group, vnc_nve_group_cmd, "vnc nve-group NAME",
1888 "VNC/RFP related configuration\n"
1889 "Configure a NVE group\n"
1890 "Group name\n")
718e3744 1891{
d62a17ae 1892 vty->node = BGP_VNC_NVE_GROUP_NODE;
1893 return CMD_SUCCESS;
1894}
1895
1896DEFUNSH(VTYSH_BGPD, vnc_vrf_policy, vnc_vrf_policy_cmd, "vrf-policy NAME",
1897 "Configure a VRF policy group\n"
1898 "Group name\n")
8ecd3266 1899{
d62a17ae 1900 vty->node = BGP_VRF_POLICY_NODE;
1901 return CMD_SUCCESS;
1902}
1903
1904DEFUNSH(VTYSH_BGPD, vnc_l2_group, vnc_l2_group_cmd, "vnc l2-group NAME",
1905 "VNC/RFP related configuration\n"
1906 "Configure a L2 group\n"
1907 "Group name\n")
718e3744 1908{
d62a17ae 1909 vty->node = BGP_VNC_L2_GROUP_NODE;
1910 return CMD_SUCCESS;
718e3744 1911}
662a1b05
WC
1912
1913DEFUNSH(VTYSH_BGPD, exit_vnc_config, exit_vnc_config_cmd, "exit-vnc",
1914 "Exit from VNC configuration mode\n")
1915{
1916 if (vty->node == BGP_VNC_DEFAULTS_NODE
1917 || vty->node == BGP_VNC_NVE_GROUP_NODE
1918 || vty->node == BGP_VNC_L2_GROUP_NODE)
1919 vty->node = BGP_NODE;
1920 return CMD_SUCCESS;
1921}
1922
1923DEFUNSH(VTYSH_BGPD, exit_vrf_policy, exit_vrf_policy_cmd, "exit-vrf-policy",
1924 "Exit from VRF policy configuration mode\n")
1925{
1926 if (vty->node == BGP_VRF_POLICY_NODE)
1927 vty->node = BGP_NODE;
1928 return CMD_SUCCESS;
1929}
d62a17ae 1930#endif
0eb5751d 1931#endif /* HAVE_BGPD */
718e3744 1932
3a3a24c8 1933DEFUNSH(VTYSH_KEYS, key_chain, key_chain_cmd, "key chain WORD",
d62a17ae 1934 "Authentication key management\n"
1935 "Key-chain management\n"
1936 "Key-chain name\n")
718e3744 1937{
d62a17ae 1938 vty->node = KEYCHAIN_NODE;
1939 return CMD_SUCCESS;
39530dfe 1940}
c7f1274b 1941
3a3a24c8 1942DEFUNSH(VTYSH_KEYS, key, key_cmd, "key (0-2147483647)",
d62a17ae 1943 "Configure a key\n"
1944 "Key identifier number\n")
39530dfe 1945{
d62a17ae 1946 vty->node = KEYCHAIN_KEY_NODE;
1947 return CMD_SUCCESS;
39530dfe 1948}
f51bae9c 1949
0eb5751d 1950#ifdef HAVE_RIPD
ae7b826a
RW
1951DEFUNSH(VTYSH_RIPD, router_rip, router_rip_cmd, "router rip [vrf NAME]",
1952 ROUTER_STR "RIP\n" VRF_CMD_HELP_STR)
39530dfe 1953{
d62a17ae 1954 vty->node = RIP_NODE;
1955 return CMD_SUCCESS;
57b5b7ed 1956}
0eb5751d 1957#endif /* HAVE_RIPD */
718e3744 1958
0eb5751d 1959#ifdef HAVE_RIPNGD
dde7b15b
RW
1960DEFUNSH(VTYSH_RIPNGD, router_ripng, router_ripng_cmd, "router ripng [vrf NAME]",
1961 ROUTER_STR "RIPng\n" VRF_CMD_HELP_STR)
05ba625a 1962{
d62a17ae 1963 vty->node = RIPNG_NODE;
1964 return CMD_SUCCESS;
57b5b7ed 1965}
0eb5751d 1966#endif /* HAVE_RIPNGD */
57b5b7ed 1967
0eb5751d 1968#ifdef HAVE_OSPFD
b5a8894d
CS
1969DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd,
1970 "router ospf [(1-65535)] [vrf NAME]",
d62a17ae 1971 "Enable a routing process\n"
1972 "Start OSPF configuration\n"
b86543b8
LB
1973 "Instance ID\n"
1974 VRF_CMD_HELP_STR)
90e60aa7 1975{
d62a17ae 1976 vty->node = OSPF_NODE;
1977 return CMD_SUCCESS;
90e60aa7 1978}
0eb5751d 1979#endif /* HAVE_OSPFD */
90e60aa7 1980
0eb5751d 1981#ifdef HAVE_EIGRPD
e9449961 1982DEFUNSH(VTYSH_EIGRPD, router_eigrp, router_eigrp_cmd, "router eigrp (1-65535) [vrf NAME]",
d62a17ae 1983 "Enable a routing process\n"
1984 "Start EIGRP configuration\n"
e9449961
DS
1985 "AS number to use\n"
1986 VRF_CMD_HELP_STR)
14a227b8 1987{
d62a17ae 1988 vty->node = EIGRP_NODE;
1989 return CMD_SUCCESS;
14a227b8 1990}
0eb5751d 1991#endif /* HAVE_EIGRPD */
90e60aa7 1992
0eb5751d 1993#ifdef HAVE_BABELD
d62a17ae 1994DEFUNSH(VTYSH_BABELD, router_babel, router_babel_cmd, "router babel",
1995 "Enable a routing process\n"
1996 "Make Babel instance command\n")
90e60aa7 1997{
d62a17ae 1998 vty->node = BABEL_NODE;
1999 return CMD_SUCCESS;
90e60aa7 2000}
0eb5751d 2001#endif /* HAVE_BABELD */
14a227b8 2002
0eb5751d 2003#ifdef HAVE_OSPF6D
d48ef099 2004DEFUNSH(VTYSH_OSPF6D, router_ospf6, router_ospf6_cmd, "router ospf6 [vrf NAME]",
2005 ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR)
65efcfce 2006{
d62a17ae 2007 vty->node = OSPF6_NODE;
2008 return CMD_SUCCESS;
65efcfce 2009}
0eb5751d 2010#endif
65efcfce 2011
d62a17ae 2012#if defined(HAVE_LDPD)
2013DEFUNSH(VTYSH_LDPD, ldp_mpls_ldp, ldp_mpls_ldp_cmd, "mpls ldp",
2014 "Global MPLS configuration subcommands\n"
2015 "Label Distribution Protocol\n")
65efcfce 2016{
d62a17ae 2017 vty->node = LDP_NODE;
2018 return CMD_SUCCESS;
65efcfce
LB
2019}
2020
d62a17ae 2021DEFUNSH(VTYSH_LDPD, ldp_address_family_ipv4, ldp_address_family_ipv4_cmd,
2022 "address-family ipv4",
2023 "Configure Address Family and its parameters\n"
2024 "IPv4\n")
5ff06872 2025{
d62a17ae 2026 vty->node = LDP_IPV4_NODE;
2027 return CMD_SUCCESS;
5ff06872
LB
2028}
2029
d62a17ae 2030DEFUNSH(VTYSH_LDPD, ldp_address_family_ipv6, ldp_address_family_ipv6_cmd,
2031 "address-family ipv6",
2032 "Configure Address Family and its parameters\n"
2033 "IPv6\n")
65efcfce 2034{
d62a17ae 2035 vty->node = LDP_IPV6_NODE;
2036 return CMD_SUCCESS;
65efcfce
LB
2037}
2038
983bd6f7
RW
2039DEFUNSH(VTYSH_LDPD, ldp_exit_address_family, ldp_exit_address_family_cmd,
2040 "exit-address-family", "Exit from Address Family configuration mode\n")
2041{
2042 if (vty->node == LDP_IPV4_NODE || vty->node == LDP_IPV6_NODE)
2043 vty->node = LDP_NODE;
2044 return CMD_SUCCESS;
2045}
2046
d62a17ae 2047DEFUNSH(VTYSH_LDPD, ldp_interface_ifname, ldp_interface_ifname_cmd,
2048 "interface IFNAME",
2049 "Enable LDP on an interface and enter interface submode\n"
2050 "Interface's name\n")
718e3744 2051{
d62a17ae 2052 switch (vty->node) {
2053 case LDP_IPV4_NODE:
2054 vty->node = LDP_IPV4_IFACE_NODE;
2055 break;
2056 case LDP_IPV6_NODE:
2057 vty->node = LDP_IPV6_IFACE_NODE;
2058 break;
2059 default:
2060 break;
2061 }
2062
2063 return CMD_SUCCESS;
2064}
718e3744 2065
d62a17ae 2066DEFUNSH(VTYSH_LDPD, ldp_l2vpn_word_type_vpls, ldp_l2vpn_word_type_vpls_cmd,
2067 "l2vpn WORD type vpls",
2068 "Configure l2vpn commands\n"
2069 "L2VPN name\n"
2070 "L2VPN type\n"
2071 "Virtual Private LAN Service\n")
718e3744 2072{
d62a17ae 2073 vty->node = LDP_L2VPN_NODE;
2074 return CMD_SUCCESS;
718e3744 2075}
2076
d62a17ae 2077DEFUNSH(VTYSH_LDPD, ldp_member_pseudowire_ifname,
2078 ldp_member_pseudowire_ifname_cmd, "member pseudowire IFNAME",
2079 "L2VPN member configuration\n"
2080 "Pseudowire interface\n"
2081 "Interface's name\n")
718e3744 2082{
d62a17ae 2083 vty->node = LDP_PSEUDOWIRE_NODE;
2084 return CMD_SUCCESS;
718e3744 2085}
d62a17ae 2086#endif
718e3744 2087
0eb5751d 2088#ifdef HAVE_ISISD
65251ce8 2089DEFUNSH(VTYSH_ISISD, router_isis, router_isis_cmd,
2090 "router isis WORD [vrf NAME]",
d62a17ae 2091 ROUTER_STR
2092 "ISO IS-IS\n"
65251ce8 2093 "ISO Routing area tag\n" VRF_CMD_HELP_STR)
d62a17ae 2094{
2095 vty->node = ISIS_NODE;
2096 return CMD_SUCCESS;
2097}
0eb5751d 2098#endif /* HAVE_ISISD */
d62a17ae 2099
0eb5751d 2100#ifdef HAVE_FABRICD
770ccdf8
CF
2101DEFUNSH(VTYSH_FABRICD, router_openfabric, router_openfabric_cmd, "router openfabric WORD",
2102 ROUTER_STR
2103 "OpenFabric routing protocol\n"
2104 "ISO Routing area tag\n")
2105{
2106 vty->node = OPENFABRIC_NODE;
2107 return CMD_SUCCESS;
2108}
0eb5751d 2109#endif /* HAVE_FABRICD */
770ccdf8 2110
6c0a7c09 2111DEFUNSH(VTYSH_SR, segment_routing, segment_routing_cmd,
4d7b695d
SM
2112 "segment-routing",
2113 "Configure segment routing\n")
2114{
2115 vty->node = SEGMENT_ROUTING_NODE;
2116 return CMD_SUCCESS;
2117}
2118
5df73b05 2119#if defined (HAVE_PATHD)
4d7b695d
SM
2120DEFUNSH(VTYSH_PATHD, sr_traffic_eng, sr_traffic_eng_cmd,
2121 "traffic-eng",
2122 "Configure SR traffic engineering\n")
2123{
2124 vty->node = SR_TRAFFIC_ENG_NODE;
2125 return CMD_SUCCESS;
2126}
2127
2128DEFUNSH(VTYSH_PATHD, srte_segment_list, srte_segment_list_cmd,
2129 "segment-list WORD$name",
2130 "Segment List\n"
2131 "Segment List Name\n")
2132{
2133 vty->node = SR_SEGMENT_LIST_NODE;
2134 return CMD_SUCCESS;
2135}
2136
2137DEFUNSH(VTYSH_PATHD, srte_policy, srte_policy_cmd,
2138 "policy color (0-4294967295) endpoint <A.B.C.D|X:X::X:X>",
2139 "Segment Routing Policy\n"
2140 "SR Policy color\n"
2141 "SR Policy color value\n"
2142 "SR Policy endpoint\n"
2143 "SR Policy endpoint IPv4 address\n"
2144 "SR Policy endpoint IPv6 address\n")
2145{
2146 vty->node = SR_POLICY_NODE;
2147 return CMD_SUCCESS;
2148}
2149
2150DEFUNSH(VTYSH_PATHD, srte_policy_candidate_dyn_path,
2151 srte_policy_candidate_dyn_path_cmd,
2152 "candidate-path preference (0-4294967295) name WORD dynamic",
2153 "Segment Routing Policy Candidate Path\n"
2154 "Segment Routing Policy Candidate Path Preference\n"
2155 "Administrative Preference\n"
2156 "Segment Routing Policy Candidate Path Name\n"
2157 "Symbolic Name\n"
2158 "Dynamic Path\n")
2159{
2160 vty->node = SR_CANDIDATE_DYN_NODE;
2161 return CMD_SUCCESS;
2162}
efba0985 2163
efba0985
SM
2164DEFUNSH(VTYSH_PATHD, pcep, pcep_cmd,
2165 "pcep",
2166 "Configure SR pcep\n")
2167{
2168 vty->node = PCEP_NODE;
2169 return CMD_SUCCESS;
2170}
2171
2172DEFUNSH(VTYSH_PATHD, pcep_cli_pcc, pcep_cli_pcc_cmd,
53fc645d 2173 "pcc",
efba0985
SM
2174 "PCC configuration\n")
2175{
2176 vty->node = PCEP_PCC_NODE;
2177 return CMD_SUCCESS;
2178}
2179
2180DEFUNSH(VTYSH_PATHD, pcep_cli_pce, pcep_cli_pce_cmd,
53fc645d 2181 "pce WORD",
efba0985
SM
2182 "PCE configuration\n"
2183 "Peer name\n")
2184{
2185 vty->node = PCEP_PCE_NODE;
2186 return CMD_SUCCESS;
2187}
2188
2189DEFUNSH(VTYSH_PATHD, pcep_cli_pcep_pce_config, pcep_cli_pcep_pce_config_cmd,
53fc645d 2190 "pce-config WORD",
efba0985
SM
2191 "PCEP peer Configuration Group\n"
2192 "PCEP peer Configuration Group name\n")
2193{
2194 vty->node = PCEP_PCE_CONFIG_NODE;
2195 return CMD_SUCCESS;
2196}
2197
4d7b695d
SM
2198#endif /* HAVE_PATHD */
2199
05a12619
LS
2200/* max value is EXT_ADMIN_GROUP_MAX_POSITIONS - 1 */
2201DEFUNSH(VTYSH_AFFMAP, affinity_map, vtysh_affinity_map_cmd,
2202 "affinity-map NAME bit-position (0-1023)",
2203 "Affinity map configuration\n"
2204 "Affinity attribute name\n"
2205 "Bit position for affinity attribute value\n"
2206 "Bit position\n")
2207{
2208 return CMD_SUCCESS;
2209}
2210
2211/* max value is EXT_ADMIN_GROUP_MAX_POSITIONS - 1 */
2212DEFUNSH(VTYSH_AFFMAP, no_affinity_map, vtysh_no_affinity_map_cmd,
2213 "no affinity-map NAME$name [bit-position (0-1023)$position]",
2214 NO_STR
2215 "Affinity map configuration\n"
2216 "Affinity attribute name\n"
2217 "Bit position for affinity attribute value\n"
2218 "Bit position\n")
2219{
2220 return CMD_SUCCESS;
2221}
2222
d62a17ae 2223DEFUNSH(VTYSH_RMAP, vtysh_route_map, vtysh_route_map_cmd,
8f241168 2224 "route-map RMAP_NAME <deny|permit> (1-65535)",
d62a17ae 2225 "Create route-map or enter route-map command mode\n"
2226 "Route map tag\n"
2227 "Route map denies set operations\n"
2228 "Route map permits set operations\n"
2229 "Sequence to insert to/delete from existing route-map entry\n")
2230{
2231 vty->node = RMAP_NODE;
2232 return CMD_SUCCESS;
2233}
2234
0eb5751d 2235#ifdef HAVE_PBRD
e5c83d9b 2236DEFUNSH(VTYSH_PBRD, vtysh_pbr_map, vtysh_pbr_map_cmd,
17f8c652 2237 "pbr-map PBRMAP seq (1-700)",
e5c83d9b
DS
2238 "Create pbr-map or enter pbr-map command mode\n"
2239 "The name of the PBR MAP\n"
2240 "Sequence to insert to/delete from existing pbr-map entry\n"
2241 "Sequence number\n")
2242{
2243 vty->node = PBRMAP_NODE;
2244 return CMD_SUCCESS;
2245}
2246
5d574646
IR
2247DEFSH(VTYSH_PBRD, vtysh_no_pbr_map_cmd, "no pbr-map PBRMAP [seq (1-700)]",
2248 NO_STR
2249 "Delete pbr-map\n"
2250 "The name of the PBR MAP\n"
2251 "Sequence to delete from existing pbr-map entry\n"
2252 "Sequence number\n")
0eb5751d 2253#endif /* HAVE_PBRD */
5d574646 2254
c2f29cf3
RZ
2255#if HAVE_BFDD > 0
2256DEFUNSH(VTYSH_BFDD, bfd_enter, bfd_enter_cmd, "bfd", "Configure BFD peers\n")
2257{
2258 vty->node = BFD_NODE;
2259 return CMD_SUCCESS;
2260}
2261
2262DEFUNSH(VTYSH_BFDD, bfd_peer_enter, bfd_peer_enter_cmd,
2263 "peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
2264 "Configure peer\n"
2265 "IPv4 peer address\n"
2266 "IPv6 peer address\n"
2267 "Configure multihop\n"
2268 "Configure local address\n"
2269 "IPv4 local address\n"
2270 "IPv6 local address\n"
2271 INTERFACE_STR
2272 "Configure interface name to use\n"
2273 "Configure VRF\n"
2274 "Configure VRF name\n")
2275{
2276 vty->node = BFD_PEER_NODE;
2277 return CMD_SUCCESS;
2278}
d40d6c22
RZ
2279
2280DEFUNSH(VTYSH_BFDD, bfd_profile_enter, bfd_profile_enter_cmd,
0a01b0f4 2281 "profile BFDPROF",
d40d6c22
RZ
2282 BFD_PROFILE_STR
2283 BFD_PROFILE_NAME_STR)
2284{
2285 vty->node = BFD_PROFILE_NODE;
2286 return CMD_SUCCESS;
2287}
c2f29cf3
RZ
2288#endif /* HAVE_BFDD */
2289
d62a17ae 2290DEFUNSH(VTYSH_ALL, vtysh_line_vty, vtysh_line_vty_cmd, "line vty",
2291 "Configure a terminal line\n"
2292 "Virtual terminal\n")
2293{
2294 vty->node = VTY_NODE;
2295 return CMD_SUCCESS;
2296}
2297
2298DEFUNSH(VTYSH_REALLYALL, vtysh_enable, vtysh_enable_cmd, "enable",
2299 "Turn on privileged mode command\n")
2300{
2301 vty->node = ENABLE_NODE;
2302 return CMD_SUCCESS;
2303}
2304
2305DEFUNSH(VTYSH_REALLYALL, vtysh_disable, vtysh_disable_cmd, "disable",
2306 "Turn off privileged mode command\n")
2307{
2308 if (vty->node == ENABLE_NODE)
2309 vty->node = VIEW_NODE;
2310 return CMD_SUCCESS;
2311}
2312
2313DEFUNSH(VTYSH_REALLYALL, vtysh_config_terminal, vtysh_config_terminal_cmd,
dc1c13c0 2314 "configure [terminal]",
d62a17ae 2315 "Configuration from vty interface\n"
2316 "Configuration terminal\n")
2317{
2318 vty->node = CONFIG_NODE;
2319 return CMD_SUCCESS;
2320}
2321
2322static int vtysh_exit(struct vty *vty)
2323{
d42eb101
DL
2324 struct cmd_node *cnode = vector_lookup(cmdvec, vty->node);
2325
2326 if (vty->node == VIEW_NODE || vty->node == ENABLE_NODE)
d62a17ae 2327 exit(0);
d42eb101
DL
2328 if (cnode->node_exit)
2329 cnode->node_exit(vty);
2330 if (cnode->parent_node)
2331 vty->node = cnode->parent_node;
2332
2333 if (vty->node == CONFIG_NODE) {
2334 /* resync in case one of the daemons is somewhere else */
d62a17ae 2335 vtysh_execute("end");
dc1c13c0 2336 vtysh_execute("configure");
d62a17ae 2337 }
2338 return CMD_SUCCESS;
2339}
2340
2341DEFUNSH(VTYSH_REALLYALL, vtysh_exit_all, vtysh_exit_all_cmd, "exit",
2342 "Exit current mode and down to previous mode\n")
4fcbf6e2 2343{
d62a17ae 2344 return vtysh_exit(vty);
4fcbf6e2
RW
2345}
2346
5772415b 2347DEFUNSH(VTYSH_REALLYALL, vtysh_quit_all, vtysh_quit_all_cmd, "quit",
d62a17ae 2348 "Exit current mode and down to previous mode\n")
4fcbf6e2 2349{
d62a17ae 2350 return vtysh_exit_all(self, vty, argc, argv);
2351}
4fcbf6e2 2352
0eb5751d 2353#ifdef HAVE_BGPD
d62a17ae 2354DEFUNSH(VTYSH_BGPD, exit_address_family, exit_address_family_cmd,
2355 "exit-address-family", "Exit from Address Family configuration mode\n")
4fcbf6e2 2356{
d62a17ae 2357 if (vty->node == BGP_IPV4_NODE || vty->node == BGP_IPV4M_NODE
2358 || vty->node == BGP_IPV4L_NODE || vty->node == BGP_VPNV4_NODE
2359 || vty->node == BGP_VPNV6_NODE || vty->node == BGP_IPV6_NODE
2360 || vty->node == BGP_IPV6L_NODE || vty->node == BGP_IPV6M_NODE
e7d78d0f
PG
2361 || vty->node == BGP_EVPN_NODE
2362 || vty->node == BGP_FLOWSPECV4_NODE
2363 || vty->node == BGP_FLOWSPECV6_NODE)
d62a17ae 2364 vty->node = BGP_NODE;
2365 return CMD_SUCCESS;
2366}
4fcbf6e2 2367
d62a17ae 2368DEFUNSH(VTYSH_BGPD, exit_vni, exit_vni_cmd, "exit-vni", "Exit from VNI mode\n")
4fcbf6e2 2369{
d62a17ae 2370 if (vty->node == BGP_EVPN_VNI_NODE)
2371 vty->node = BGP_EVPN_NODE;
2372 return CMD_SUCCESS;
2373}
2374
61a484a9
QY
2375DEFUNSH(VTYSH_BGPD, rpki_exit, rpki_exit_cmd, "exit",
2376 "Exit current mode and down to previous mode\n")
2377{
2378 vtysh_exit(vty);
2379 return CMD_SUCCESS;
2380}
2381
2382DEFUNSH(VTYSH_BGPD, rpki_quit, rpki_quit_cmd, "quit",
2383 "Exit current mode and down to previous mode\n")
2384{
2385 return rpki_exit(self, vty, argc, argv);
4fcbf6e2
RW
2386}
2387
ed18356f
DL
2388DEFUNSH(VTYSH_BGPD, bmp_exit, bmp_exit_cmd, "exit",
2389 "Exit current mode and down to previous mode\n")
2390{
2391 vtysh_exit(vty);
2392 return CMD_SUCCESS;
2393}
2394
2395DEFUNSH(VTYSH_BGPD, bmp_quit, bmp_quit_cmd, "quit",
2396 "Exit current mode and down to previous mode\n")
2397{
2398 return bmp_exit(self, vty, argc, argv);
2399}
0eb5751d 2400#endif /* HAVE_BGPD */
5ff06872 2401
5d574646
IR
2402DEFUNSH(VTYSH_VRF, exit_vrf_config, exit_vrf_config_cmd, "exit-vrf",
2403 "Exit from VRF configuration mode\n")
2404{
2405 if (vty->node == VRF_NODE)
2406 vty->node = CONFIG_NODE;
2407 return CMD_SUCCESS;
2408}
2409
ee785340 2410DEFUNSH(VTYSH_ZEBRA, exit_srv6_config, exit_srv6_config_cmd, "exit",
6c0a7c09
HS
2411 "Exit from SRv6 configuration mode\n")
2412{
2413 if (vty->node == SRV6_NODE)
2414 vty->node = SEGMENT_ROUTING_NODE;
2415 return CMD_SUCCESS;
2416}
2417
ee785340 2418DEFUNSH(VTYSH_ZEBRA, exit_srv6_locs_config, exit_srv6_locs_config_cmd, "exit",
6c0a7c09
HS
2419 "Exit from SRv6-locator configuration mode\n")
2420{
2421 if (vty->node == SRV6_LOCS_NODE)
2422 vty->node = SRV6_NODE;
2423 return CMD_SUCCESS;
2424}
2425
ee785340 2426DEFUNSH(VTYSH_ZEBRA, exit_srv6_loc_config, exit_srv6_loc_config_cmd, "exit",
6c0a7c09
HS
2427 "Exit from SRv6-locators configuration mode\n")
2428{
2429 if (vty->node == SRV6_LOC_NODE)
2430 vty->node = SRV6_LOCS_NODE;
2431 return CMD_SUCCESS;
2432}
2433
0eb5751d 2434#ifdef HAVE_RIPD
d62a17ae 2435DEFUNSH(VTYSH_RIPD, vtysh_exit_ripd, vtysh_exit_ripd_cmd, "exit",
2436 "Exit current mode and down to previous mode\n")
718e3744 2437{
d62a17ae 2438 return vtysh_exit(vty);
718e3744 2439}
2440
d62a17ae 2441DEFUNSH(VTYSH_RIPD, vtysh_quit_ripd, vtysh_quit_ripd_cmd, "quit",
2442 "Exit current mode and down to previous mode\n")
a98d33ab 2443{
d62a17ae 2444 return vtysh_exit_ripd(self, vty, argc, argv);
a98d33ab 2445}
0eb5751d 2446#endif /* HAVE_RIPD */
718e3744 2447
0eb5751d 2448#ifdef HAVE_RIPNGD
d62a17ae 2449DEFUNSH(VTYSH_RIPNGD, vtysh_exit_ripngd, vtysh_exit_ripngd_cmd, "exit",
2450 "Exit current mode and down to previous mode\n")
68980084 2451{
d62a17ae 2452 return vtysh_exit(vty);
68980084 2453}
2454
d62a17ae 2455DEFUNSH(VTYSH_RIPNGD, vtysh_quit_ripngd, vtysh_quit_ripngd_cmd, "quit",
2456 "Exit current mode and down to previous mode\n")
a98d33ab 2457{
d62a17ae 2458 return vtysh_exit_ripngd(self, vty, argc, argv);
a98d33ab 2459}
0eb5751d 2460#endif /* HAVE_RIPNGD */
68980084 2461
d62a17ae 2462DEFUNSH(VTYSH_RMAP, vtysh_exit_rmap, vtysh_exit_rmap_cmd, "exit",
2463 "Exit current mode and down to previous mode\n")
718e3744 2464{
d62a17ae 2465 return vtysh_exit(vty);
718e3744 2466}
2467
d62a17ae 2468DEFUNSH(VTYSH_RMAP, vtysh_quit_rmap, vtysh_quit_rmap_cmd, "quit",
2469 "Exit current mode and down to previous mode\n")
a98d33ab 2470{
d62a17ae 2471 return vtysh_exit_rmap(self, vty, argc, argv);
a98d33ab 2472}
718e3744 2473
0eb5751d 2474#ifdef HAVE_PBRD
e5c83d9b
DS
2475DEFUNSH(VTYSH_PBRD, vtysh_exit_pbr_map, vtysh_exit_pbr_map_cmd, "exit",
2476 "Exit current mode and down to previous mode\n")
2477{
2478 return vtysh_exit(vty);
2479}
2480
2481DEFUNSH(VTYSH_PBRD, vtysh_quit_pbr_map, vtysh_quit_pbr_map_cmd, "quit",
2482 "Exit current mode and down to previous mode\n")
2483{
2484 return vtysh_exit_rmap(self, vty, argc, argv);
2485}
0eb5751d 2486#endif /* HAVE_PBRD */
e5c83d9b 2487
0eb5751d 2488#ifdef HAVE_BGPD
d62a17ae 2489DEFUNSH(VTYSH_BGPD, vtysh_exit_bgpd, vtysh_exit_bgpd_cmd, "exit",
2490 "Exit current mode and down to previous mode\n")
718e3744 2491{
d62a17ae 2492 return vtysh_exit(vty);
718e3744 2493}
2494
d62a17ae 2495DEFUNSH(VTYSH_BGPD, vtysh_quit_bgpd, vtysh_quit_bgpd_cmd, "quit",
2496 "Exit current mode and down to previous mode\n")
a98d33ab 2497{
d62a17ae 2498 return vtysh_exit_bgpd(self, vty, argc, argv);
a98d33ab 2499}
0eb5751d 2500#endif /* HAVE_BGPD */
718e3744 2501
0eb5751d 2502#ifdef HAVE_OSPFD
d62a17ae 2503DEFUNSH(VTYSH_OSPFD, vtysh_exit_ospfd, vtysh_exit_ospfd_cmd, "exit",
2504 "Exit current mode and down to previous mode\n")
718e3744 2505{
d62a17ae 2506 return vtysh_exit(vty);
718e3744 2507}
2508
d62a17ae 2509DEFUNSH(VTYSH_OSPFD, vtysh_quit_ospfd, vtysh_quit_ospfd_cmd, "quit",
2510 "Exit current mode and down to previous mode\n")
a98d33ab 2511{
d62a17ae 2512 return vtysh_exit_ospfd(self, vty, argc, argv);
a98d33ab 2513}
0eb5751d 2514#endif /* HAVE_OSPFD */
718e3744 2515
0eb5751d 2516#ifdef HAVE_EIGRPD
d62a17ae 2517DEFUNSH(VTYSH_EIGRPD, vtysh_exit_eigrpd, vtysh_exit_eigrpd_cmd, "exit",
2518 "Exit current mode and down to previous mode\n")
7f57883e 2519{
d62a17ae 2520 return vtysh_exit(vty);
7f57883e
DS
2521}
2522
d62a17ae 2523DEFUNSH(VTYSH_EIGRPD, vtysh_quit_eigrpd, vtysh_quit_eigrpd_cmd, "quit",
2524 "Exit current mode and down to previous mode\n")
7f57883e 2525{
d62a17ae 2526 return vtysh_exit(vty);
7f57883e 2527}
0eb5751d 2528#endif /* HAVE_EIGRPD */
7f57883e 2529
0eb5751d 2530#ifdef HAVE_BABELD
460982cf 2531DEFUNSH(VTYSH_BABELD, vtysh_exit_babeld, vtysh_exit_babeld_cmd, "exit",
d62a17ae 2532 "Exit current mode and down to previous mode\n")
a616ea5f 2533{
d62a17ae 2534 return vtysh_exit(vty);
a616ea5f
DS
2535}
2536
d62a17ae 2537DEFUNSH(VTYSH_BABELD, vtysh_quit_babeld, vtysh_quit_babeld_cmd, "quit",
2538 "Exit current mode and down to previous mode\n")
a616ea5f 2539{
d62a17ae 2540 return vtysh_exit(vty);
a616ea5f 2541}
0eb5751d 2542#endif /* HAVE_BABELD */
a616ea5f 2543
0eb5751d 2544#ifdef HAVE_OSPF6D
d62a17ae 2545DEFUNSH(VTYSH_OSPF6D, vtysh_exit_ospf6d, vtysh_exit_ospf6d_cmd, "exit",
2546 "Exit current mode and down to previous mode\n")
68980084 2547{
d62a17ae 2548 return vtysh_exit(vty);
68980084 2549}
2550
d62a17ae 2551DEFUNSH(VTYSH_OSPF6D, vtysh_quit_ospf6d, vtysh_quit_ospf6d_cmd, "quit",
2552 "Exit current mode and down to previous mode\n")
a98d33ab 2553{
d62a17ae 2554 return vtysh_exit_ospf6d(self, vty, argc, argv);
a98d33ab 2555}
0eb5751d 2556#endif /* HAVE_OSPF6D */
68980084 2557
d62a17ae 2558#if defined(HAVE_LDPD)
2559DEFUNSH(VTYSH_LDPD, vtysh_exit_ldpd, vtysh_exit_ldpd_cmd, "exit",
2560 "Exit current mode and down to previous mode\n")
4fcbf6e2 2561{
d62a17ae 2562 return vtysh_exit(vty);
4fcbf6e2
RW
2563}
2564
d62a17ae 2565ALIAS(vtysh_exit_ldpd, vtysh_quit_ldpd_cmd, "quit",
2566 "Exit current mode and down to previous mode\n")
87ab4aec 2567#endif
4fcbf6e2 2568
0eb5751d 2569#ifdef HAVE_ISISD
d62a17ae 2570DEFUNSH(VTYSH_ISISD, vtysh_exit_isisd, vtysh_exit_isisd_cmd, "exit",
2571 "Exit current mode and down to previous mode\n")
c25e458a 2572{
d62a17ae 2573 return vtysh_exit(vty);
c25e458a 2574}
2575
d62a17ae 2576DEFUNSH(VTYSH_ISISD, vtysh_quit_isisd, vtysh_quit_isisd_cmd, "quit",
2577 "Exit current mode and down to previous mode\n")
a98d33ab 2578{
d62a17ae 2579 return vtysh_exit_isisd(self, vty, argc, argv);
a98d33ab 2580}
0eb5751d 2581#endif /* HAVE_ISISD */
c25e458a 2582
c2f29cf3
RZ
2583#if HAVE_BFDD > 0
2584DEFUNSH(VTYSH_BFDD, vtysh_exit_bfdd, vtysh_exit_bfdd_cmd, "exit",
2585 "Exit current mode and down to previous mode\n")
2586{
2587 return vtysh_exit(vty);
2588}
2589
2590ALIAS(vtysh_exit_bfdd, vtysh_quit_bfdd_cmd, "quit",
2591 "Exit current mode and down to previous mode\n")
2592#endif
2593
0eb5751d 2594#ifdef HAVE_FABRICD
770ccdf8
CF
2595DEFUNSH(VTYSH_FABRICD, vtysh_exit_fabricd, vtysh_exit_fabricd_cmd, "exit",
2596 "Exit current mode and down to previous mode\n")
2597{
2598 return vtysh_exit(vty);
2599}
2600
2601DEFUNSH(VTYSH_FABRICD, vtysh_quit_fabricd, vtysh_quit_fabricd_cmd, "quit",
2602 "Exit current mode and down to previous mode\n")
2603{
2604 return vtysh_exit_fabricd(self, vty, argc, argv);
2605}
0eb5751d 2606#endif /* HAVE_FABRICD */
770ccdf8 2607
949467e2
IR
2608DEFUNSH(VTYSH_KEYS, vtysh_exit_keys, vtysh_exit_keys_cmd, "exit",
2609 "Exit current mode and down to previous mode\n")
2610{
2611 return vtysh_exit(vty);
2612}
2613
2614DEFUNSH(VTYSH_KEYS, vtysh_quit_keys, vtysh_quit_keys_cmd, "quit",
2615 "Exit current mode and down to previous mode\n")
2616{
2617 return vtysh_exit_keys(self, vty, argc, argv);
2618}
2619
5df73b05
DS
2620DEFUNSH(VTYSH_SR, vtysh_exit_sr, vtysh_exit_sr_cmd, "exit",
2621 "Exit current mode and down to previous mode\n")
2622{
2623 return vtysh_exit(vty);
2624}
2625
2626DEFUNSH(VTYSH_SR, vtysh_quit_sr, vtysh_quit_sr_cmd, "quit",
2627 "Exit current mode and down to previous mode\n")
2628{
2629 return vtysh_exit(vty);
2630}
2631
f7f6a796 2632#if defined(HAVE_PATHD)
4d7b695d
SM
2633DEFUNSH(VTYSH_PATHD, vtysh_exit_pathd, vtysh_exit_pathd_cmd, "exit",
2634 "Exit current mode and down to previous mode\n")
2635{
2636 return vtysh_exit(vty);
2637}
2638
2639DEFUNSH(VTYSH_PATHD, vtysh_quit_pathd, vtysh_quit_pathd_cmd, "quit",
2640 "Exit current mode and down to previous mode\n")
2641{
2642 return vtysh_exit_pathd(self, vty, argc, argv);
2643}
f7f6a796 2644#endif /* HAVE_PATHD */
4d7b695d 2645
d62a17ae 2646DEFUNSH(VTYSH_ALL, vtysh_exit_line_vty, vtysh_exit_line_vty_cmd, "exit",
2647 "Exit current mode and down to previous mode\n")
e7168df4 2648{
d62a17ae 2649 return vtysh_exit(vty);
e7168df4 2650}
2651
d62a17ae 2652DEFUNSH(VTYSH_ALL, vtysh_quit_line_vty, vtysh_quit_line_vty_cmd, "quit",
2653 "Exit current mode and down to previous mode\n")
a98d33ab 2654{
d62a17ae 2655 return vtysh_exit_line_vty(self, vty, argc, argv);
a98d33ab 2656}
e7168df4 2657
d62a17ae 2658DEFUNSH(VTYSH_INTERFACE, vtysh_interface, vtysh_interface_cmd,
2659 "interface IFNAME [vrf NAME]",
2660 "Select an interface to configure\n"
2661 "Interface's name\n" VRF_CMD_HELP_STR)
718e3744 2662{
d62a17ae 2663 vty->node = INTERFACE_NODE;
2664 return CMD_SUCCESS;
718e3744 2665}
2666
2dd0d726
RW
2667DEFUNSH(VTYSH_ZEBRA, vtysh_pseudowire, vtysh_pseudowire_cmd,
2668 "pseudowire IFNAME",
2669 "Static pseudowire configuration\n"
2670 "Pseudowire name\n")
2671{
2672 vty->node = PW_NODE;
2673 return CMD_SUCCESS;
2674}
2675
7183a034
MS
2676DEFUNSH(VTYSH_NH_GROUP,
2677 vtysh_nexthop_group, vtysh_nexthop_group_cmd,
868ee86c 2678 "nexthop-group NHGNAME",
e5c83d9b
DS
2679 "Nexthop Group configuration\n"
2680 "Name of the Nexthop Group\n")
2681{
2682 vty->node = NH_GROUP_NODE;
2683 return CMD_SUCCESS;
2684}
2685
7183a034 2686DEFSH(VTYSH_NH_GROUP, vtysh_no_nexthop_group_cmd,
868ee86c 2687 "no nexthop-group NHGNAME",
e5c83d9b
DS
2688 NO_STR
2689 "Nexthop Group Configuration\n"
2690 "Name of the Nexthop Group\n")
2691
d62a17ae 2692DEFUNSH(VTYSH_VRF, vtysh_vrf, vtysh_vrf_cmd, "vrf NAME",
2693 "Select a VRF to configure\n"
2694 "VRF's name\n")
e9d94ea7 2695{
d62a17ae 2696 vty->node = VRF_NODE;
2697 return CMD_SUCCESS;
e9d94ea7
DS
2698}
2699
d62a17ae 2700DEFUNSH(VTYSH_VRF, vtysh_exit_vrf, vtysh_exit_vrf_cmd, "exit",
2701 "Exit current mode and down to previous mode\n")
e9d94ea7 2702{
d62a17ae 2703 return vtysh_exit(vty);
e9d94ea7
DS
2704}
2705
d62a17ae 2706DEFUNSH(VTYSH_VRF, vtysh_quit_vrf, vtysh_quit_vrf_cmd, "quit",
2707 "Exit current mode and down to previous mode\n")
a98d33ab 2708{
d62a17ae 2709 return vtysh_exit_vrf(self, vty, argc, argv);
a98d33ab 2710}
e9d94ea7 2711
7183a034
MS
2712DEFUNSH(VTYSH_NH_GROUP,
2713 vtysh_exit_nexthop_group, vtysh_exit_nexthop_group_cmd,
e5c83d9b
DS
2714 "exit", "Exit current mode and down to previous mode\n")
2715{
2716 return vtysh_exit(vty);
2717}
2718
7183a034
MS
2719DEFUNSH(VTYSH_NH_GROUP,
2720 vtysh_quit_nexthop_group, vtysh_quit_nexthop_group_cmd,
e5c83d9b
DS
2721 "quit", "Exit current mode and down to previous mode\n")
2722{
2723 return vtysh_exit_nexthop_group(self, vty, argc, argv);
2724}
2725
d62a17ae 2726DEFUNSH(VTYSH_INTERFACE, vtysh_exit_interface, vtysh_exit_interface_cmd, "exit",
2727 "Exit current mode and down to previous mode\n")
718e3744 2728{
d62a17ae 2729 return vtysh_exit(vty);
718e3744 2730}
2731
d62a17ae 2732DEFUNSH(VTYSH_INTERFACE, vtysh_quit_interface, vtysh_quit_interface_cmd, "quit",
2733 "Exit current mode and down to previous mode\n")
a98d33ab 2734{
d62a17ae 2735 return vtysh_exit_interface(self, vty, argc, argv);
a98d33ab 2736}
718e3744 2737
92de4c7f
IR
2738DEFUNSH(VTYSH_ZEBRA, vtysh_exit_pseudowire, vtysh_exit_pseudowire_cmd, "exit",
2739 "Exit current mode and down to previous mode\n")
2740{
2741 return vtysh_exit(vty);
2742}
2743
2744DEFUNSH(VTYSH_ZEBRA, vtysh_quit_pseudowire, vtysh_quit_pseudowire_cmd, "quit",
2745 "Exit current mode and down to previous mode\n")
2746{
2747 return vtysh_exit_pseudowire(self, vty, argc, argv);
2748}
2749
a5eb3b0d
IR
2750static char *do_prepend(struct vty *vty, struct cmd_token **argv, int argc)
2751{
2752 const char *argstr[argc + 1];
2753 int i, off = 0;
2754
2755 if (vty->node != VIEW_NODE) {
2756 off = 1;
2757 argstr[0] = "do";
2758 }
2759
2760 for (i = 0; i < argc; i++)
2761 argstr[i + off] = argv[i]->arg;
2762
2763 return frrstr_join(argstr, argc + off, " ");
2764}
2765
c84e5187
DL
2766#pragma GCC diagnostic push
2767#pragma GCC diagnostic ignored "-Wformat-nonliteral"
2768/* 'headline' is a format string with a %s for the daemon name
2769 *
2770 * Also for some reason GCC emits the warning on the end of the function
2771 * (optimization maybe?) rather than on the vty_out line, so this pragma
2772 * wraps the entire function rather than just the vty_out line.
2773 */
2774
a5eb3b0d
IR
2775static int show_per_daemon(struct vty *vty, struct cmd_token **argv, int argc,
2776 const char *headline)
8872626b
DS
2777{
2778 unsigned int i;
8872626b 2779 int ret = CMD_SUCCESS;
a5eb3b0d 2780 char *line = do_prepend(vty, argv, argc);
8872626b 2781
8872626b 2782 for (i = 0; i < array_size(vtysh_client); i++)
a4e2dac1 2783 if (vtysh_client[i].fd >= 0 || vtysh_client[i].next) {
a5eb3b0d 2784 vty_out(vty, headline, vtysh_client[i].name);
8872626b
DS
2785 ret = vtysh_client_execute(&vtysh_client[i], line);
2786 vty_out(vty, "\n");
2787 }
a5eb3b0d
IR
2788
2789 XFREE(MTYPE_TMP, line);
2790
2791 return ret;
2792}
c84e5187 2793#pragma GCC diagnostic pop
a5eb3b0d
IR
2794
2795static int show_one_daemon(struct vty *vty, struct cmd_token **argv, int argc,
2796 const char *name)
2797{
2798 int ret;
2799 char *line = do_prepend(vty, argv, argc);
2800
2801 ret = vtysh_client_execute_name(name, line);
2802
2803 XFREE(MTYPE_TMP, line);
2804
8872626b
DS
2805 return ret;
2806}
2807
22f31b8c
DS
2808DEFUN (vtysh_show_thread_timer,
2809 vtysh_show_thread_timer_cmd,
2810 "show thread timers",
2811 SHOW_STR
2812 "Thread information\n"
2813 "Show all timers and how long they have in the system\n")
2814{
2815 return show_per_daemon(vty, argv, argc, "Thread timers for %s:\n");
2816}
2817
a5eb3b0d
IR
2818DEFUN (vtysh_show_poll,
2819 vtysh_show_poll_cmd,
2820 "show thread poll",
2821 SHOW_STR
2822 "Thread information\n"
2823 "Thread Poll Information\n")
2824{
2825 return show_per_daemon(vty, argv, argc, "Thread statistics for %s:\n");
2826}
2827
0f69b58c
DS
2828DEFUN (vtysh_show_thread,
2829 vtysh_show_thread_cmd,
2830 "show thread cpu [FILTER]",
c25c6137
QY
2831 SHOW_STR
2832 "Thread information\n"
2833 "Thread CPU usage\n"
2834 "Display filter (rwtexb)\n")
0f69b58c 2835{
a5eb3b0d 2836 return show_per_daemon(vty, argv, argc, "Thread statistics for %s:\n");
0f69b58c
DS
2837}
2838
2839DEFUN (vtysh_show_work_queues,
2840 vtysh_show_work_queues_cmd,
2841 "show work-queues",
2842 SHOW_STR
2843 "Work Queue information\n")
2844{
a5eb3b0d
IR
2845 return show_per_daemon(vty, argv, argc,
2846 "Work queue statistics for %s:\n");
0f69b58c
DS
2847}
2848
b47b0a84
DS
2849DEFUN (vtysh_show_work_queues_daemon,
2850 vtysh_show_work_queues_daemon_cmd,
2e77de95 2851 "show work-queues " DAEMONS_LIST,
b47b0a84
DS
2852 SHOW_STR
2853 "Work Queue information\n"
2e77de95 2854 DAEMONS_STR)
b47b0a84 2855{
a5eb3b0d 2856 return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
b47b0a84
DS
2857}
2858
d62a17ae 2859DEFUNSH(VTYSH_ZEBRA, vtysh_link_params, vtysh_link_params_cmd, "link-params",
2860 LINK_PARAMS_STR)
16f1b9ee 2861{
d62a17ae 2862 vty->node = LINK_PARAMS_NODE;
2863 return CMD_SUCCESS;
16f1b9ee
OD
2864}
2865
d62a17ae 2866DEFUNSH(VTYSH_ZEBRA, exit_link_params, exit_link_params_cmd, "exit-link-params",
2867 "Exit from Link Params configuration node\n")
03f99d9a 2868{
d62a17ae 2869 if (vty->node == LINK_PARAMS_NODE)
2870 vty->node = INTERFACE_NODE;
2871 return CMD_SUCCESS;
03f99d9a
DS
2872}
2873
92de4c7f
IR
2874DEFUNSH(VTYSH_ZEBRA, vtysh_exit_link_params, vtysh_exit_link_params_cmd, "exit",
2875 "Exit current mode and down to previous mode\n")
2876{
2877 if (vty->node == LINK_PARAMS_NODE)
2878 vty->node = INTERFACE_NODE;
2879 return CMD_SUCCESS;
2880}
2881
2882DEFUNSH(VTYSH_ZEBRA, vtysh_quit_link_params, vtysh_quit_link_params_cmd, "quit",
2883 "Exit current mode and down to previous mode\n")
2884{
2885 return vtysh_exit_link_params(self, vty, argc, argv);
2886}
2887
aea03ad6
QY
2888DEFUNSH_HIDDEN (0x00,
2889 vtysh_debug_all,
2890 vtysh_debug_all_cmd,
2891 "[no] debug all",
2892 NO_STR
2893 DEBUG_STR
2894 "Toggle all debugs on or off\n")
2895{
2896 return CMD_SUCCESS;
2897}
2898
87f6dc50
DS
2899DEFUN (vtysh_show_debugging,
2900 vtysh_show_debugging_cmd,
2901 "show debugging",
2902 SHOW_STR
2903 DEBUG_STR)
2904{
a5eb3b0d 2905 return show_per_daemon(vty, argv, argc, "");
87f6dc50
DS
2906}
2907
40818cec
DL
2908DEFUN (vtysh_show_debugging_hashtable,
2909 vtysh_show_debugging_hashtable_cmd,
2910 "show debugging hashtable [statistics]",
2911 SHOW_STR
2912 DEBUG_STR
2913 "Statistics about hash tables\n"
2914 "Statistics about hash tables\n")
2915{
a5eb3b0d
IR
2916 bool stats = strmatch(argv[argc - 1]->text, "statistics");
2917
2cddf2ff
QY
2918 vty_out(vty, "\n");
2919 vty_out(vty,
44deef01 2920 "Load factor (LF) - average number of elements across all buckets\n");
2cddf2ff 2921 vty_out(vty,
44deef01 2922 "Full load factor (FLF) - average number of elements across full buckets\n\n");
2cddf2ff 2923 vty_out(vty,
44deef01 2924 "Standard deviation (SD) is calculated for both the LF and FLF\n");
2cddf2ff 2925 vty_out(vty,
44deef01 2926 "and indicates the typical deviation of bucket chain length\n");
2cddf2ff 2927 vty_out(vty, "from the value in the corresponding load factor.\n\n");
44deef01 2928
a5eb3b0d 2929 return show_per_daemon(vty, argv, stats ? argc - 1 : argc,
40818cec
DL
2930 "Hashtable statistics for %s:\n");
2931}
2932
7b526b61
QY
2933DEFUN (vtysh_show_error_code,
2934 vtysh_show_error_code_cmd,
ed8841d3 2935 "show error <(1-4294967296)|all> [json]",
7b526b61
QY
2936 SHOW_STR
2937 "Information on errors\n"
ed8841d3
QY
2938 "Error code to get info about\n"
2939 "Information on all errors\n"
2940 JSON_STR)
7b526b61 2941{
1f9128d6
QY
2942 uint32_t arg = 0;
2943
2944 if (!strmatch(argv[2]->text, "all"))
2945 arg = strtoul(argv[2]->arg, NULL, 10);
2946
2947 /* If it's not a shared code, send it to all the daemons */
2948 if (arg < LIB_FERR_START || arg > LIB_FERR_END) {
a5eb3b0d 2949 show_per_daemon(vty, argv, argc, "");
1f9128d6
QY
2950 /* Otherwise, print it ourselves to avoid duplication */
2951 } else {
2952 bool json = strmatch(argv[argc - 1]->text, "json");
2d6e4d2e 2953
1f9128d6
QY
2954 if (!strmatch(argv[2]->text, "all"))
2955 arg = strtoul(argv[2]->arg, NULL, 10);
2956
2957 log_ref_display(vty, arg, json);
2958 }
ed8841d3 2959
1f9128d6 2960 return CMD_SUCCESS;
7b526b61
QY
2961}
2962
4ad77140 2963/* Northbound. */
122ee38a 2964DEFUN_HIDDEN (show_config_running,
bcbe60d4
IR
2965 show_config_running_cmd,
2966 "show configuration running\
2967 [<json|xml> [translate WORD]]\
8ba718d7 2968 [with-defaults] " DAEMONS_LIST,
bcbe60d4
IR
2969 SHOW_STR
2970 "Configuration information\n"
2971 "Running configuration\n"
2972 "Change output format to JSON\n"
2973 "Change output format to XML\n"
2974 "Translate output\n"
2975 "YANG module translator\n"
2976 "Show default values\n"
2977 DAEMONS_STR)
2978{
2979 return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
2980}
2981
eba4e1ea
RW
2982DEFUN (show_yang_operational_data,
2983 show_yang_operational_data_cmd,
21f5aade 2984 "show yang operational-data XPATH\
eba4e1ea 2985 [{\
21f5aade
RW
2986 format <json|xml>\
2987 |translate WORD\
54aeec5e 2988 |with-config\
8ba718d7 2989 }] " DAEMONS_LIST,
eba4e1ea
RW
2990 SHOW_STR
2991 "YANG information\n"
2992 "Show YANG operational data\n"
2993 "XPath expression specifying the YANG data path\n"
2994 "Set the output format\n"
2995 "JavaScript Object Notation\n"
2996 "Extensible Markup Language\n"
2997 "Translate operational data\n"
2998 "YANG module translator\n"
54aeec5e 2999 "Merge configuration data\n"
eba4e1ea
RW
3000 DAEMONS_STR)
3001{
a5eb3b0d 3002 return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
eba4e1ea
RW
3003}
3004
3bb513c3
CH
3005DEFUN(show_yang_module, show_yang_module_cmd,
3006 "show yang module [module-translator WORD] " DAEMONS_LIST,
3007 SHOW_STR
3008 "YANG information\n"
3009 "Show loaded modules\n"
3010 "YANG module translator\n"
3011 "YANG module translator\n" DAEMONS_STR)
3012{
3013 return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
3014}
3015
3016DEFUN(show_yang_module_detail, show_yang_module_detail_cmd,
3017 "show yang module\
3018 [module-translator WORD]\
3019 WORD <compiled|summary|tree|yang|yin> " DAEMONS_LIST,
3020 SHOW_STR
3021 "YANG information\n"
3022 "Show loaded modules\n"
3023 "YANG module translator\n"
3024 "YANG module translator\n"
3025 "Module name\n"
3026 "Display compiled module in YANG format\n"
3027 "Display summary information about the module\n"
3028 "Display module in the tree (RFC 8340) format\n"
3029 "Display module in the YANG format\n"
3030 "Display module in the YIN format\n" DAEMONS_STR)
3031{
3032 return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
3033}
3034
3035
4ad77140
RW
3036DEFUNSH(VTYSH_ALL, debug_nb,
3037 debug_nb_cmd,
3038 "[no] debug northbound\
3039 [<\
21f5aade
RW
3040 callbacks [{configuration|state|rpc}]\
3041 |notifications\
3042 |events\
62ae9ade 3043 |libyang\
4ad77140
RW
3044 >]",
3045 NO_STR
3046 DEBUG_STR
3047 "Northbound debugging\n"
3048 "Callbacks\n"
3049 "Configuration\n"
3050 "State\n"
3051 "RPC\n"
3052 "Notifications\n"
62ae9ade
RW
3053 "Events\n"
3054 "libyang debugging\n")
4ad77140
RW
3055{
3056 return CMD_SUCCESS;
3057}
3058
a65f4b5d
DS
3059DEFUN (vtysh_show_history,
3060 vtysh_show_history_cmd,
3061 "show history",
3062 SHOW_STR
3063 "The list of commands stored in history\n")
3064{
3065 HIST_ENTRY **hlist = history_list();
3066 int i = 0;
3067
3068 while (hlist[i]) {
3069 vty_out(vty, "%s\n", hlist[i]->line);
3070 i++;
3071 }
3072 return CMD_SUCCESS;
3073}
3074
2a8e27af
DL
3075/* Memory */
3076DEFUN (vtysh_show_memory,
3077 vtysh_show_memory_cmd,
f09e0369 3078 "show memory [" DAEMONS_LIST "]",
2a8e27af 3079 SHOW_STR
f09e0369
IR
3080 "Memory statistics\n"
3081 DAEMONS_STR)
2a8e27af 3082{
f09e0369
IR
3083 if (argc == 3)
3084 return show_one_daemon(vty, argv, argc - 1,
3085 argv[argc - 1]->text);
3086
a5eb3b0d 3087 return show_per_daemon(vty, argv, argc, "Memory statistics for %s:\n");
2a8e27af
DL
3088}
3089
3090DEFUN (vtysh_show_modules,
3091 vtysh_show_modules_cmd,
3092 "show modules",
3093 SHOW_STR
3094 "Loaded modules\n")
3095{
a5eb3b0d 3096 return show_per_daemon(vty, argv, argc, "Module information for %s:\n");
2a8e27af
DL
3097}
3098
95e735b5 3099/* Logging commands. */
dbf7d13d
PJ
3100DEFUN (vtysh_show_logging,
3101 vtysh_show_logging_cmd,
3102 "show logging",
3103 SHOW_STR
3104 "Show current logging configuration\n")
3105{
a5eb3b0d 3106 return show_per_daemon(vty, argv, argc,
7292d851 3107 "Logging configuration for %s:\n");
d62a17ae 3108}
3109
85a6806d
MS
3110DEFUNSH(VTYSH_ALL, vtysh_debug_memstats,
3111 vtysh_debug_memstats_cmd, "[no] debug memstats-at-exit",
3112 NO_STR
3113 "Debug\n"
3114 "Print memory statistics at exit\n")
3115{
3116 return CMD_SUCCESS;
3117}
3118
0beb61ab
DL
3119DEFUN(vtysh_debug_uid_backtrace,
3120 vtysh_debug_uid_backtrace_cmd,
3121 "[no] debug unique-id UID backtrace",
3122 NO_STR
3123 DEBUG_STR
3124 "Options per individual log message, by unique ID\n"
3125 "Log message unique ID (XXXXX-XXXXX)\n"
3126 "Add backtrace to log when message is printed\n")
3127{
3128 unsigned int i, ok = 0;
3129 int err = CMD_SUCCESS, ret;
3130 const char *uid;
3131 char line[64];
3132
3133 if (!strcmp(argv[0]->text, "no")) {
3134 uid = argv[3]->arg;
3135 snprintfrr(line, sizeof(line),
3136 "no debug unique-id %s backtrace", uid);
3137 } else {
3138 uid = argv[2]->arg;
3139 snprintfrr(line, sizeof(line), "debug unique-id %s backtrace",
3140 uid);
3141 }
3142
3143 for (i = 0; i < array_size(vtysh_client); i++)
3144 if (vtysh_client[i].fd >= 0 || vtysh_client[i].next) {
3145 ret = vtysh_client_execute(&vtysh_client[i], line);
3146 switch (ret) {
3147 case CMD_SUCCESS:
3148 ok++;
3149 break;
3150 case CMD_ERR_NOTHING_TODO:
3151 /* ignore this daemon
3152 *
3153 * note this doesn't need to handle instances
3154 * of the same daemon individually because
3155 * the same daemon will have the same UIDs
3156 */
3157 break;
3158 default:
3159 if (err == CMD_SUCCESS)
3160 err = ret;
3161 break;
3162 }
3163 }
3164
3165 if (err == CMD_SUCCESS && !ok) {
3166 vty_out(vty, "%% no running daemon recognizes unique-ID %s\n",
3167 uid);
3168 err = CMD_WARNING;
3169 }
3170 return err;
3171}
3172
ac156aec
DA
3173DEFUNSH(VTYSH_ALL, vtysh_allow_reserved_ranges, vtysh_allow_reserved_ranges_cmd,
3174 "allow-reserved-ranges",
3175 "Allow using IPv4 (Class E) reserved IP space\n")
3176{
3177 return CMD_SUCCESS;
3178}
3179
3180DEFUNSH(VTYSH_ALL, no_vtysh_allow_reserved_ranges,
3181 no_vtysh_allow_reserved_ranges_cmd, "no allow-reserved-ranges",
3182 NO_STR "Allow using IPv4 (Class E) reserved IP space\n")
3183{
3184 return CMD_SUCCESS;
3185}
3186
d62a17ae 3187DEFUNSH(VTYSH_ALL, vtysh_service_password_encrypt,
3188 vtysh_service_password_encrypt_cmd, "service password-encryption",
3189 "Set up miscellaneous service\n"
3190 "Enable encrypted passwords\n")
e7168df4 3191{
d62a17ae 3192 return CMD_SUCCESS;
e7168df4 3193}
3194
d62a17ae 3195DEFUNSH(VTYSH_ALL, no_vtysh_service_password_encrypt,
3196 no_vtysh_service_password_encrypt_cmd, "no service password-encryption",
3197 NO_STR
3198 "Set up miscellaneous service\n"
3199 "Enable encrypted passwords\n")
e7168df4 3200{
d62a17ae 3201 return CMD_SUCCESS;
e7168df4 3202}
3203
d62a17ae 3204DEFUNSH(VTYSH_ALL, vtysh_config_password, vtysh_password_cmd,
3205 "password [(8-8)] LINE",
322e2d5c 3206 "Modify the terminal connection password\n"
d62a17ae 3207 "Specifies a HIDDEN password will follow\n"
3208 "The password string\n")
e7168df4 3209{
d62a17ae 3210 return CMD_SUCCESS;
e7168df4 3211}
3212
322e2d5c
PM
3213DEFUNSH(VTYSH_ALL, no_vtysh_config_password, no_vtysh_password_cmd,
3214 "no password", NO_STR
3215 "Modify the terminal connection password\n")
3216{
4911ca9c 3217 vty_out(vty, NO_PASSWD_CMD_WARNING);
eb83f7ce 3218
322e2d5c
PM
3219 return CMD_SUCCESS;
3220}
3221
d62a17ae 3222DEFUNSH(VTYSH_ALL, vtysh_config_enable_password, vtysh_enable_password_cmd,
3223 "enable password [(8-8)] LINE",
3224 "Modify enable password parameters\n"
3225 "Assign the privileged level password\n"
3226 "Specifies a HIDDEN password will follow\n"
3227 "The 'enable' password string\n")
e7168df4 3228{
d62a17ae 3229 return CMD_SUCCESS;
e7168df4 3230}
3231
d62a17ae 3232DEFUNSH(VTYSH_ALL, no_vtysh_config_enable_password,
9d303b37 3233 no_vtysh_enable_password_cmd, "no enable password", NO_STR
d62a17ae 3234 "Modify enable password parameters\n"
3235 "Assign the privileged level password\n")
e7168df4 3236{
4911ca9c 3237 vty_out(vty, NO_PASSWD_CMD_WARNING);
eb83f7ce 3238
d62a17ae 3239 return CMD_SUCCESS;
e7168df4 3240}
3241
718e3744 3242DEFUN (vtysh_write_terminal,
3243 vtysh_write_terminal_cmd,
30941443 3244 "write terminal ["DAEMONS_LIST"] [no-header]",
718e3744 3245 "Write running configuration to memory, network, or terminal\n"
066242b5 3246 "Write to terminal\n"
30941443
DL
3247 DAEMONS_STR
3248 "Skip \"Building configuration...\" header\n")
718e3744 3249{
d7c0a89a 3250 unsigned int i;
edae23ff 3251 char line[] = "do write terminal";
d62a17ae 3252
30941443
DL
3253 if (!strcmp(argv[argc - 1]->arg, "no-header"))
3254 argc--;
3255 else {
3256 vty_out(vty, "Building configuration...\n");
3257 vty_out(vty, "\nCurrent configuration:\n");
3258 vty_out(vty, "!\n");
3259 }
d62a17ae 3260
3261 for (i = 0; i < array_size(vtysh_client); i++)
3262 if ((argc < 3)
3263 || (strmatch(vtysh_client[i].name, argv[2]->text)))
3264 vtysh_client_config(&vtysh_client[i], line);
3265
3266 /* Integrate vtysh specific configuration. */
2cddf2ff 3267 vty_open_pager(vty);
d62a17ae 3268 vtysh_config_write();
2cddf2ff
QY
3269 vtysh_config_dump();
3270 vty_close_pager(vty);
3271 vty_out(vty, "end\n");
d62a17ae 3272
d62a17ae 3273 return CMD_SUCCESS;
718e3744 3274}
3275
a98d33ab
QY
3276DEFUN (vtysh_show_running_config,
3277 vtysh_show_running_config_cmd,
30941443 3278 "show running-config ["DAEMONS_LIST"] [no-header]",
a98d33ab
QY
3279 SHOW_STR
3280 "Current operating configuration\n"
30941443
DL
3281 DAEMONS_STR
3282 "Skip \"Building configuration...\" header\n")
c006e89e 3283{
d62a17ae 3284 return vtysh_write_terminal(self, vty, argc, argv);
c006e89e
DS
3285}
3286
e7168df4 3287DEFUN (vtysh_integrated_config,
3288 vtysh_integrated_config_cmd,
3289 "service integrated-vtysh-config",
3290 "Set up miscellaneous service\n"
3291 "Write configuration into integrated file\n")
4fc01e67 3292{
d62a17ae 3293 vtysh_write_integrated = WRITE_INTEGRATED_YES;
3294 return CMD_SUCCESS;
4fc01e67 3295}
3296
e7168df4 3297DEFUN (no_vtysh_integrated_config,
3298 no_vtysh_integrated_config_cmd,
3299 "no service integrated-vtysh-config",
3300 NO_STR
3301 "Set up miscellaneous service\n"
3302 "Write configuration into integrated file\n")
4fc01e67 3303{
d62a17ae 3304 vtysh_write_integrated = WRITE_INTEGRATED_NO;
3305 return CMD_SUCCESS;
4fc01e67 3306}
3307
d62a17ae 3308static void backup_config_file(const char *fbackup)
718e3744 3309{
d62a17ae 3310 char *integrate_sav = NULL;
718e3744 3311
2e600d75
QY
3312 size_t integrate_sav_sz = strlen(fbackup) + strlen(CONF_BACKUP_EXT) + 1;
3313 integrate_sav = malloc(integrate_sav_sz);
3314 strlcpy(integrate_sav, fbackup, integrate_sav_sz);
3315 strlcat(integrate_sav, CONF_BACKUP_EXT, integrate_sav_sz);
718e3744 3316
d62a17ae 3317 /* Move current configuration file to backup config file. */
9fb05a74
TA
3318 if (unlink(integrate_sav) != 0 && errno != ENOENT)
3319 vty_out(vty, "Unlink failed for %s: %s\n", integrate_sav,
3320 strerror(errno));
3321 if (rename(fbackup, integrate_sav) != 0 && errno != ENOENT)
3322 vty_out(vty, "Error renaming %s to %s: %s\n", fbackup,
3323 integrate_sav, strerror(errno));
d62a17ae 3324 free(integrate_sav);
a7222276
DS
3325}
3326
d62a17ae 3327int vtysh_write_config_integrated(void)
a7222276 3328{
d7c0a89a 3329 unsigned int i;
edae23ff 3330 char line[] = "do write terminal";
d62a17ae 3331 FILE *fp;
3332 int fd;
029a775e 3333#ifdef FRR_USER
d62a17ae 3334 struct passwd *pwentry;
029a775e 3335#endif
3336#ifdef FRR_GROUP
d62a17ae 3337 struct group *grentry;
029a775e 3338#endif
d62a17ae 3339 uid_t uid = -1;
3340 gid_t gid = -1;
3341 struct stat st;
3342 int err = 0;
a7222276 3343
2cddf2ff 3344 vty_out(vty, "Building Configuration...\n");
a7222276 3345
9b8a8249
DL
3346 backup_config_file(frr_config);
3347 fp = fopen(frr_config, "w");
d62a17ae 3348 if (fp == NULL) {
2cddf2ff 3349 vty_out(vty,
d62a17ae 3350 "%% Error: failed to open configuration file %s: %s\n",
9b8a8249 3351 frr_config, safe_strerror(errno));
d62a17ae 3352 return CMD_WARNING_CONFIG_FAILED;
3353 }
3354 fd = fileno(fp);
a7222276 3355
d62a17ae 3356 for (i = 0; i < array_size(vtysh_client); i++)
3357 vtysh_client_config(&vtysh_client[i], line);
718e3744 3358
d62a17ae 3359 vtysh_config_write();
b7ae6ac4
QY
3360 vty->of_saved = vty->of;
3361 vty->of = fp;
2cddf2ff 3362 vtysh_config_dump();
b7ae6ac4 3363 vty->of = vty->of_saved;
718e3744 3364
d62a17ae 3365 if (fchmod(fd, CONFIGFILE_MASK) != 0) {
3366 printf("%% Warning: can't chmod configuration file %s: %s\n",
9b8a8249 3367 frr_config, safe_strerror(errno));
d62a17ae 3368 err++;
3369 }
718e3744 3370
9e8df988 3371#ifdef FRR_USER
d62a17ae 3372 pwentry = getpwnam(FRR_USER);
3373 if (pwentry)
3374 uid = pwentry->pw_uid;
3375 else {
3376 printf("%% Warning: could not look up user \"%s\"\n", FRR_USER);
3377 err++;
3378 }
9e8df988
JAG
3379#endif
3380#ifdef FRR_GROUP
d62a17ae 3381 grentry = getgrnam(FRR_GROUP);
3382 if (grentry)
3383 gid = grentry->gr_gid;
3384 else {
3385 printf("%% Warning: could not look up group \"%s\"\n",
3386 FRR_GROUP);
3387 err++;
3388 }
9e8df988 3389#endif
4fc01e67 3390
d62a17ae 3391 if (!fstat(fd, &st)) {
3392 if (st.st_uid == uid)
3393 uid = -1;
3394 if (st.st_gid == gid)
3395 gid = -1;
3396 if ((uid != (uid_t)-1 || gid != (gid_t)-1)
3397 && fchown(fd, uid, gid)) {
3398 printf("%% Warning: can't chown configuration file %s: %s\n",
9b8a8249 3399 frr_config, safe_strerror(errno));
d62a17ae 3400 err++;
3401 }
3402 } else {
9b8a8249 3403 printf("%% Warning: stat() failed on %s: %s\n", frr_config,
d62a17ae 3404 safe_strerror(errno));
3405 err++;
3406 }
3407
789c5919
DA
3408 if (fflush(fp) != 0) {
3409 printf("%% Warning: fflush() failed on %s: %s\n", frr_config,
3410 safe_strerror(errno));
3411 err++;
3412 }
3413
3414 if (fsync(fd) < 0) {
3415 printf("%% Warning: fsync() failed on %s: %s\n", frr_config,
3416 safe_strerror(errno));
3417 err++;
3418 }
3419
d62a17ae 3420 fclose(fp);
3421
9b8a8249 3422 printf("Integrated configuration saved to %s\n", frr_config);
d62a17ae 3423 if (err)
3424 return CMD_WARNING;
3425
3426 printf("[OK]\n");
3427 return CMD_SUCCESS;
718e3744 3428}
3429
e6648f01
DS
3430DEFUN_HIDDEN(start_config, start_config_cmd, "XFRR_start_configuration",
3431 "The Beginning of Configuration\n")
3432{
3433 unsigned int i;
3434 char line[] = "XFRR_start_configuration";
3435
3436 for (i = 0; i < array_size(vtysh_client); i++)
3437 vtysh_client_execute(&vtysh_client[i], line);
3438
3439 return CMD_SUCCESS;
3440}
3441
3442DEFUN_HIDDEN(end_config, end_config_cmd, "XFRR_end_configuration",
3443 "The End of Configuration\n")
3444{
3445 unsigned int i;
3446 char line[] = "XFRR_end_configuration";
3447
3448 for (i = 0; i < array_size(vtysh_client); i++)
3449 vtysh_client_execute(&vtysh_client[i], line);
3450
3451 return CMD_SUCCESS;
3452}
3453
a68f8616 3454static bool want_config_integrated(void)
039eaca3 3455{
d62a17ae 3456 struct stat s;
3457
3458 switch (vtysh_write_integrated) {
3459 case WRITE_INTEGRATED_UNSPECIFIED:
9b8a8249 3460 if (stat(frr_config, &s) && errno == ENOENT)
d62a17ae 3461 return false;
3462 return true;
3463 case WRITE_INTEGRATED_NO:
3464 return false;
3465 case WRITE_INTEGRATED_YES:
3466 return true;
3467 }
3468 return true;
039eaca3
CF
3469}
3470
4fc01e67 3471DEFUN (vtysh_write_memory,
3472 vtysh_write_memory_cmd,
a98d33ab 3473 "write [<memory|file>]",
4fc01e67 3474 "Write running configuration to memory, network, or terminal\n"
a98d33ab
QY
3475 "Write configuration to the file (same as write file)\n"
3476 "Write configuration to the file (same as write memory)\n")
4fc01e67 3477{
d62a17ae 3478 int ret = CMD_SUCCESS;
edae23ff 3479 char line[] = "do write memory";
d7c0a89a 3480 unsigned int i;
d62a17ae 3481
2cddf2ff 3482 vty_out(vty, "Note: this version of vtysh never writes vtysh.conf\n");
d62a17ae 3483
f75b9163 3484 /* If integrated frr.conf explicitly set. */
d62a17ae 3485 if (want_config_integrated()) {
3486 ret = CMD_WARNING_CONFIG_FAILED;
869f5586
QY
3487
3488 /* first attempt to use watchfrr if it's available */
3489 bool used_watchfrr = false;
3490
d62a17ae 3491 for (i = 0; i < array_size(vtysh_client); i++)
3492 if (vtysh_client[i].flag == VTYSH_WATCHFRR)
3493 break;
869f5586
QY
3494 if (i < array_size(vtysh_client) && vtysh_client[i].fd != -1) {
3495 used_watchfrr = true;
d62a17ae 3496 ret = vtysh_client_execute(&vtysh_client[i],
2cddf2ff 3497 "do write integrated");
869f5586 3498 }
d62a17ae 3499
470bc619 3500 /*
869f5586
QY
3501 * If we didn't use watchfrr, fallback to writing the config
3502 * ourselves
470bc619 3503 */
869f5586 3504 if (!used_watchfrr) {
3efd0893 3505 printf("\nWarning: attempting direct configuration write without watchfrr.\nFile permissions and ownership may be incorrect, or write may fail.\n\n");
d62a17ae 3506 ret = vtysh_write_config_integrated();
3507 }
3508 return ret;
3509 }
a7222276 3510
2cddf2ff 3511 vty_out(vty, "Building Configuration...\n");
a7222276 3512
d62a17ae 3513 for (i = 0; i < array_size(vtysh_client); i++)
2cddf2ff 3514 ret = vtysh_client_execute(&vtysh_client[i], line);
4fc01e67 3515
d62a17ae 3516 return ret;
4fc01e67 3517}
3518
a98d33ab
QY
3519DEFUN (vtysh_copy_running_config,
3520 vtysh_copy_running_config_cmd,
3521 "copy running-config startup-config",
718e3744 3522 "Copy from one file to another\n"
3523 "Copy from current system configuration\n"
3524 "Copy to startup configuration\n")
a98d33ab 3525{
d62a17ae 3526 return vtysh_write_memory(self, vty, argc, argv);
a98d33ab 3527}
718e3744 3528
874f579d
MS
3529DEFUN (vtysh_copy_to_running,
3530 vtysh_copy_to_running_cmd,
3531 "copy FILENAME running-config",
3532 "Apply a configuration file\n"
3533 "Configuration file to read\n"
3534 "Apply to current configuration\n")
3535{
3536 int ret;
3537 const char *fname = argv[1]->arg;
3538
ac768090 3539 ret = vtysh_apply_config(fname, true, false);
874f579d
MS
3540
3541 /* Return to enable mode - the 'read_config' api leaves us up a level */
3542 vtysh_execute_no_pager("enable");
3543
3544 return ret;
3545}
3546
76fd5262
DL
3547DEFUN (vtysh_terminal_paginate,
3548 vtysh_terminal_paginate_cmd,
3549 "[no] terminal paginate",
3550 NO_STR
3551 "Set terminal line parameters\n"
3552 "Use pager for output scrolling\n")
3553{
3554 free(vtysh_pager_name);
3555 vtysh_pager_name = NULL;
3556
3557 if (strcmp(argv[0]->text, "no"))
1569f224 3558 vtysh_pager_envdef(true);
76fd5262
DL
3559 return CMD_SUCCESS;
3560}
3561
34553cc3 3562DEFUN (vtysh_terminal_length,
3563 vtysh_terminal_length_cmd,
76fd5262
DL
3564 "[no] terminal length (0-4294967295)",
3565 NO_STR
34553cc3 3566 "Set terminal line parameters\n"
3567 "Set number of lines on a screen\n"
76fd5262 3568 "Number of lines on screen (0 for no pausing, nonzero to use pager)\n")
34553cc3 3569{
d62a17ae 3570 int idx_number = 2;
76fd5262 3571 unsigned long lines;
34553cc3 3572
76fd5262
DL
3573 free(vtysh_pager_name);
3574 vtysh_pager_name = NULL;
34553cc3 3575
76fd5262
DL
3576 if (!strcmp(argv[0]->text, "no") || !strcmp(argv[1]->text, "no")) {
3577 /* "terminal no length" = use VTYSH_PAGER */
1569f224 3578 vtysh_pager_envdef(true);
76fd5262 3579 return CMD_SUCCESS;
d62a17ae 3580 }
34553cc3 3581
76fd5262 3582 lines = strtoul(argv[idx_number]->arg, NULL, 10);
d62a17ae 3583 if (lines != 0) {
76fd5262
DL
3584 vty_out(vty,
3585 "%% The \"terminal length\" command is deprecated and its value is ignored.\n"
3586 "%% Please use \"terminal paginate\" instead with OS TTY length handling.\n");
1569f224 3587 vtysh_pager_envdef(true);
d62a17ae 3588 }
34553cc3 3589
d62a17ae 3590 return CMD_SUCCESS;
34553cc3 3591}
3592
76fd5262 3593ALIAS_DEPRECATED(vtysh_terminal_length,
34553cc3 3594 vtysh_terminal_no_length_cmd,
3595 "terminal no length",
3596 "Set terminal line parameters\n"
3597 NO_STR
3598 "Set number of lines on a screen\n")
34553cc3 3599
f2799e69 3600DEFUN (vtysh_show_daemons,
3601 vtysh_show_daemons_cmd,
3602 "show daemons",
e7168df4 3603 SHOW_STR
3604 "Show list of running daemons\n")
3605{
d7c0a89a 3606 unsigned int i;
b1aa147d 3607
d62a17ae 3608 for (i = 0; i < array_size(vtysh_client); i++)
3609 if (vtysh_client[i].fd >= 0)
2cddf2ff
QY
3610 vty_out(vty, " %s", vtysh_client[i].name);
3611 vty_out(vty, "\n");
e7168df4 3612
d62a17ae 3613 return CMD_SUCCESS;
e7168df4 3614}
3615
bec667a6
DL
3616struct visual_prio {
3617 /* 4 characters for nice alignment */
3618 const char *label;
3619
3620 int c256_background;
3621 int c256_formatarg;
3622};
3623
3624/* clang-format off */
3625struct visual_prio visual_prios[] = {
3626 [LOG_EMERG] = {
3627 .label = "\e[31;1mEMRG",
3628 .c256_background = 53,
3629 .c256_formatarg = 225,
3630 },
3631 [LOG_ALERT] = {
3632 .label = "\e[31;1mALRT",
3633 .c256_background = 53,
3634 .c256_formatarg = 225,
3635 },
3636 [LOG_CRIT] = {
3637 .label = "\e[31;1mCRIT",
3638 .c256_background = 53,
3639 .c256_formatarg = 225,
3640 },
3641 [LOG_ERR] = {
3642 .label = "\e[38;5;202mERR!",
3643 .c256_background = 52,
3644 .c256_formatarg = 224,
3645 },
3646 [LOG_WARNING] = {
3647 .label = "\e[38;5;222mWARN",
3648 .c256_background = 58,
3649 .c256_formatarg = 230,
3650 },
3651 [LOG_NOTICE] = {
3652 .label = "NTFY",
3653 .c256_background = 234,
3654 .c256_formatarg = 195,
3655 },
3656 [LOG_INFO] = {
3657 .label = "\e[38;5;192mINFO",
3658 .c256_background = 236,
3659 .c256_formatarg = 195,
3660 },
3661 [LOG_DEBUG] = {
3662 .label = "\e[38;5;116mDEBG",
3663 .c256_background = 238,
3664 .c256_formatarg = 195,
3665 },
3666};
3667/* clang-format on */
3668
3669static void vtysh_log_print(struct vtysh_client *vclient,
3670 struct zlog_live_hdr *hdr, const char *text)
3671{
3672 size_t textlen = hdr->textlen, textpos = 0;
3673 time_t ts = hdr->ts_sec;
3674 struct visual_prio *vis;
3675 struct tm tm;
3676 char ts_buf[32];
3677
3030e7b5 3678 if (hdr->prio >= array_size(visual_prios))
bec667a6
DL
3679 vis = &visual_prios[LOG_CRIT];
3680 else
3681 vis = &visual_prios[hdr->prio];
3682
3683 localtime_r(&ts, &tm);
3684 strftime(ts_buf, sizeof(ts_buf), "%Y-%m-%d %H:%M:%S", &tm);
3685
3686 if (!stderr_tty) {
3687 const char *label = vis->label + strlen(vis->label) - 4;
3688
3689 fprintf(stderr, "%s.%03u [%s] %s: %.*s\n", ts_buf,
3690 hdr->ts_nsec / 1000000U, label, vclient->name,
3691 (int)textlen, text);
3692 return;
3693 }
3694
3695 fprintf(stderr,
3696 "\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",
3697 vis->c256_background, ts_buf, hdr->ts_nsec / 1000000U,
3698 vis->label, vclient->name);
3699
3700 for (size_t fmtpos = 0; fmtpos < hdr->n_argpos; fmtpos++) {
3701 struct fmt_outpos *fmt = &hdr->argpos[fmtpos];
3702
3703 if (fmt->off_start < textpos || fmt->off_end < fmt->off_start ||
3704 fmt->off_end > textlen)
3705 continue;
3706
3707 while (fmt->off_end > fmt->off_start &&
3708 text[fmt->off_end - 1] == ' ')
3709 fmt->off_end--;
3710
3711 fprintf(stderr, "%.*s\e[38;5;%dm%.*s\e[38;5;251m",
3712 (int)(fmt->off_start - textpos), text + textpos,
3713 vis->c256_formatarg,
3714 (int)(fmt->off_end - fmt->off_start),
3715 text + fmt->off_start);
3716 textpos = fmt->off_end;
3717 }
3718 fprintf(stderr, "%.*s\033[K\033[m\n", (int)(textlen - textpos),
3719 text + textpos);
3720}
3721
e6685141 3722static void vtysh_log_read(struct event *thread)
bec667a6 3723{
e16d030c 3724 struct vtysh_client *vclient = EVENT_ARG(thread);
bec667a6
DL
3725 struct {
3726 struct zlog_live_hdr hdr;
3727 char text[4096];
3728 } buf;
3729 const char *text;
3730 ssize_t ret;
3731
907a2395
DS
3732 event_add_read(master, vtysh_log_read, vclient, vclient->log_fd,
3733 &vclient->log_reader);
bec667a6
DL
3734
3735 ret = recv(vclient->log_fd, &buf, sizeof(buf), 0);
3736
3737 if (ret < 0 && ERRNO_IO_RETRY(errno))
3738 return;
3739
a4af82ee
DL
3740 if (stderr_stdout_same) {
3741#ifdef HAVE_RL_CLEAR_VISIBLE_LINE
3742 rl_clear_visible_line();
3743#else
3744 puts("\r");
3745#endif
3746 fflush(stdout);
3747 }
3748
bec667a6
DL
3749 if (ret <= 0) {
3750 struct timespec ts;
3751
3030e7b5
DL
3752 buf.text[0] = '\0'; /* coverity */
3753
bec667a6
DL
3754 if (ret != 0)
3755 snprintfrr(buf.text, sizeof(buf.text),
3756 "log monitor connection error: %m");
3757 else
3758 snprintfrr(
3759 buf.text, sizeof(buf.text),
3760 "log monitor connection closed unexpectedly");
3761 buf.hdr.textlen = strlen(buf.text);
3762
e16d030c 3763 EVENT_OFF(vclient->log_reader);
bec667a6
DL
3764 close(vclient->log_fd);
3765 vclient->log_fd = -1;
3766
3767 clock_gettime(CLOCK_REALTIME, &ts);
3768 buf.hdr.ts_sec = ts.tv_sec;
3769 buf.hdr.ts_nsec = ts.tv_nsec;
3770 buf.hdr.prio = LOG_ERR;
3771 buf.hdr.flags = 0;
834585bd 3772 buf.hdr.texthdrlen = 0;
bec667a6 3773 buf.hdr.n_argpos = 0;
a4af82ee
DL
3774 } else {
3775 int32_t lost_msgs = buf.hdr.lost_msgs - vclient->lost_msgs;
bec667a6 3776
a4af82ee
DL
3777 if (lost_msgs > 0) {
3778 vclient->lost_msgs = buf.hdr.lost_msgs;
3779 fprintf(stderr,
3780 "%d log messages from %s lost (vtysh reading too slowly)\n",
3781 lost_msgs, vclient->name);
3782 }
bec667a6
DL
3783 }
3784
3785 text = buf.text + sizeof(buf.hdr.argpos[0]) * buf.hdr.n_argpos;
3786 vtysh_log_print(vclient, &buf.hdr, text);
3787
3788 if (stderr_stdout_same)
3789 rl_forced_update_display();
3790
3791 return;
3792}
3793
3794#ifdef CLIPPY
3795/* clippy/clidef can't process the DEFPY below without some value for this */
3796#define DAEMONS_LIST "daemon"
3797#endif
3798
3799DEFPY (vtysh_terminal_monitor,
3800 vtysh_terminal_monitor_cmd,
3801 "terminal monitor ["DAEMONS_LIST"]$daemon",
3802 "Set terminal line parameters\n"
3803 "Receive log messages to active VTY session\n"
3804 DAEMONS_STR)
3805{
edae23ff 3806 static const char line[] = "terminal monitor";
bec667a6
DL
3807 int ret_all = CMD_SUCCESS, ret, fd;
3808 size_t i, ok = 0;
3809
3810 for (i = 0; i < array_size(vtysh_client); i++) {
3811 struct vtysh_client *vclient = &vtysh_client[i];
3812
3813 if (daemon && strcmp(vclient->name, daemon))
3814 continue;
3815
3816 for (; vclient; vclient = vclient->next) {
3817 if (vclient->log_fd != -1) {
3818 vty_out(vty, "%% %s: already monitoring logs\n",
3819 vclient->name);
3820 ok++;
3821 continue;
3822 }
3823
3824 fd = -1;
3825 ret = vtysh_client_run(vclient, line, NULL, NULL, &fd);
3826 if (fd != -1) {
3827 set_nonblocking(fd);
3828 vclient->log_fd = fd;
907a2395
DS
3829 event_add_read(master, vtysh_log_read, vclient,
3830 vclient->log_fd,
3831 &vclient->log_reader);
bec667a6
DL
3832 }
3833 if (ret != CMD_SUCCESS) {
3834 vty_out(vty, "%% failed to enable logs on %s\n",
3835 vclient->name);
3836 ret_all = CMD_WARNING;
3837 } else
3838 ok++;
3839 }
3840 }
3841
3842 if (!ok && ret_all == CMD_SUCCESS) {
3843 vty_out(vty,
3844 "%% command had no effect, relevant daemons not connected?\n");
3845 ret_all = CMD_WARNING;
3846 }
3847 return ret_all;
3848}
3849
3850DEFPY (no_vtysh_terminal_monitor,
3851 no_vtysh_terminal_monitor_cmd,
3852 "no terminal monitor ["DAEMONS_LIST"]$daemon",
3853 NO_STR
3854 "Set terminal line parameters\n"
3855 "Receive log messages to active VTY session\n"
3856 DAEMONS_STR)
3857{
edae23ff 3858 static const char line[] = "no terminal monitor";
bec667a6
DL
3859 int ret_all = CMD_SUCCESS, ret;
3860 size_t i, ok = 0;
3861
3862 for (i = 0; i < array_size(vtysh_client); i++) {
3863 struct vtysh_client *vclient = &vtysh_client[i];
3864
3865 if (daemon && strcmp(vclient->name, daemon))
3866 continue;
3867
3868 for (; vclient; vclient = vclient->next) {
3869 /* run this even if log_fd == -1, in case something
3870 * got desync'd
3871 */
3872 ret = vtysh_client_run(vclient, line, NULL, NULL, NULL);
3873 if (ret != CMD_SUCCESS) {
3874 vty_out(vty,
3875 "%% failed to disable logs on %s\n",
3876 vclient->name);
3877 ret_all = CMD_WARNING;
3878 } else
3879 ok++;
3880
3881 /* with this being a datagram socket, we can't expect
3882 * a close notification...
3883 */
3884 if (vclient->log_fd != -1) {
e16d030c 3885 EVENT_OFF(vclient->log_reader);
bec667a6
DL
3886
3887 close(vclient->log_fd);
3888 vclient->log_fd = -1;
3889 }
3890 }
3891 }
3892
3893 if (!ok && ret_all == CMD_SUCCESS) {
3894 vty_out(vty,
3895 "%% command had no effect, relevant daemons not connected?\n");
3896 ret_all = CMD_WARNING;
3897 }
3898 return ret_all;
3899}
3900
3901
718e3744 3902/* Execute command in child process. */
996c9314
LB
3903static void execute_command(const char *command, int argc, const char *arg1,
3904 const char *arg2)
d62a17ae 3905{
3906 pid_t pid;
3907 int status;
3908
3909 /* Call fork(). */
3910 pid = fork();
3911
3912 if (pid < 0) {
3913 /* Failure of fork(). */
3914 fprintf(stderr, "Can't fork: %s\n", safe_strerror(errno));
3915 exit(1);
3916 } else if (pid == 0) {
3917 /* This is child process. */
3918 switch (argc) {
3919 case 0:
3920 execlp(command, command, (const char *)NULL);
3921 break;
3922 case 1:
3923 execlp(command, command, arg1, (const char *)NULL);
3924 break;
3925 case 2:
3926 execlp(command, command, arg1, arg2,
3927 (const char *)NULL);
3928 break;
3929 }
718e3744 3930
d62a17ae 3931 /* When execlp suceed, this part is not executed. */
3932 fprintf(stderr, "Can't execute %s: %s\n", command,
3933 safe_strerror(errno));
3934 exit(1);
3935 } else {
3936 /* This is parent. */
3937 execute_flag = 1;
3938 wait4(pid, &status, 0, NULL);
3939 execute_flag = 0;
3940 }
718e3744 3941}
3942
3943DEFUN (vtysh_ping,
3944 vtysh_ping_cmd,
3945 "ping WORD",
4eeccf18 3946 "Send echo messages\n"
718e3744 3947 "Ping destination address or hostname\n")
3948{
137a1684
DS
3949 int idx = 1;
3950
3951 argv_find(argv, argc, "WORD", &idx);
3952 execute_command("ping", 1, argv[idx]->arg, NULL);
d62a17ae 3953 return CMD_SUCCESS;
718e3744 3954}
3955
012f7ae4
SR
3956DEFUN(vtysh_motd, vtysh_motd_cmd, "show motd", SHOW_STR "Show motd\n")
3957{
3958 vty_hello(vty);
3959 return CMD_SUCCESS;
3960}
3961
d62a17ae 3962ALIAS(vtysh_ping, vtysh_ping_ip_cmd, "ping ip WORD",
3963 "Send echo messages\n"
3964 "IP echo\n"
3965 "Ping destination address or hostname\n")
4eeccf18 3966
718e3744 3967DEFUN (vtysh_traceroute,
3968 vtysh_traceroute_cmd,
3969 "traceroute WORD",
3970 "Trace route to destination\n"
3971 "Trace route to destination address or hostname\n")
3972{
137a1684
DS
3973 int idx = 1;
3974
3975 argv_find(argv, argc, "WORD", &idx);
3976 execute_command("traceroute", 1, argv[idx]->arg, NULL);
d62a17ae 3977 return CMD_SUCCESS;
718e3744 3978}
3979
d62a17ae 3980ALIAS(vtysh_traceroute, vtysh_traceroute_ip_cmd, "traceroute ip WORD",
3981 "Trace route to destination\n"
3982 "IP trace\n"
3983 "Trace route to destination address or hostname\n")
4eeccf18 3984
4d9ad5dc
MS
3985DEFUN (vtysh_mtrace,
3986 vtysh_mtrace_cmd,
71e55fb2 3987 "mtrace WORD [WORD]",
4d9ad5dc 3988 "Multicast trace route to multicast source\n"
71e55fb2
MS
3989 "Multicast trace route to multicast source address\n"
3990 "Multicast trace route for multicast group address\n")
4d9ad5dc 3991{
71e55fb2
MS
3992 if (argc == 2)
3993 execute_command("mtracebis", 1, argv[1]->arg, NULL);
3994 else
3995 execute_command("mtracebis", 2, argv[1]->arg, argv[2]->arg);
4d9ad5dc
MS
3996 return CMD_SUCCESS;
3997}
3998
4eeccf18 3999DEFUN (vtysh_ping6,
4000 vtysh_ping6_cmd,
4001 "ping ipv6 WORD",
4002 "Send echo messages\n"
4003 "IPv6 echo\n"
4004 "Ping destination address or hostname\n")
4005{
137a1684 4006 execute_command("ping6", 1, argv[2]->arg, NULL);
d62a17ae 4007 return CMD_SUCCESS;
4eeccf18 4008}
4009
4010DEFUN (vtysh_traceroute6,
4011 vtysh_traceroute6_cmd,
4012 "traceroute ipv6 WORD",
4013 "Trace route to destination\n"
4014 "IPv6 trace\n"
4015 "Trace route to destination address or hostname\n")
4016{
137a1684 4017 execute_command("traceroute6", 1, argv[2]->arg, NULL);
d62a17ae 4018 return CMD_SUCCESS;
4eeccf18 4019}
4eeccf18 4020
0876b4c1
DS
4021#if CONFDATE > 20240201
4022CPP_NOTICE("Remove HAVE_SHELL_ACCESS and it's documentation");
4023#endif
576b6b5d 4024#if defined(HAVE_SHELL_ACCESS)
718e3744 4025DEFUN (vtysh_telnet,
4026 vtysh_telnet_cmd,
4027 "telnet WORD",
4028 "Open a telnet connection\n"
4029 "IP address or hostname of a remote system\n")
4030{
137a1684 4031 execute_command("telnet", 1, argv[1]->arg, NULL);
d62a17ae 4032 return CMD_SUCCESS;
718e3744 4033}
4034
4035DEFUN (vtysh_telnet_port,
4036 vtysh_telnet_port_cmd,
4037 "telnet WORD PORT",
4038 "Open a telnet connection\n"
4039 "IP address or hostname of a remote system\n"
4040 "TCP Port number\n")
4041{
137a1684 4042 execute_command("telnet", 2, argv[1]->arg, argv[2]->arg);
d62a17ae 4043 return CMD_SUCCESS;
718e3744 4044}
4045
5087df56 4046DEFUN (vtysh_ssh,
4047 vtysh_ssh_cmd,
4048 "ssh WORD",
4049 "Open an ssh connection\n"
4050 "[user@]host\n")
4051{
137a1684 4052 execute_command("ssh", 1, argv[1]->arg, NULL);
d62a17ae 4053 return CMD_SUCCESS;
5087df56 4054}
4055
718e3744 4056DEFUN (vtysh_start_shell,
4057 vtysh_start_shell_cmd,
4058 "start-shell",
4059 "Start UNIX shell\n")
4060{
d62a17ae 4061 execute_command("sh", 0, NULL, NULL);
4062 return CMD_SUCCESS;
718e3744 4063}
4064
4065DEFUN (vtysh_start_bash,
4066 vtysh_start_bash_cmd,
4067 "start-shell bash",
4068 "Start UNIX shell\n"
4069 "Start bash\n")
4070{
d62a17ae 4071 execute_command("bash", 0, NULL, NULL);
4072 return CMD_SUCCESS;
718e3744 4073}
4074
4075DEFUN (vtysh_start_zsh,
4076 vtysh_start_zsh_cmd,
4077 "start-shell zsh",
4078 "Start UNIX shell\n"
4079 "Start Z shell\n")
4080{
d62a17ae 4081 execute_command("zsh", 0, NULL, NULL);
4082 return CMD_SUCCESS;
718e3744 4083}
576b6b5d 4084#endif
b094d260 4085
0b84f294
DL
4086DEFUN (config_list,
4087 config_list_cmd,
4088 "list [permutations]",
4089 "Print command list\n"
4090 "Print all possible command permutations\n")
4091{
d62a17ae 4092 return cmd_list_cmds(vty, argc == 2);
0b84f294
DL
4093}
4094
193a5a95
QY
4095DEFUN (vtysh_output_file,
4096 vtysh_output_file_cmd,
4097 "output file FILE",
4098 "Direct vtysh output to file\n"
4099 "Direct vtysh output to file\n"
4100 "Path to dump output to\n")
4101{
4102 const char *path = argv[argc - 1]->arg;
2cddf2ff
QY
4103 vty->of = fopen(path, "a");
4104 if (!vty->of) {
4105 vty_out(vty, "Failed to open file '%s': %s\n", path,
193a5a95 4106 safe_strerror(errno));
2cddf2ff 4107 vty->of = stdout;
193a5a95
QY
4108 }
4109 return CMD_SUCCESS;
4110}
4111
4112DEFUN (no_vtysh_output_file,
4113 no_vtysh_output_file_cmd,
4114 "no output file [FILE]",
4115 NO_STR
4116 "Direct vtysh output to file\n"
4117 "Direct vtysh output to file\n"
4118 "Path to dump output to\n")
4119{
2cddf2ff
QY
4120 if (vty->of != stdout) {
4121 fclose(vty->of);
4122 vty->of = stdout;
193a5a95
QY
4123 }
4124 return CMD_SUCCESS;
4125}
4126
cf6c83e7
QY
4127DEFUN(find,
4128 find_cmd,
767f67a4 4129 "find REGEX...",
68912a20
QY
4130 "Find CLI command matching a regular expression\n"
4131 "Search pattern (POSIX regex)\n")
cf6c83e7 4132{
c2278962 4133 return cmd_find_cmds(vty, argv, argc);
cf6c83e7
QY
4134}
4135
26fbe472
QY
4136DEFUN_HIDDEN(show_cli_graph_vtysh,
4137 show_cli_graph_vtysh_cmd,
4138 "show cli graph",
4139 SHOW_STR
4140 "CLI reflection\n"
4141 "Dump current command space as DOT graph\n")
4142{
4143 struct cmd_node *cn = vector_slot(cmdvec, vty->node);
4144 char *dot = cmd_graph_dump_dot(cn->cmdgraph);
4145
4146 vty_out(vty, "%s\n", dot);
4147 XFREE(MTYPE_TMP, dot);
4148 return CMD_SUCCESS;
4149}
4150
d62a17ae 4151static void vtysh_install_default(enum node_type node)
718e3744 4152{
01485adb
DL
4153 _install_element(node, &config_list_cmd);
4154 _install_element(node, &find_cmd);
4155 _install_element(node, &show_cli_graph_vtysh_cmd);
4156 _install_element(node, &vtysh_output_file_cmd);
4157 _install_element(node, &no_vtysh_output_file_cmd);
718e3744 4158}
4159
4160/* Making connection to protocol daemon. */
d62a17ae 4161static int vtysh_connect(struct vtysh_client *vclient)
4162{
4163 int ret;
4164 int sock, len;
4165 struct sockaddr_un addr;
4166 struct stat s_stat;
4167 const char *path;
4168
4169 if (!vclient->path[0])
4170 snprintf(vclient->path, sizeof(vclient->path), "%s/%s.vty",
9b8a8249 4171 vtydir, vclient->name);
d62a17ae 4172 path = vclient->path;
4173
4174 /* Stat socket to see if we have permission to access it. */
4175 ret = stat(path, &s_stat);
4176 if (ret < 0 && errno != ENOENT) {
4177 fprintf(stderr, "vtysh_connect(%s): stat = %s\n", path,
4178 safe_strerror(errno));
4179 exit(1);
4180 }
4181
4182 if (ret >= 0) {
4183 if (!S_ISSOCK(s_stat.st_mode)) {
4184 fprintf(stderr, "vtysh_connect(%s): Not a socket\n",
4185 path);
4186 exit(1);
4187 }
718e3744 4188 }
718e3744 4189
d62a17ae 4190 sock = socket(AF_UNIX, SOCK_STREAM, 0);
4191 if (sock < 0) {
718e3744 4192#ifdef DEBUG
d62a17ae 4193 fprintf(stderr, "vtysh_connect(%s): socket = %s\n", path,
4194 safe_strerror(errno));
718e3744 4195#endif /* DEBUG */
d62a17ae 4196 return -1;
4197 }
718e3744 4198
6006b807 4199 memset(&addr, 0, sizeof(addr));
d62a17ae 4200 addr.sun_family = AF_UNIX;
4201 strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
6f0e3f6e 4202#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
d62a17ae 4203 len = addr.sun_len = SUN_LEN(&addr);
718e3744 4204#else
d62a17ae 4205 len = sizeof(addr.sun_family) + strlen(addr.sun_path);
6f0e3f6e 4206#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
718e3744 4207
d62a17ae 4208 ret = connect(sock, (struct sockaddr *)&addr, len);
4209 if (ret < 0) {
718e3744 4210#ifdef DEBUG
d62a17ae 4211 fprintf(stderr, "vtysh_connect(%s): connect = %s\n", path,
4212 safe_strerror(errno));
718e3744 4213#endif /* DEBUG */
d62a17ae 4214 close(sock);
4215 return -1;
4216 }
4217 vclient->fd = sock;
718e3744 4218
d62a17ae 4219 return 0;
718e3744 4220}
4221
67736451
MS
4222static int vtysh_reconnect(struct vtysh_client *vclient)
4223{
4224 int ret;
4225
4226 fprintf(stderr, "Warning: connecting to %s...", vclient->name);
4227 ret = vtysh_connect(vclient);
4228 if (ret < 0) {
4229 fprintf(stderr, "failed!\n");
4230 return ret;
4231 }
4232 fprintf(stderr, "success!\n");
2cddf2ff 4233 if (vtysh_client_execute(vclient, "enable") < 0)
67736451
MS
4234 return -1;
4235 return vtysh_execute_no_pager("end");
4236}
4237
7c8ff89e 4238/* Return true if str ends with suffix, else return false */
d62a17ae 4239static int ends_with(const char *str, const char *suffix)
7c8ff89e 4240{
d62a17ae 4241 if (!str || !suffix)
4242 return 0;
4243 size_t lenstr = strlen(str);
4244 size_t lensuffix = strlen(suffix);
4245 if (lensuffix > lenstr)
4246 return 0;
4247 return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
7c8ff89e
DS
4248}
4249
d62a17ae 4250static void vtysh_client_sorted_insert(struct vtysh_client *head_client,
4251 struct vtysh_client *client)
7c8ff89e 4252{
d62a17ae 4253 struct vtysh_client *prev_node, *current_node;
7c8ff89e 4254
d62a17ae 4255 prev_node = head_client;
4256 current_node = head_client->next;
4257 while (current_node) {
4258 if (strcmp(current_node->path, client->path) > 0)
4259 break;
7c8ff89e 4260
d62a17ae 4261 prev_node = current_node;
4262 current_node = current_node->next;
4263 }
4264 client->next = current_node;
4265 prev_node->next = client;
7c8ff89e
DS
4266}
4267
4268#define MAXIMUM_INSTANCES 10
4269
462ea14a 4270static void vtysh_update_all_instances(struct vtysh_client *head_client)
d62a17ae 4271{
4272 struct vtysh_client *client;
4273 DIR *dir;
4274 struct dirent *file;
4275 int n = 0;
4276
4277 if (head_client->flag != VTYSH_OSPFD)
4278 return;
4279
4280 /* ls vty_sock_dir and look for all files ending in .vty */
9b8a8249 4281 dir = opendir(vtydir);
d62a17ae 4282 if (dir) {
4283 while ((file = readdir(dir)) != NULL) {
90cf59ec 4284 if (frrstr_startswith(file->d_name, "ospfd-")
d62a17ae 4285 && ends_with(file->d_name, ".vty")) {
4286 if (n == MAXIMUM_INSTANCES) {
4287 fprintf(stderr,
4288 "Parsing %s, client limit(%d) reached!\n",
9b8a8249 4289 vtydir, n);
d62a17ae 4290 break;
4291 }
4292 client = (struct vtysh_client *)malloc(
4293 sizeof(struct vtysh_client));
4294 client->fd = -1;
4295 client->name = "ospfd";
4296 client->flag = VTYSH_OSPFD;
4297 snprintf(client->path, sizeof(client->path),
9b8a8249 4298 "%s/%s", vtydir, file->d_name);
d62a17ae 4299 client->next = NULL;
4300 vtysh_client_sorted_insert(head_client, client);
4301 n++;
4302 }
4303 }
4304 closedir(dir);
4305 }
4306}
4307
4308static int vtysh_connect_all_instances(struct vtysh_client *head_client)
4309{
4310 struct vtysh_client *client;
4311 int rc = 0;
4312
462ea14a 4313 vtysh_update_all_instances(head_client);
d62a17ae 4314
4315 client = head_client->next;
4316 while (client) {
4317 if (vtysh_connect(client) == 0)
4318 rc++;
4319 client = client->next;
4320 }
4321
4322 return rc;
4323}
4324
4325int vtysh_connect_all(const char *daemon_name)
4326{
d7c0a89a 4327 unsigned int i;
d62a17ae 4328 int rc = 0;
4329 int matches = 0;
4330
4331 for (i = 0; i < array_size(vtysh_client); i++) {
4332 if (!daemon_name
4333 || !strcmp(daemon_name, vtysh_client[i].name)) {
4334 matches++;
4335 if (vtysh_connect(&vtysh_client[i]) == 0)
4336 rc++;
4337
4338 rc += vtysh_connect_all_instances(&vtysh_client[i]);
4339 }
4340 }
4341 if (!matches)
4342 fprintf(stderr, "Error: no daemons match name %s!\n",
4343 daemon_name);
4344 return rc;
718e3744 4345}
4346
95e735b5 4347/* To disable readline's filename completion. */
d62a17ae 4348static char *vtysh_completion_entry_function(const char *ignore,
4349 int invoking_key)
718e3744 4350{
d62a17ae 4351 return NULL;
718e3744 4352}
4353
d62a17ae 4354void vtysh_readline_init(void)
718e3744 4355{
d62a17ae 4356 /* readline related settings. */
dab6893f
QY
4357 char *disable_bracketed_paste =
4358 XSTRDUP(MTYPE_TMP, "set enable-bracketed-paste off");
4359
d62a17ae 4360 rl_initialize();
dab6893f 4361 rl_parse_and_bind(disable_bracketed_paste);
d62a17ae 4362 rl_bind_key('?', (rl_command_func_t *)vtysh_rl_describe);
4363 rl_completion_entry_function = vtysh_completion_entry_function;
7c70dc57 4364 rl_attempted_completion_function = new_completion;
dab6893f
QY
4365
4366 XFREE(MTYPE_TMP, disable_bracketed_paste);
718e3744 4367}
4368
d62a17ae 4369char *vtysh_prompt(void)
718e3744 4370{
63e653a2 4371 static char buf[512];
718e3744 4372
c84e5187
DL
4373#pragma GCC diagnostic push
4374#pragma GCC diagnostic ignored "-Wformat-nonliteral"
4375 /* prompt formatting has a %s in the cmd_node prompt string. */
0d6f7fd6 4376 snprintf(buf, sizeof(buf), cmd_prompt(vty->node), cmd_hostname_get());
c84e5187 4377#pragma GCC diagnostic pop
d62a17ae 4378 return buf;
718e3744 4379}
4380
7f059ea6
DL
4381static void vtysh_ac_line(void *arg, const char *line)
4382{
d62a17ae 4383 vector comps = arg;
4384 size_t i;
4385 for (i = 0; i < vector_active(comps); i++)
4386 if (!strcmp(line, (char *)vector_slot(comps, i)))
4387 return;
4388 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, line));
7f059ea6
DL
4389}
4390
4391static void vtysh_autocomplete(vector comps, struct cmd_token *token)
4392{
d62a17ae 4393 char accmd[256];
4394 size_t i;
7f059ea6 4395
d62a17ae 4396 snprintf(accmd, sizeof(accmd), "autocomplete %d %s %s", token->type,
4397 token->text, token->varname ? token->varname : "-");
7f059ea6 4398
8d70e7fe
QY
4399 vty->of_saved = vty->of;
4400 vty->of = NULL;
d62a17ae 4401 for (i = 0; i < array_size(vtysh_client); i++)
2cddf2ff
QY
4402 vtysh_client_run_all(&vtysh_client[i], accmd, 1, vtysh_ac_line,
4403 comps);
8d70e7fe 4404 vty->of = vty->of_saved;
7f059ea6
DL
4405}
4406
1d6664e0 4407static const struct cmd_variable_handler vtysh_var_handler[] = {
d62a17ae 4408 {/* match all */
4409 .tokenname = NULL,
4410 .varname = NULL,
4411 .completions = vtysh_autocomplete},
4412 {.completions = NULL}};
4413
4d762f26 4414void vtysh_uninit(void)
193a5a95 4415{
2cddf2ff
QY
4416 if (vty->of != stdout)
4417 fclose(vty->of);
193a5a95
QY
4418}
4419
d62a17ae 4420void vtysh_init_vty(void)
4421{
bec667a6
DL
4422 struct stat st_out, st_err;
4423
0e06eb8b
DL
4424 cmd_defer_tree(true);
4425
bec667a6
DL
4426 for (size_t i = 0; i < array_size(vtysh_client); i++) {
4427 vtysh_client[i].fd = -1;
4428 vtysh_client[i].log_fd = -1;
4429 }
4430
4431 stderr_tty = isatty(STDERR_FILENO);
4432
4433 if (fstat(STDOUT_FILENO, &st_out) || fstat(STDERR_FILENO, &st_err) ||
4434 (st_out.st_dev == st_err.st_dev && st_out.st_ino == st_err.st_ino))
4435 stderr_stdout_same = true;
4436
d62a17ae 4437 /* Make vty structure. */
4438 vty = vty_new();
4439 vty->type = VTY_SHELL;
4440 vty->node = VIEW_NODE;
4441
193a5a95 4442 /* set default output */
2cddf2ff 4443 vty->of = stdout;
1569f224 4444 vtysh_pager_envdef(false);
193a5a95 4445
d62a17ae 4446 /* Initialize commands. */
4447 cmd_init(0);
4448 cmd_variable_handler_register(vtysh_var_handler);
4449
5d574646 4450 /* bgpd */
0eb5751d 4451#ifdef HAVE_BGPD
612c2c15 4452 install_node(&bgp_node);
5d574646
IR
4453 install_element(CONFIG_NODE, &router_bgp_cmd);
4454 install_element(BGP_NODE, &vtysh_exit_bgpd_cmd);
4455 install_element(BGP_NODE, &vtysh_quit_bgpd_cmd);
4456 install_element(BGP_NODE, &vtysh_end_all_cmd);
4457
612c2c15 4458 install_node(&bgp_vpnv4_node);
5d574646
IR
4459 install_element(BGP_NODE, &address_family_ipv4_vpn_cmd);
4460#ifdef KEEP_OLD_VPN_COMMANDS
4461 install_element(BGP_NODE, &address_family_vpnv4_cmd);
4462#endif /* KEEP_OLD_VPN_COMMANDS */
4463 install_element(BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd);
4464 install_element(BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd);
4465 install_element(BGP_VPNV4_NODE, &vtysh_end_all_cmd);
4466 install_element(BGP_VPNV4_NODE, &exit_address_family_cmd);
4467
612c2c15 4468 install_node(&bgp_vpnv6_node);
5d574646
IR
4469 install_element(BGP_NODE, &address_family_ipv6_vpn_cmd);
4470#ifdef KEEP_OLD_VPN_COMMANDS
4471 install_element(BGP_NODE, &address_family_vpnv6_cmd);
4472#endif /* KEEP_OLD_VPN_COMMANDS */
4473 install_element(BGP_VPNV6_NODE, &vtysh_exit_bgpd_cmd);
4474 install_element(BGP_VPNV6_NODE, &vtysh_quit_bgpd_cmd);
4475 install_element(BGP_VPNV6_NODE, &vtysh_end_all_cmd);
4476 install_element(BGP_VPNV6_NODE, &exit_address_family_cmd);
4477
612c2c15 4478 install_node(&bgp_flowspecv4_node);
5d574646
IR
4479 install_element(BGP_NODE, &address_family_flowspecv4_cmd);
4480 install_element(BGP_FLOWSPECV4_NODE, &vtysh_exit_bgpd_cmd);
4481 install_element(BGP_FLOWSPECV4_NODE, &vtysh_quit_bgpd_cmd);
4482 install_element(BGP_FLOWSPECV4_NODE, &vtysh_end_all_cmd);
4483 install_element(BGP_FLOWSPECV4_NODE, &exit_address_family_cmd);
4484
612c2c15 4485 install_node(&bgp_flowspecv6_node);
5d574646
IR
4486 install_element(BGP_NODE, &address_family_flowspecv6_cmd);
4487 install_element(BGP_FLOWSPECV6_NODE, &vtysh_exit_bgpd_cmd);
4488 install_element(BGP_FLOWSPECV6_NODE, &vtysh_quit_bgpd_cmd);
4489 install_element(BGP_FLOWSPECV6_NODE, &vtysh_end_all_cmd);
4490 install_element(BGP_FLOWSPECV6_NODE, &exit_address_family_cmd);
4491
612c2c15 4492 install_node(&bgp_ipv4_node);
5d574646
IR
4493 install_element(BGP_NODE, &address_family_ipv4_cmd);
4494 install_element(BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd);
4495 install_element(BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd);
4496 install_element(BGP_IPV4_NODE, &vtysh_end_all_cmd);
4497 install_element(BGP_IPV4_NODE, &exit_address_family_cmd);
4498
612c2c15 4499 install_node(&bgp_ipv4m_node);
5d574646
IR
4500 install_element(BGP_NODE, &address_family_ipv4_multicast_cmd);
4501 install_element(BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd);
4502 install_element(BGP_IPV4M_NODE, &vtysh_quit_bgpd_cmd);
4503 install_element(BGP_IPV4M_NODE, &vtysh_end_all_cmd);
4504 install_element(BGP_IPV4M_NODE, &exit_address_family_cmd);
4505
612c2c15 4506 install_node(&bgp_ipv4l_node);
5d574646
IR
4507 install_element(BGP_NODE, &address_family_ipv4_labeled_unicast_cmd);
4508 install_element(BGP_IPV4L_NODE, &vtysh_exit_bgpd_cmd);
4509 install_element(BGP_IPV4L_NODE, &vtysh_quit_bgpd_cmd);
4510 install_element(BGP_IPV4L_NODE, &vtysh_end_all_cmd);
4511 install_element(BGP_IPV4L_NODE, &exit_address_family_cmd);
4512
612c2c15 4513 install_node(&bgp_ipv6_node);
5d574646
IR
4514 install_element(BGP_NODE, &address_family_ipv6_cmd);
4515 install_element(BGP_IPV6_NODE, &vtysh_exit_bgpd_cmd);
4516 install_element(BGP_IPV6_NODE, &vtysh_quit_bgpd_cmd);
4517 install_element(BGP_IPV6_NODE, &vtysh_end_all_cmd);
4518 install_element(BGP_IPV6_NODE, &exit_address_family_cmd);
4519
612c2c15 4520 install_node(&bgp_ipv6m_node);
5d574646
IR
4521 install_element(BGP_NODE, &address_family_ipv6_multicast_cmd);
4522 install_element(BGP_IPV6M_NODE, &vtysh_exit_bgpd_cmd);
4523 install_element(BGP_IPV6M_NODE, &vtysh_quit_bgpd_cmd);
4524 install_element(BGP_IPV6M_NODE, &vtysh_end_all_cmd);
4525 install_element(BGP_IPV6M_NODE, &exit_address_family_cmd);
4526
612c2c15 4527 install_node(&bgp_ipv6l_node);
5d574646
IR
4528 install_element(BGP_NODE, &address_family_ipv6_labeled_unicast_cmd);
4529 install_element(BGP_IPV6L_NODE, &vtysh_exit_bgpd_cmd);
4530 install_element(BGP_IPV6L_NODE, &vtysh_quit_bgpd_cmd);
4531 install_element(BGP_IPV6L_NODE, &vtysh_end_all_cmd);
4532 install_element(BGP_IPV6L_NODE, &exit_address_family_cmd);
4533
4534#if defined(ENABLE_BGP_VNC)
612c2c15 4535 install_node(&bgp_vrf_policy_node);
5d574646
IR
4536 install_element(BGP_NODE, &vnc_vrf_policy_cmd);
4537 install_element(BGP_VRF_POLICY_NODE, &vtysh_exit_bgpd_cmd);
4538 install_element(BGP_VRF_POLICY_NODE, &vtysh_quit_bgpd_cmd);
4539 install_element(BGP_VRF_POLICY_NODE, &vtysh_end_all_cmd);
4540 install_element(BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd);
4541
612c2c15 4542 install_node(&bgp_vnc_defaults_node);
5d574646
IR
4543 install_element(BGP_NODE, &vnc_defaults_cmd);
4544 install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_exit_bgpd_cmd);
4545 install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_quit_bgpd_cmd);
4546 install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_end_all_cmd);
4547 install_element(BGP_VNC_DEFAULTS_NODE, &exit_vnc_config_cmd);
4548
612c2c15 4549 install_node(&bgp_vnc_nve_group_node);
5d574646
IR
4550 install_element(BGP_NODE, &vnc_nve_group_cmd);
4551 install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_exit_bgpd_cmd);
4552 install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_quit_bgpd_cmd);
4553 install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_end_all_cmd);
4554 install_element(BGP_VNC_NVE_GROUP_NODE, &exit_vnc_config_cmd);
4555
612c2c15 4556 install_node(&bgp_vnc_l2_group_node);
5d574646
IR
4557 install_element(BGP_NODE, &vnc_l2_group_cmd);
4558 install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_exit_bgpd_cmd);
4559 install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_quit_bgpd_cmd);
4560 install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_end_all_cmd);
4561 install_element(BGP_VNC_L2_GROUP_NODE, &exit_vnc_config_cmd);
4562#endif
d62a17ae 4563
5d574646
IR
4564 install_node(&bgp_evpn_node);
4565 install_element(BGP_NODE, &address_family_evpn_cmd);
5d574646
IR
4566 install_element(BGP_EVPN_NODE, &vtysh_quit_bgpd_cmd);
4567 install_element(BGP_EVPN_NODE, &vtysh_exit_bgpd_cmd);
4568 install_element(BGP_EVPN_NODE, &vtysh_end_all_cmd);
4569 install_element(BGP_EVPN_NODE, &exit_address_family_cmd);
d62a17ae 4570
5d574646
IR
4571 install_node(&bgp_evpn_vni_node);
4572 install_element(BGP_EVPN_NODE, &bgp_evpn_vni_cmd);
4573 install_element(BGP_EVPN_VNI_NODE, &vtysh_exit_bgpd_cmd);
4574 install_element(BGP_EVPN_VNI_NODE, &vtysh_quit_bgpd_cmd);
4575 install_element(BGP_EVPN_VNI_NODE, &vtysh_end_all_cmd);
4576 install_element(BGP_EVPN_VNI_NODE, &exit_vni_cmd);
d62a17ae 4577
5d574646
IR
4578 install_node(&rpki_node);
4579 install_element(CONFIG_NODE, &rpki_cmd);
4580 install_element(RPKI_NODE, &rpki_exit_cmd);
4581 install_element(RPKI_NODE, &rpki_quit_cmd);
4582 install_element(RPKI_NODE, &vtysh_end_all_cmd);
4583
4584 install_node(&bmp_node);
4585 install_element(BGP_NODE, &bmp_targets_cmd);
4586 install_element(BMP_NODE, &bmp_exit_cmd);
4587 install_element(BMP_NODE, &bmp_quit_cmd);
4588 install_element(BMP_NODE, &vtysh_end_all_cmd);
bfaab44d
HS
4589
4590 install_node(&bgp_srv6_node);
4591 install_element(BGP_NODE, &bgp_srv6_cmd);
4592 install_element(BGP_SRV6_NODE, &exit_bgp_srv6_cmd);
4593 install_element(BGP_SRV6_NODE, &quit_bgp_srv6_cmd);
4594 install_element(BGP_SRV6_NODE, &vtysh_end_all_cmd);
0eb5751d 4595#endif /* HAVE_BGPD */
5d574646
IR
4596
4597 /* ripd */
4598 install_node(&rip_node);
0eb5751d 4599#ifdef HAVE_RIPD
5d574646 4600 install_element(CONFIG_NODE, &router_rip_cmd);
d62a17ae 4601 install_element(RIP_NODE, &vtysh_exit_ripd_cmd);
4602 install_element(RIP_NODE, &vtysh_quit_ripd_cmd);
5d574646 4603 install_element(RIP_NODE, &vtysh_end_all_cmd);
0eb5751d 4604#endif /* HAVE_RIPD */
5d574646
IR
4605
4606 /* ripngd */
4607 install_node(&ripng_node);
0eb5751d 4608#ifdef HAVE_RIPNGD
5d574646 4609 install_element(CONFIG_NODE, &router_ripng_cmd);
d62a17ae 4610 install_element(RIPNG_NODE, &vtysh_exit_ripngd_cmd);
4611 install_element(RIPNG_NODE, &vtysh_quit_ripngd_cmd);
5d574646 4612 install_element(RIPNG_NODE, &vtysh_end_all_cmd);
0eb5751d 4613#endif /* HAVE_RIPNGD */
5d574646
IR
4614
4615 /* ospfd */
0eb5751d 4616#ifdef HAVE_OSPFD
5d574646
IR
4617 install_node(&ospf_node);
4618 install_element(CONFIG_NODE, &router_ospf_cmd);
d62a17ae 4619 install_element(OSPF_NODE, &vtysh_exit_ospfd_cmd);
4620 install_element(OSPF_NODE, &vtysh_quit_ospfd_cmd);
5d574646 4621 install_element(OSPF_NODE, &vtysh_end_all_cmd);
0eb5751d 4622#endif /* HAVE_OSPFD */
5d574646
IR
4623
4624 /* ospf6d */
0eb5751d 4625#ifdef HAVE_OSPF6D
5d574646
IR
4626 install_node(&ospf6_node);
4627 install_element(CONFIG_NODE, &router_ospf6_cmd);
d62a17ae 4628 install_element(OSPF6_NODE, &vtysh_exit_ospf6d_cmd);
4629 install_element(OSPF6_NODE, &vtysh_quit_ospf6d_cmd);
5d574646 4630 install_element(OSPF6_NODE, &vtysh_end_all_cmd);
0eb5751d 4631#endif /* HAVE_OSPF6D */
5d574646
IR
4632
4633 /* ldpd */
d62a17ae 4634#if defined(HAVE_LDPD)
5d574646
IR
4635 install_node(&ldp_node);
4636 install_element(CONFIG_NODE, &ldp_mpls_ldp_cmd);
d62a17ae 4637 install_element(LDP_NODE, &vtysh_exit_ldpd_cmd);
4638 install_element(LDP_NODE, &vtysh_quit_ldpd_cmd);
5d574646
IR
4639 install_element(LDP_NODE, &vtysh_end_all_cmd);
4640
4641 install_node(&ldp_ipv4_node);
4642 install_element(LDP_NODE, &ldp_address_family_ipv4_cmd);
d62a17ae 4643 install_element(LDP_IPV4_NODE, &vtysh_exit_ldpd_cmd);
4644 install_element(LDP_IPV4_NODE, &vtysh_quit_ldpd_cmd);
983bd6f7 4645 install_element(LDP_IPV4_NODE, &ldp_exit_address_family_cmd);
5d574646
IR
4646 install_element(LDP_IPV4_NODE, &vtysh_end_all_cmd);
4647
4648 install_node(&ldp_ipv6_node);
4649 install_element(LDP_NODE, &ldp_address_family_ipv6_cmd);
d62a17ae 4650 install_element(LDP_IPV6_NODE, &vtysh_exit_ldpd_cmd);
4651 install_element(LDP_IPV6_NODE, &vtysh_quit_ldpd_cmd);
983bd6f7 4652 install_element(LDP_IPV6_NODE, &ldp_exit_address_family_cmd);
5d574646
IR
4653 install_element(LDP_IPV6_NODE, &vtysh_end_all_cmd);
4654
4655 install_node(&ldp_ipv4_iface_node);
4656 install_element(LDP_IPV4_NODE, &ldp_interface_ifname_cmd);
d62a17ae 4657 install_element(LDP_IPV4_IFACE_NODE, &vtysh_exit_ldpd_cmd);
4658 install_element(LDP_IPV4_IFACE_NODE, &vtysh_quit_ldpd_cmd);
5d574646
IR
4659 install_element(LDP_IPV4_IFACE_NODE, &vtysh_end_all_cmd);
4660
4661 install_node(&ldp_ipv6_iface_node);
4662 install_element(LDP_IPV6_NODE, &ldp_interface_ifname_cmd);
d62a17ae 4663 install_element(LDP_IPV6_IFACE_NODE, &vtysh_exit_ldpd_cmd);
4664 install_element(LDP_IPV6_IFACE_NODE, &vtysh_quit_ldpd_cmd);
5d574646
IR
4665 install_element(LDP_IPV6_IFACE_NODE, &vtysh_end_all_cmd);
4666
4667 install_node(&ldp_l2vpn_node);
4668 install_element(CONFIG_NODE, &ldp_l2vpn_word_type_vpls_cmd);
d62a17ae 4669 install_element(LDP_L2VPN_NODE, &vtysh_exit_ldpd_cmd);
4670 install_element(LDP_L2VPN_NODE, &vtysh_quit_ldpd_cmd);
5d574646
IR
4671 install_element(LDP_L2VPN_NODE, &vtysh_end_all_cmd);
4672
4673 install_node(&ldp_pseudowire_node);
4674 install_element(LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd);
d62a17ae 4675 install_element(LDP_PSEUDOWIRE_NODE, &vtysh_exit_ldpd_cmd);
4676 install_element(LDP_PSEUDOWIRE_NODE, &vtysh_quit_ldpd_cmd);
5d574646 4677 install_element(LDP_PSEUDOWIRE_NODE, &vtysh_end_all_cmd);
87ab4aec 4678#endif
5d574646
IR
4679
4680 /* eigrpd */
0eb5751d 4681#ifdef HAVE_EIGRPD
5d574646
IR
4682 install_node(&eigrp_node);
4683 install_element(CONFIG_NODE, &router_eigrp_cmd);
4684 install_element(EIGRP_NODE, &vtysh_exit_eigrpd_cmd);
4685 install_element(EIGRP_NODE, &vtysh_quit_eigrpd_cmd);
4686 install_element(EIGRP_NODE, &vtysh_end_all_cmd);
0eb5751d 4687#endif /* HAVE_EIGRPD */
5d574646
IR
4688
4689 /* babeld */
0eb5751d 4690#ifdef HAVE_BABELD
5d574646
IR
4691 install_node(&babel_node);
4692 install_element(CONFIG_NODE, &router_babel_cmd);
4693 install_element(BABEL_NODE, &vtysh_exit_babeld_cmd);
4694 install_element(BABEL_NODE, &vtysh_quit_babeld_cmd);
4695 install_element(BABEL_NODE, &vtysh_end_all_cmd);
0eb5751d 4696#endif /* HAVE_BABELD */
5d574646
IR
4697
4698 /* isisd */
0eb5751d 4699#ifdef HAVE_ISISD
5d574646
IR
4700 install_node(&isis_node);
4701 install_element(CONFIG_NODE, &router_isis_cmd);
d62a17ae 4702 install_element(ISIS_NODE, &vtysh_exit_isisd_cmd);
4703 install_element(ISIS_NODE, &vtysh_quit_isisd_cmd);
5d574646 4704 install_element(ISIS_NODE, &vtysh_end_all_cmd);
0eb5751d 4705#endif /* HAVE_ISISD */
5d574646
IR
4706
4707 /* fabricd */
0eb5751d 4708#ifdef HAVE_FABRICD
5d574646
IR
4709 install_node(&openfabric_node);
4710 install_element(CONFIG_NODE, &router_openfabric_cmd);
770ccdf8
CF
4711 install_element(OPENFABRIC_NODE, &vtysh_exit_fabricd_cmd);
4712 install_element(OPENFABRIC_NODE, &vtysh_quit_fabricd_cmd);
5d574646 4713 install_element(OPENFABRIC_NODE, &vtysh_end_all_cmd);
0eb5751d 4714#endif /* HAVE_FABRICD */
5d574646
IR
4715
4716 /* pbrd */
0eb5751d 4717#ifdef HAVE_PBRD
5d574646
IR
4718 install_node(&pbr_map_node);
4719 install_element(CONFIG_NODE, &vtysh_pbr_map_cmd);
4720 install_element(CONFIG_NODE, &vtysh_no_pbr_map_cmd);
e5c83d9b
DS
4721 install_element(PBRMAP_NODE, &vtysh_exit_pbr_map_cmd);
4722 install_element(PBRMAP_NODE, &vtysh_quit_pbr_map_cmd);
5d574646 4723 install_element(PBRMAP_NODE, &vtysh_end_all_cmd);
0eb5751d 4724#endif /* HAVE_PBRD */
5d574646
IR
4725
4726 /* bfdd */
c2f29cf3 4727#if HAVE_BFDD > 0
5d574646 4728 install_node(&bfd_node);
c2f29cf3 4729 install_element(CONFIG_NODE, &bfd_enter_cmd);
c2f29cf3
RZ
4730 install_element(BFD_NODE, &vtysh_exit_bfdd_cmd);
4731 install_element(BFD_NODE, &vtysh_quit_bfdd_cmd);
5d574646
IR
4732 install_element(BFD_NODE, &vtysh_end_all_cmd);
4733
4734 install_node(&bfd_peer_node);
4735 install_element(BFD_NODE, &bfd_peer_enter_cmd);
c2f29cf3
RZ
4736 install_element(BFD_PEER_NODE, &vtysh_exit_bfdd_cmd);
4737 install_element(BFD_PEER_NODE, &vtysh_quit_bfdd_cmd);
5d574646
IR
4738 install_element(BFD_PEER_NODE, &vtysh_end_all_cmd);
4739
4740 install_node(&bfd_profile_node);
4741 install_element(BFD_NODE, &bfd_profile_enter_cmd);
d40d6c22
RZ
4742 install_element(BFD_PROFILE_NODE, &vtysh_exit_bfdd_cmd);
4743 install_element(BFD_PROFILE_NODE, &vtysh_quit_bfdd_cmd);
d40d6c22 4744 install_element(BFD_PROFILE_NODE, &vtysh_end_all_cmd);
c2f29cf3 4745#endif /* HAVE_BFDD */
d62a17ae 4746
4d7b695d 4747 install_node(&segment_routing_node);
1b3aea98 4748 install_element(CONFIG_NODE, &segment_routing_cmd);
5df73b05
DS
4749 install_element(SEGMENT_ROUTING_NODE, &vtysh_exit_sr_cmd);
4750 install_element(SEGMENT_ROUTING_NODE, &vtysh_quit_sr_cmd);
4751 install_element(SEGMENT_ROUTING_NODE, &vtysh_end_all_cmd);
4752
4753#if defined(HAVE_PATHD)
4d7b695d
SM
4754 install_node(&sr_traffic_eng_node);
4755 install_node(&srte_segment_list_node);
4756 install_node(&srte_policy_node);
4757 install_node(&srte_candidate_dyn_node);
4758
4d7b695d
SM
4759 install_element(SR_TRAFFIC_ENG_NODE, &vtysh_exit_pathd_cmd);
4760 install_element(SR_TRAFFIC_ENG_NODE, &vtysh_quit_pathd_cmd);
4761 install_element(SR_SEGMENT_LIST_NODE, &vtysh_exit_pathd_cmd);
4762 install_element(SR_SEGMENT_LIST_NODE, &vtysh_quit_pathd_cmd);
4763 install_element(SR_POLICY_NODE, &vtysh_exit_pathd_cmd);
4764 install_element(SR_POLICY_NODE, &vtysh_quit_pathd_cmd);
4765 install_element(SR_CANDIDATE_DYN_NODE, &vtysh_exit_pathd_cmd);
4766 install_element(SR_CANDIDATE_DYN_NODE, &vtysh_quit_pathd_cmd);
4767
5df73b05 4768
4d7b695d
SM
4769 install_element(SR_TRAFFIC_ENG_NODE, &vtysh_end_all_cmd);
4770 install_element(SR_SEGMENT_LIST_NODE, &vtysh_end_all_cmd);
4771 install_element(SR_POLICY_NODE, &vtysh_end_all_cmd);
4772 install_element(SR_CANDIDATE_DYN_NODE, &vtysh_end_all_cmd);
4773
4d7b695d
SM
4774 install_element(SEGMENT_ROUTING_NODE, &sr_traffic_eng_cmd);
4775 install_element(SR_TRAFFIC_ENG_NODE, &srte_segment_list_cmd);
4776 install_element(SR_TRAFFIC_ENG_NODE, &srte_policy_cmd);
4777 install_element(SR_POLICY_NODE, &srte_policy_candidate_dyn_path_cmd);
efba0985 4778
efba0985
SM
4779 install_node(&pcep_node);
4780 install_node(&pcep_pcc_node);
4781 install_node(&pcep_pce_node);
4782 install_node(&pcep_pce_config_node);
4783
4784 install_element(PCEP_NODE, &vtysh_exit_pathd_cmd);
4785 install_element(PCEP_NODE, &vtysh_quit_pathd_cmd);
4786 install_element(PCEP_PCC_NODE, &vtysh_exit_pathd_cmd);
4787 install_element(PCEP_PCC_NODE, &vtysh_quit_pathd_cmd);
4788 install_element(PCEP_PCE_NODE, &vtysh_exit_pathd_cmd);
4789 install_element(PCEP_PCE_NODE, &vtysh_quit_pathd_cmd);
4790 install_element(PCEP_PCE_CONFIG_NODE, &vtysh_exit_pathd_cmd);
4791 install_element(PCEP_PCE_CONFIG_NODE, &vtysh_quit_pathd_cmd);
4792
4793 install_element(PCEP_NODE, &vtysh_end_all_cmd);
4794 install_element(PCEP_PCC_NODE, &vtysh_end_all_cmd);
4795 install_element(PCEP_PCE_NODE, &vtysh_end_all_cmd);
4796 install_element(PCEP_PCE_CONFIG_NODE, &vtysh_end_all_cmd);
4797
4798 install_element(SR_TRAFFIC_ENG_NODE, &pcep_cmd);
4799 install_element(PCEP_NODE, &pcep_cli_pcc_cmd);
4800 install_element(PCEP_NODE, &pcep_cli_pcep_pce_config_cmd);
4801 install_element(PCEP_NODE, &pcep_cli_pce_cmd);
efba0985 4802
4d7b695d
SM
4803#endif /* HAVE_PATHD */
4804
5d574646
IR
4805 /* keychain */
4806 install_node(&keychain_node);
4807 install_element(CONFIG_NODE, &key_chain_cmd);
4808 install_element(KEYCHAIN_NODE, &key_chain_cmd);
4809 install_element(KEYCHAIN_NODE, &vtysh_exit_keys_cmd);
4810 install_element(KEYCHAIN_NODE, &vtysh_quit_keys_cmd);
d62a17ae 4811 install_element(KEYCHAIN_NODE, &vtysh_end_all_cmd);
5d574646
IR
4812
4813 install_node(&keychain_key_node);
4814 install_element(KEYCHAIN_NODE, &key_cmd);
4815 install_element(KEYCHAIN_KEY_NODE, &key_chain_cmd);
4816 install_element(KEYCHAIN_KEY_NODE, &vtysh_exit_keys_cmd);
4817 install_element(KEYCHAIN_KEY_NODE, &vtysh_quit_keys_cmd);
d62a17ae 4818 install_element(KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd);
d62a17ae 4819
5d574646
IR
4820 /* nexthop-group */
4821 install_node(&nh_group_node);
4822 install_element(CONFIG_NODE, &vtysh_nexthop_group_cmd);
4823 install_element(CONFIG_NODE, &vtysh_no_nexthop_group_cmd);
4824 install_element(NH_GROUP_NODE, &vtysh_end_all_cmd);
4825 install_element(NH_GROUP_NODE, &vtysh_exit_nexthop_group_cmd);
4826 install_element(NH_GROUP_NODE, &vtysh_quit_nexthop_group_cmd);
4827
4828 /* zebra and all */
4829 install_node(&zebra_node);
4830
4831 install_node(&interface_node);
4832 install_element(CONFIG_NODE, &vtysh_interface_cmd);
d62a17ae 4833 install_element(INTERFACE_NODE, &vtysh_end_all_cmd);
4834 install_element(INTERFACE_NODE, &vtysh_exit_interface_cmd);
5d574646
IR
4835 install_element(INTERFACE_NODE, &vtysh_quit_interface_cmd);
4836
4837 install_node(&link_params_node);
4838 install_element(INTERFACE_NODE, &vtysh_link_params_cmd);
d62a17ae 4839 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
4840 install_element(LINK_PARAMS_NODE, &vtysh_end_all_cmd);
92de4c7f
IR
4841 install_element(LINK_PARAMS_NODE, &vtysh_exit_link_params_cmd);
4842 install_element(LINK_PARAMS_NODE, &vtysh_quit_link_params_cmd);
d62a17ae 4843
5d574646
IR
4844 install_node(&pw_node);
4845 install_element(CONFIG_NODE, &vtysh_pseudowire_cmd);
2dd0d726 4846 install_element(PW_NODE, &vtysh_end_all_cmd);
92de4c7f
IR
4847 install_element(PW_NODE, &vtysh_exit_pseudowire_cmd);
4848 install_element(PW_NODE, &vtysh_quit_pseudowire_cmd);
2dd0d726 4849
5d574646
IR
4850 install_node(&vrf_node);
4851 install_element(CONFIG_NODE, &vtysh_vrf_cmd);
5d574646 4852 install_element(VRF_NODE, &exit_vrf_config_cmd);
d62a17ae 4853 install_element(VRF_NODE, &vtysh_end_all_cmd);
4854 install_element(VRF_NODE, &vtysh_exit_vrf_cmd);
4855 install_element(VRF_NODE, &vtysh_quit_vrf_cmd);
85dcff6e 4856
05a12619
LS
4857 install_element(CONFIG_NODE, &vtysh_affinity_map_cmd);
4858 install_element(CONFIG_NODE, &vtysh_no_affinity_map_cmd);
4859
5d574646
IR
4860 install_node(&rmap_node);
4861 install_element(CONFIG_NODE, &vtysh_route_map_cmd);
4862 install_element(RMAP_NODE, &vtysh_exit_rmap_cmd);
4863 install_element(RMAP_NODE, &vtysh_quit_rmap_cmd);
4864 install_element(RMAP_NODE, &vtysh_end_all_cmd);
d62a17ae 4865
5d574646
IR
4866 install_node(&vty_node);
4867 install_element(CONFIG_NODE, &vtysh_line_vty_cmd);
4868 install_element(VTY_NODE, &vtysh_exit_line_vty_cmd);
4869 install_element(VTY_NODE, &vtysh_quit_line_vty_cmd);
4870 install_element(VTY_NODE, &vtysh_end_all_cmd);
d62a17ae 4871
ed18356f 4872
5d574646
IR
4873 struct cmd_node *node;
4874 for (unsigned int i = 0; i < vector_active(cmdvec); i++) {
4875 node = vector_slot(cmdvec, i);
4876 if (!node || node->node == VIEW_NODE)
4877 continue;
4878 vtysh_install_default(node->node);
4879 }
dabecd7c 4880
5d574646 4881 /* vtysh */
d62a17ae 4882
c5479628
IR
4883 if (!user_mode)
4884 install_element(VIEW_NODE, &vtysh_enable_cmd);
5d574646
IR
4885 install_element(ENABLE_NODE, &vtysh_config_terminal_cmd);
4886 install_element(ENABLE_NODE, &vtysh_disable_cmd);
4887
4888 /* "exit" command. */
4889 install_element(VIEW_NODE, &vtysh_exit_all_cmd);
4890 install_element(CONFIG_NODE, &vtysh_exit_all_cmd);
4891 install_element(VIEW_NODE, &vtysh_quit_all_cmd);
4892 install_element(CONFIG_NODE, &vtysh_quit_all_cmd);
4893
4894 /* "end" command. */
4895 install_element(CONFIG_NODE, &vtysh_end_all_cmd);
4896 install_element(ENABLE_NODE, &vtysh_end_all_cmd);
d62a17ae 4897
6c0a7c09
HS
4898 /* SRv6 Data-plane */
4899 install_node(&srv6_node);
4900 install_element(SEGMENT_ROUTING_NODE, &srv6_cmd);
4901 install_element(SRV6_NODE, &srv6_locators_cmd);
4902 install_element(SRV6_NODE, &exit_srv6_config_cmd);
4903 install_element(SRV6_NODE, &vtysh_end_all_cmd);
4904
4905 install_node(&srv6_locs_node);
4906 install_element(SRV6_LOCS_NODE, &srv6_locator_cmd);
4907 install_element(SRV6_LOCS_NODE, &exit_srv6_locs_config_cmd);
4908 install_element(SRV6_LOCS_NODE, &vtysh_end_all_cmd);
4909
4910 install_node(&srv6_loc_node);
4911 install_element(SRV6_LOC_NODE, &exit_srv6_loc_config_cmd);
4912 install_element(SRV6_LOC_NODE, &vtysh_end_all_cmd);
4913
d62a17ae 4914 install_element(ENABLE_NODE, &vtysh_show_running_config_cmd);
4915 install_element(ENABLE_NODE, &vtysh_copy_running_config_cmd);
874f579d 4916 install_element(ENABLE_NODE, &vtysh_copy_to_running_cmd);
d62a17ae 4917
d62a17ae 4918 /* "write terminal" command. */
4919 install_element(ENABLE_NODE, &vtysh_write_terminal_cmd);
4920
4921 install_element(CONFIG_NODE, &vtysh_integrated_config_cmd);
4922 install_element(CONFIG_NODE, &no_vtysh_integrated_config_cmd);
4923
4924 /* "write memory" command. */
4925 install_element(ENABLE_NODE, &vtysh_write_memory_cmd);
4926
e6648f01
DS
4927 install_element(CONFIG_NODE, &start_config_cmd);
4928 install_element(CONFIG_NODE, &end_config_cmd);
4929
1569f224 4930 install_element(CONFIG_NODE, &vtysh_terminal_paginate_cmd);
76fd5262 4931 install_element(VIEW_NODE, &vtysh_terminal_paginate_cmd);
d62a17ae 4932 install_element(VIEW_NODE, &vtysh_terminal_length_cmd);
4933 install_element(VIEW_NODE, &vtysh_terminal_no_length_cmd);
4934 install_element(VIEW_NODE, &vtysh_show_daemons_cmd);
4935
bec667a6
DL
4936 install_element(VIEW_NODE, &vtysh_terminal_monitor_cmd);
4937 install_element(VIEW_NODE, &no_vtysh_terminal_monitor_cmd);
4938
d62a17ae 4939 install_element(VIEW_NODE, &vtysh_ping_cmd);
012f7ae4 4940 install_element(VIEW_NODE, &vtysh_motd_cmd);
d62a17ae 4941 install_element(VIEW_NODE, &vtysh_ping_ip_cmd);
4942 install_element(VIEW_NODE, &vtysh_traceroute_cmd);
4943 install_element(VIEW_NODE, &vtysh_traceroute_ip_cmd);
4d9ad5dc 4944 install_element(VIEW_NODE, &vtysh_mtrace_cmd);
d62a17ae 4945 install_element(VIEW_NODE, &vtysh_ping6_cmd);
4946 install_element(VIEW_NODE, &vtysh_traceroute6_cmd);
576b6b5d 4947#if defined(HAVE_SHELL_ACCESS)
d62a17ae 4948 install_element(VIEW_NODE, &vtysh_telnet_cmd);
4949 install_element(VIEW_NODE, &vtysh_telnet_port_cmd);
4950 install_element(VIEW_NODE, &vtysh_ssh_cmd);
4eeccf18 4951#endif
576b6b5d 4952#if defined(HAVE_SHELL_ACCESS)
d62a17ae 4953 install_element(ENABLE_NODE, &vtysh_start_shell_cmd);
4954 install_element(ENABLE_NODE, &vtysh_start_bash_cmd);
4955 install_element(ENABLE_NODE, &vtysh_start_zsh_cmd);
576b6b5d
DS
4956#endif
4957
aea03ad6 4958 /* debugging */
7b526b61 4959 install_element(VIEW_NODE, &vtysh_show_error_code_cmd);
dd73744d
IR
4960 install_element(ENABLE_NODE, &vtysh_show_debugging_cmd);
4961 install_element(ENABLE_NODE, &vtysh_show_debugging_hashtable_cmd);
eb68fbc6 4962 install_element(ENABLE_NODE, &vtysh_debug_all_cmd);
aea03ad6 4963 install_element(CONFIG_NODE, &vtysh_debug_all_cmd);
85a6806d
MS
4964 install_element(ENABLE_NODE, &vtysh_debug_memstats_cmd);
4965 install_element(CONFIG_NODE, &vtysh_debug_memstats_cmd);
0beb61ab
DL
4966 install_element(ENABLE_NODE, &vtysh_debug_uid_backtrace_cmd);
4967 install_element(CONFIG_NODE, &vtysh_debug_uid_backtrace_cmd);
aea03ad6 4968
4ad77140 4969 /* northbound */
bcbe60d4 4970 install_element(ENABLE_NODE, &show_config_running_cmd);
88c71200 4971 install_element(ENABLE_NODE, &show_yang_operational_data_cmd);
3bb513c3
CH
4972 install_element(ENABLE_NODE, &show_yang_module_cmd);
4973 install_element(ENABLE_NODE, &show_yang_module_detail_cmd);
4ad77140
RW
4974 install_element(ENABLE_NODE, &debug_nb_cmd);
4975 install_element(CONFIG_NODE, &debug_nb_cmd);
4976
aea03ad6 4977 /* misc lib show commands */
a65f4b5d 4978 install_element(VIEW_NODE, &vtysh_show_history_cmd);
d62a17ae 4979 install_element(VIEW_NODE, &vtysh_show_memory_cmd);
4980 install_element(VIEW_NODE, &vtysh_show_modules_cmd);
d62a17ae 4981 install_element(VIEW_NODE, &vtysh_show_work_queues_cmd);
4982 install_element(VIEW_NODE, &vtysh_show_work_queues_daemon_cmd);
d62a17ae 4983 install_element(VIEW_NODE, &vtysh_show_thread_cmd);
8872626b 4984 install_element(VIEW_NODE, &vtysh_show_poll_cmd);
22f31b8c 4985 install_element(VIEW_NODE, &vtysh_show_thread_timer_cmd);
d62a17ae 4986
4987 /* Logging */
4988 install_element(VIEW_NODE, &vtysh_show_logging_cmd);
d62a17ae 4989
4990 install_element(CONFIG_NODE, &vtysh_service_password_encrypt_cmd);
4991 install_element(CONFIG_NODE, &no_vtysh_service_password_encrypt_cmd);
4992
ac156aec
DA
4993 install_element(CONFIG_NODE, &vtysh_allow_reserved_ranges_cmd);
4994 install_element(CONFIG_NODE, &no_vtysh_allow_reserved_ranges_cmd);
4995
d62a17ae 4996 install_element(CONFIG_NODE, &vtysh_password_cmd);
322e2d5c 4997 install_element(CONFIG_NODE, &no_vtysh_password_cmd);
d62a17ae 4998 install_element(CONFIG_NODE, &vtysh_enable_password_cmd);
4999 install_element(CONFIG_NODE, &no_vtysh_enable_password_cmd);
718e3744 5000}