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