From 5689fe5fefdb6f9f4f5dcb73cc863f44db76aa78 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Mon, 27 Jul 2015 20:30:22 -0700 Subject: [PATCH] Quagga processes should not die if they read an unrecognized line in their config file Ticket: CM-6738 Reviewed By: Donald and Dinesh Testing Done: --- lib/command.c | 47 +++++++++++++++++++++++++++++++------------- lib/vty.c | 15 ++++++++------ lib/vty.h | 3 +++ vtysh/vtysh.c | 10 +++++----- vtysh/vtysh.h | 2 +- vtysh/vtysh_config.c | 19 +----------------- 6 files changed, 52 insertions(+), 44 deletions(-) diff --git a/lib/command.c b/lib/command.c index b034369d98..d487ce4e73 100644 --- a/lib/command.c +++ b/lib/command.c @@ -2761,11 +2761,12 @@ cmd_execute_command_strict (vector vline, struct vty *vty, return cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd); } -/* Configration make from file. */ +/* Configuration make from file. */ int config_from_file (struct vty *vty, FILE *fp) { - int ret; + int ret, error_ret=0; + int saved_node; vector vline; while (fgets (vty->buf, VTY_BUFSIZ, fp)) @@ -2778,24 +2779,42 @@ config_from_file (struct vty *vty, FILE *fp) /* Execute configuration command : this is strict match */ ret = cmd_execute_command_strict (vline, vty, NULL); - /* Try again with setting node to CONFIG_NODE */ - while (ret != CMD_SUCCESS && ret != CMD_WARNING - && ret != CMD_ERR_NOTHING_TODO && vty->node != CONFIG_NODE) - { - vty->node = node_parent(vty->node); - ret = cmd_execute_command_strict (vline, vty, NULL); - } + // Climb the tree and try the command again at each node + if (ret != CMD_SUCCESS && ret != CMD_WARNING && + ret != CMD_ERR_NOTHING_TODO && vty->node != CONFIG_NODE) { - cmd_free_strvec (vline); + saved_node = vty->node; - if (ret != CMD_SUCCESS && ret != CMD_WARNING - && ret != CMD_ERR_NOTHING_TODO) - return ret; + while (ret != CMD_SUCCESS && ret != CMD_WARNING && + ret != CMD_ERR_NOTHING_TODO && vty->node != CONFIG_NODE) { + vty->node = node_parent(vty->node); + ret = cmd_execute_command_strict (vline, vty, NULL); + } + + // If climbing the tree did not work then ignore the command and + // stay at the same node + if (ret != CMD_SUCCESS && ret != CMD_WARNING && + ret != CMD_ERR_NOTHING_TODO) { + vty->node = saved_node; + + if (!error_ret) { + memcpy(vty->error_buf, vty->buf, VTY_BUFSIZ); + error_ret = ret; + } + } + } + + cmd_free_strvec (vline); } + + if (error_ret) { + return error_ret; + } + return CMD_SUCCESS; } -/* Configration from terminal */ +/* Configuration from terminal */ DEFUN (config_terminal, config_terminal_cmd, "configure terminal", diff --git a/lib/vty.c b/lib/vty.c index 7ced104014..890f47acb6 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -322,6 +322,7 @@ vty_new () new->obuf = buffer_new(0); /* Use default buffer size. */ new->buf = XCALLOC (MTYPE_VTY, VTY_BUFSIZ); + new->error_buf = XCALLOC (MTYPE_VTY, VTY_BUFSIZ); new->max = VTY_BUFSIZ; return new; @@ -478,6 +479,7 @@ vty_ensure (struct vty *vty, int length) { vty->max *= 2; vty->buf = XREALLOC (MTYPE_VTY, vty->buf, vty->max); + vty->error_buf = XREALLOC (MTYPE_VTY, vty->error_buf, vty->max); } } @@ -2195,6 +2197,9 @@ vty_close (struct vty *vty) if (vty->buf) XFREE (MTYPE_VTY, vty->buf); + if (vty->error_buf) + XFREE (MTYPE_VTY, vty->error_buf); + /* Check configure. */ vty_config_unlock (vty); @@ -2243,16 +2248,14 @@ vty_read_file (FILE *confp) switch (ret) { case CMD_ERR_AMBIGUOUS: - fprintf (stderr, "Ambiguous command.\n"); + fprintf (stderr, "\nAmbiguous command."); break; case CMD_ERR_NO_MATCH: - fprintf (stderr, "There is no such command.\n"); + fprintf (stderr, "\nThere is no such command."); break; } - fprintf (stderr, "Error occured during reading below line.\n%s\n", - vty->buf); - vty_close (vty); - exit (1); + fprintf (stderr, "\nError occured during reading below line.\n%s\n", + vty->error_buf); } vty_close (vty); diff --git a/lib/vty.h b/lib/vty.h index bce6c80bf1..e3ca3db038 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -49,6 +49,9 @@ struct vty /* Command input buffer */ char *buf; + /* Command input error buffer */ + char *error_buf; + /* Command cursor point */ int cp; diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index b1c9f453b6..d134c027b6 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -662,7 +662,7 @@ vtysh_mark_file (const char *filename) } /* Configration make from file. */ -int +void vtysh_config_from_file (struct vty *vty, FILE *fp) { int ret; @@ -707,14 +707,15 @@ vtysh_config_from_file (struct vty *vty, FILE *fp) else { save_node = vty->node; - vtysh_execute ("end"); - vtysh_execute ("configure terminal"); vty->node = CONFIG_NODE; ret = cmd_execute_command_strict (vline, vty, &cmd); + + // If the command did not work at CONFIG_NODE either then ignore + // the command and go back to our previous node. if ((ret != CMD_SUCCESS) && (ret != CMD_SUCCESS_DAEMON) && (ret != CMD_WARNING)) - vty->node = save_node; + vty->node = save_node; } } @@ -758,7 +759,6 @@ vtysh_config_from_file (struct vty *vty, FILE *fp) } } } - return CMD_SUCCESS; } /* We don't care about the point of the cursor when '?' is typed. */ diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index b7ad299e18..36128eed03 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -50,7 +50,7 @@ char *vtysh_prompt (void); void vtysh_config_write (void); -int vtysh_config_from_file (struct vty *, FILE *); +void vtysh_config_from_file (struct vty *, FILE *); int vtysh_mark_file(const char *filename); diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index b60b83120c..47886ea463 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -368,7 +368,6 @@ vtysh_config_dump (FILE *fp) static void vtysh_read_file (FILE *confp) { - int ret; struct vty *vty; vty = vty_new (); @@ -380,28 +379,12 @@ vtysh_read_file (FILE *confp) vtysh_execute_no_pager ("configure terminal"); /* Execute configuration file. */ - ret = vtysh_config_from_file (vty, confp); + vtysh_config_from_file (vty, confp); vtysh_execute_no_pager ("end"); vtysh_execute_no_pager ("disable"); vty_close (vty); - - if (ret != CMD_SUCCESS) - { - switch (ret) - { - case CMD_ERR_AMBIGUOUS: - fprintf (stderr, "Ambiguous command.\n"); - break; - case CMD_ERR_NO_MATCH: - fprintf (stderr, "There is no such command.\n"); - break; - } - fprintf (stderr, "Error occured during reading below line.\n%s\n", - vty->buf); - exit (1); - } } /* Read up configuration file from config_default_dir. */ -- 2.39.5