Skip to content

Commit

Permalink
mgmtd: validate candidate yang tree before creating a config diff
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
idryzhov committed Nov 30, 2023
1 parent 4aff978 commit c81776c
Showing 1 changed file with 19 additions and 18 deletions.
37 changes: 19 additions & 18 deletions mgmtd/mgmt_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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) {
Expand Down

0 comments on commit c81776c

Please sign in to comment.