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