summaryrefslogtreecommitdiffstats
path: root/vtysh/vtysh.c
diff options
context:
space:
mode:
Diffstat (limited to 'vtysh/vtysh.c')
-rw-r--r--vtysh/vtysh.c160
1 files changed, 158 insertions, 2 deletions
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 63b596a5..0d585f55 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -34,6 +34,9 @@
#include "memory.h"
#include "vtysh/vtysh.h"
#include "log.h"
+#include "filter.h"
+#include "linklist.h"
+#include "prefix.h"
#include "bgpd/bgp_vty.h"
#include "vrf.h"
@@ -423,6 +426,157 @@ vtysh_execute (const char *line)
return vtysh_execute_func (line, 1);
}
+int
+vtysh_mark_file (const char *filename)
+{
+ struct vty *vty;
+ FILE *confp = NULL;
+ int ret;
+ vector vline;
+ int tried = 0;
+ struct cmd_element *cmd;
+ int saved_ret, prev_node;
+ int lineno = 0;
+
+ if (strncmp("-", filename, 1) == 0)
+ confp = stdin;
+ else
+ confp = fopen (filename, "r");
+
+ if (confp == NULL)
+ return (1);
+
+ vty = vty_new ();
+ vty->fd = 0; /* stdout */
+ vty->type = VTY_TERM;
+ vty->node = CONFIG_NODE;
+
+ vtysh_execute_no_pager ("enable");
+ vtysh_execute_no_pager ("configure terminal");
+
+ while (fgets (vty->buf, VTY_BUFSIZ, confp))
+ {
+ lineno++;
+ tried = 0;
+
+ if (vty->buf[0] == '!' || vty->buf[1] == '#')
+ {
+ fprintf(stdout, "%s", vty->buf);
+ continue;
+ }
+
+ /* Split readline string up into the vector. */
+ vline = cmd_make_strvec (vty->buf);
+
+ if (vline == NULL)
+ {
+ fprintf(stdout, "%s", vty->buf);
+ continue;
+ }
+
+ prev_node = vty->node;
+ saved_ret = ret = cmd_execute_command_strict (vline, vty, &cmd);
+
+ /* If command doesn't succeeded in current node, try to walk up in node tree.
+ * Changing vty->node is enough to try it just out without actual walkup in
+ * the vtysh. */
+ while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON && ret != CMD_WARNING
+ && vty->node > CONFIG_NODE)
+ {
+ vty->node = node_parent(vty->node);
+ ret = cmd_execute_command_strict (vline, vty, &cmd);
+ tried++;
+ }
+
+ /* If command succeeded in any other node than current (tried > 0) we have
+ * to move into node in the vtysh where it succeeded. */
+ if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON || ret == CMD_WARNING)
+ {
+ if ((prev_node == BGP_VPNV4_NODE || prev_node == BGP_IPV4_NODE
+ || prev_node == BGP_IPV6_NODE || prev_node == BGP_IPV4M_NODE
+ || prev_node == BGP_IPV6M_NODE)
+ && (tried == 1))
+ {
+ fprintf(stdout, "exit-address-family\n");
+ }
+ else if ((prev_node == KEYCHAIN_KEY_NODE) && (tried == 1))
+ {
+ fprintf(stdout, "exit\n");
+ }
+ else if (tried)
+ {
+ fprintf(stdout, "end\n");
+ }
+ }
+ /* If command didn't succeed in any node, continue with return value from
+ * first try. */
+ else if (tried)
+ {
+ ret = saved_ret;
+ vty->node = prev_node;
+ }
+
+ cmd_free_strvec (vline);
+ switch (ret)
+ {
+ case CMD_WARNING:
+ if (vty->type == VTY_FILE)
+ fprintf (stderr,"line %d: Warning...: %s\n", lineno, vty->buf);
+ fclose(confp);
+ vty_close(vty);
+ return (1);
+ case CMD_ERR_AMBIGUOUS:
+ fprintf (stderr,"line %d: %% Ambiguous command: %s\n", lineno, vty->buf);
+ fclose(confp);
+ vty_close(vty);
+ return(1);
+ case CMD_ERR_NO_MATCH:
+ fprintf (stderr,"line %d: %% Unknown command: %s\n", lineno, vty->buf);
+ fclose(confp);
+ vty_close(vty);
+ return(1);
+ case CMD_ERR_INCOMPLETE:
+ fprintf (stderr,"line %d: %% Command incomplete: %s\n", lineno, vty->buf);
+ fclose(confp);
+ vty_close(vty);
+ return(1);
+ case CMD_SUCCESS:
+ fprintf(stdout, "%s", vty->buf);
+ break;
+ case CMD_SUCCESS_DAEMON:
+ {
+ u_int i;
+ int cmd_stat = CMD_SUCCESS;
+
+ fprintf(stdout, "%s", vty->buf);
+ for (i = 0; i < array_size(vtysh_client); i++)
+ {
+ if (cmd->daemon & vtysh_client[i].flag)
+ {
+ cmd_stat = vtysh_client_execute (&vtysh_client[i],
+ vty->buf, stdout);
+ if (cmd_stat != CMD_SUCCESS)
+ break;
+ }
+ }
+ if (cmd_stat != CMD_SUCCESS)
+ break;
+
+ if (cmd->func)
+ (*cmd->func) (cmd, vty, 0, NULL);
+ }
+ }
+ }
+ /* This is the end */
+ fprintf(stdout, "end\n");
+ vty_close(vty);
+
+ if (confp != stdin)
+ fclose(confp);
+
+ return (0);
+}
+
/* Configration make from file. */
int
vtysh_config_from_file (struct vty *vty, FILE *fp)
@@ -441,13 +595,13 @@ vtysh_config_from_file (struct vty *vty, FILE *fp)
fprintf (stdout,"Warning...\n");
break;
case CMD_ERR_AMBIGUOUS:
- fprintf (stdout,"%% Ambiguous command.\n");
+ fprintf (stdout,"%% Ambiguous command: %s\n", vty->buf);
break;
case CMD_ERR_NO_MATCH:
fprintf (stdout,"%% Unknown command: %s", vty->buf);
break;
case CMD_ERR_INCOMPLETE:
- fprintf (stdout,"%% Command incomplete.\n");
+ fprintf (stdout,"%% Command incomplete: %s\n", vty->buf);
break;
case CMD_SUCCESS_DAEMON:
{
@@ -1897,6 +2051,7 @@ write_config_integrated(void)
for (i = 0; i < array_size(vtysh_client); i++)
vtysh_client_execute (&vtysh_client[i], line, NULL);
+ vtysh_config_write ();
vtysh_config_dump (fp);
fclose (fp);
@@ -2500,6 +2655,7 @@ vtysh_init_vty (void)
#ifdef HAVE_IPV6
install_element (BGP_NODE, &address_family_ipv6_cmd);
install_element (BGP_NODE, &address_family_ipv6_unicast_cmd);
+ install_element (BGP_NODE, &address_family_ipv6_multicast_cmd);
#endif
install_element (BGP_VPNV4_NODE, &exit_address_family_cmd);
install_element (BGP_VPNV6_NODE, &exit_address_family_cmd);