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