summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2019-05-28 00:48:13 +0200
committerRenato Westphal <renato@opensourcerouting.org>2019-06-12 16:17:03 +0200
commiteaf6705d7a9fdcfd48c8fb51fc4fe7cffd7701f2 (patch)
treed07d16528c109b8268384e4709e2228a5a12d5da
parentMerge pull request #4498 from ak503/ldpd (diff)
downloadfrr-eaf6705d7a9fdcfd48c8fb51fc4fe7cffd7701f2.tar.xz
frr-eaf6705d7a9fdcfd48c8fb51fc4fe7cffd7701f2.zip
lib: fix outdated candidate configuration issue
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>
-rw-r--r--lib/command.c13
-rw-r--r--lib/vty.c1
2 files changed, 11 insertions, 3 deletions
diff --git a/lib/command.c b/lib/command.c
index e5e062316..0e16f30a8 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -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);
}
diff --git a/lib/vty.c b/lib/vty.c
index e306e69b8..d0605b49b 100644
--- 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 {