]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: fix outdated candidate configuration issue
authorRenato Westphal <renato@opensourcerouting.org>
Mon, 27 May 2019 22:48:13 +0000 (19:48 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Wed, 12 Jun 2019 14:17:03 +0000 (11:17 -0300)
Even when using the classic CLI mode (i.e. when --tcli is not
used), the northbound code still uses vty->candidate_config
to perform configuration changes. From the perspective of the
user, the running configuration is being edited directly, but
under the hood the northbound layer does a full configuration
transaction for each command.  When the running configuration is
edited by a northbound client other than the CLI (e.g. kernel,
gRPC), vty->candidate_config might become outdated, and this can
lead to lots of weird problems. To fix this, always regenerate
vty->candidate_config before each configuration command when
using the classic CLI mode. When using the transactional CLI,
the user needs to update the candidate manually using the "update"
command, otherwise the "commit" command will fail with this error:
"% Candidate configuration needs to be updated before commit".

Fixes some problems reported by Don after moving an interface from
one VRF to another one while zebra is running.

Reported-by: Don Slice <dslice@cumulusnetworks.com>
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
lib/command.c
lib/vty.c

index e5e06231631c58beed7ca71f3b75cd270290e267..0e16f30a8a29f6ddfc27f287203aba3d98c84ce5 100644 (file)
@@ -1053,9 +1053,16 @@ static int cmd_execute_command_real(vector vline, enum cmd_filter_type filter,
        if (matched_element->daemon)
                ret = CMD_SUCCESS_DAEMON;
        else {
-               /* Clear enqueued configuration changes. */
-               vty->num_cfg_changes = 0;
-               memset(&vty->cfg_changes, 0, sizeof(vty->cfg_changes));
+               if (vty->config) {
+                       /* Clear array of enqueued configuration changes. */
+                       vty->num_cfg_changes = 0;
+                       memset(&vty->cfg_changes, 0, sizeof(vty->cfg_changes));
+
+                       /* Regenerate candidate configuration. */
+                       if (frr_get_cli_mode() == FRR_CLI_CLASSIC)
+                               nb_config_replace(vty->candidate_config,
+                                                 running_config, true);
+               }
 
                ret = matched_element->func(matched_element, vty, argc, argv);
        }
index e306e69b873c4f42e8558cdf9bd90f28207078be..d0605b49b457542d216201ac54a3598be9e9a439 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -2289,6 +2289,7 @@ static void vty_read_file(struct nb_config *config, FILE *confp)
        vty->wfd = STDERR_FILENO;
        vty->type = VTY_FILE;
        vty->node = CONFIG_NODE;
+       vty->config = true;
        if (config)
                vty->candidate_config = config;
        else {