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