]> git.puffer.fish Git - mirror/frr.git/commitdiff
mgmtd: validate candidate yang tree before creating a config diff 14914/head
authorIgor Ryzhov <iryzhov@nfware.com>
Tue, 14 Nov 2023 19:17:24 +0000 (20:17 +0100)
committerIgor Ryzhov <iryzhov@nfware.com>
Thu, 30 Nov 2023 01:10:09 +0000 (03:10 +0200)
The candidate yang tree should be validated before `nb_config_diff` is
called. `nb_config_diff` ignores all prohibited operations and can
provide an empty change list because of this. For example, if a user
deletes a mandatory node from the candidate datastore and tries to make
a commit, they'll receive the "No changes found to be committed!" error,
because such a change is ignored by `nb_config_diff`. Instead, mgmtd
should tell the user that their candidate datastore is not valid and
can't be commited.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
mgmtd/mgmt_txn.c

index 53457e8969d5d7f93c364e5bc2225904dfca9c84..c2dca2aea18d3101e32ad42129cb39a866c4f1d3 100644 (file)
@@ -1034,6 +1034,23 @@ static int mgmt_txn_prepare_config(struct mgmt_txn_ctx *txn)
                goto mgmt_txn_prepare_config_done;
        }
 
+       /*
+        * Validate YANG contents of the source DS and get the diff
+        * between source and destination DS contents.
+        */
+       char err_buf[BUFSIZ] = { 0 };
+
+       ret = nb_candidate_validate_yang(nb_config, true, err_buf,
+                                        sizeof(err_buf) - 1);
+       if (ret != NB_OK) {
+               if (strncmp(err_buf, " ", strlen(err_buf)) == 0)
+                       strlcpy(err_buf, "Validation failed", sizeof(err_buf));
+               (void)mgmt_txn_send_commit_cfg_reply(txn, MGMTD_INVALID_PARAM,
+                                                    err_buf);
+               ret = -1;
+               goto mgmt_txn_prepare_config_done;
+       }
+
        nb_config_diff(mgmt_ds_get_nb_config(txn->commit_cfg_req->req.commit_cfg
                                             .dst_ds_ctx),
                       nb_config, &changes);
@@ -1056,29 +1073,13 @@ static int mgmt_txn_prepare_config(struct mgmt_txn_ctx *txn)
                gettimeofday(&txn->commit_cfg_req->req.commit_cfg.cmt_stats
                                      ->validate_start,
                             NULL);
-       /*
-        * Validate YANG contents of the source DS and get the diff
-        * between source and destination DS contents.
-        */
-       char err_buf[1024] = { 0 };
-       nb_ctx.client = NB_CLIENT_MGMTD_SERVER;
-       nb_ctx.user = (void *)txn;
-
-       ret = nb_candidate_validate_yang(nb_config, true, err_buf,
-                                        sizeof(err_buf) - 1);
-       if (ret != NB_OK) {
-               if (strncmp(err_buf, " ", strlen(err_buf)) == 0)
-                       strlcpy(err_buf, "Validation failed", sizeof(err_buf));
-               (void)mgmt_txn_send_commit_cfg_reply(txn, MGMTD_INVALID_PARAM,
-                                                    err_buf);
-               ret = -1;
-               goto mgmt_txn_prepare_config_done;
-       }
        /*
         * Perform application level validations locally on the MGMTD
         * process by calling application specific validation routines
         * loaded onto MGMTD process using libraries.
         */
+       nb_ctx.client = NB_CLIENT_MGMTD_SERVER;
+       nb_ctx.user = (void *)txn;
        ret = nb_candidate_validate_code(&nb_ctx, nb_config, &changes, err_buf,
                                         sizeof(err_buf) - 1);
        if (ret != NB_OK) {