Skip to content

Commit 6b14c7e

Browse files
committed
validation UPDATE means for proper per-module(s) validation
1 parent 1dcef13 commit 6b14c7e

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

src/parser_data.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,14 @@ struct ly_in;
203203
Also, no implicit state data are added. */
204204
#define LYD_VALIDATE_PRESENT 0x0002 /**< Validate only modules whose data actually exist. */
205205
#define LYD_VALIDATE_MULTI_ERROR 0x0004 /**< Do not stop validation on the first error but generate all the detected errors. */
206-
#define LYD_VALIDATE_OPERATIONAL 0x0008 /**< Semantic constraint violations are reported only as warnings instead
207-
of errors (see [RFC 8342 sec. 5.3](https://datatracker.ietf.org/doc/html/rfc8342#section-5.3)). */
206+
#define LYD_VALIDATE_OPERATIONAL 0x0008 /**< Semantic constraint violations are reported only as warnings instead of
207+
errors (see [RFC 8342 sec. 5.3](https://datatracker.ietf.org/doc/html/rfc8342#section-5.3)). */
208208
#define LYD_VALIDATE_NO_DEFAULTS 0x0010 /**< Do not add any default nodes during validation, other implicit nodes
209209
(such as NP containers) are still added. Validation will fail if a
210210
default node is required for it to pass. */
211+
#define LYD_VALIDATE_NOT_FINAL 0x0020 /**< Skip final validation tasks that require for all the data nodes to
212+
either exist or not, based on the YANG constraints. Once the data
213+
satisfy this requirement, the final validation should be performed. */
211214

212215
#define LYD_VALIDATE_OPTS_MASK 0x0000FFFF /**< Mask for all the LYD_VALIDATE_* options. */
213216

@@ -476,6 +479,10 @@ LIBYANG_API_DECL LY_ERR lyd_validate_all(struct lyd_node **tree, const struct ly
476479
* The data tree is modified in-place. As a result of the validation, some data might be removed
477480
* from the tree. In that case, the removed items are freed, not just unlinked.
478481
*
482+
* If several modules need to be validated, the flag ::LYD_VALIDATE_NOT_FINAL should be used first for validation
483+
* of each module and then ::lyd_validate_module_final() should be called also for each module. Otherwise,
484+
* false-positive validation errors for foreign dependencies may occur.
485+
*
479486
* @param[in,out] tree Data tree to recursively validate. May be changed by validation, might become NULL.
480487
* @param[in] module Module whose data (and schema restrictions) to validate.
481488
* @param[in] val_opts Validation options (@ref datavalidationoptions).
@@ -486,6 +493,20 @@ LIBYANG_API_DECL LY_ERR lyd_validate_all(struct lyd_node **tree, const struct ly
486493
LIBYANG_API_DECL LY_ERR lyd_validate_module(struct lyd_node **tree, const struct lys_module *module, uint32_t val_opts,
487494
struct lyd_node **diff);
488495

496+
/**
497+
* @brief Finish validation of a module data that have previously been validated with ::LYD_VALIDATE_NOT_FINAL flag.
498+
*
499+
* This final validation will not add or remove any nodes.
500+
*
501+
* @param[in] tree Data tree to recursively validate.
502+
* @param[in] module Module whose data (and schema restrictions) to validate.
503+
* @param[in] val_opts Validation options (@ref datavalidationoptions).
504+
* @return LY_SUCCESS on success.
505+
* @return LY_ERR error on error.
506+
*/
507+
LIBYANG_API_DECL LY_ERR lyd_validate_module_final(struct lyd_node *tree, const struct lys_module *module,
508+
uint32_t val_opts);
509+
489510
/**
490511
* @brief Validate an RPC/action request, reply, or notification. Only the operation data tree (input/output/notif)
491512
* is validate, any parents are ignored.

src/validation.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,9 +1877,11 @@ lyd_validate(struct lyd_node **tree, const struct lys_module *module, const stru
18771877
ext_node_p, ext_val_p, val_opts, diff);
18781878
LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
18791879

1880-
/* perform final validation that assumes the data tree is final */
1881-
r = lyd_validate_final_r(*first2, NULL, NULL, mod, val_opts, 0, 0);
1882-
LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
1880+
if (!(val_opts & LYD_VALIDATE_NOT_FINAL)) {
1881+
/* perform final validation that assumes the data tree is final */
1882+
r = lyd_validate_final_r(*first2, NULL, NULL, mod, val_opts, 0, 0);
1883+
LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
1884+
}
18831885
}
18841886

18851887
cleanup:
@@ -1909,14 +1911,36 @@ lyd_validate_all(struct lyd_node **tree, const struct ly_ctx *ctx, uint32_t val_
19091911
LIBYANG_API_DEF LY_ERR
19101912
lyd_validate_module(struct lyd_node **tree, const struct lys_module *module, uint32_t val_opts, struct lyd_node **diff)
19111913
{
1912-
LY_CHECK_ARG_RET(NULL, tree, *tree || module, LY_EINVAL);
1913-
LY_CHECK_CTX_EQUAL_RET(*tree ? LYD_CTX(*tree) : NULL, module ? module->ctx : NULL, LY_EINVAL);
1914+
LY_CHECK_ARG_RET(NULL, tree, module, !(val_opts & LYD_VALIDATE_PRESENT), LY_EINVAL);
1915+
LY_CHECK_CTX_EQUAL_RET(*tree ? LYD_CTX(*tree) : NULL, module->ctx, LY_EINVAL);
19141916
if (diff) {
19151917
*diff = NULL;
19161918
}
19171919

1918-
return lyd_validate(tree, module, (*tree) ? LYD_CTX(*tree) : module->ctx, val_opts, 1, NULL, NULL, NULL, NULL, NULL,
1919-
diff);
1920+
return lyd_validate(tree, module, module->ctx, val_opts, 1, NULL, NULL, NULL, NULL, NULL, diff);
1921+
}
1922+
1923+
LIBYANG_API_DEF LY_ERR
1924+
lyd_validate_module_final(struct lyd_node *tree, const struct lys_module *module, uint32_t val_opts)
1925+
{
1926+
LY_ERR r, rc = LY_SUCCESS;
1927+
struct lyd_node *first;
1928+
const struct lys_module *mod;
1929+
uint32_t i = 0;
1930+
1931+
LY_CHECK_ARG_RET(NULL, module, !(val_opts & (LYD_VALIDATE_PRESENT | LYD_VALIDATE_NOT_FINAL)), LY_EINVAL);
1932+
LY_CHECK_CTX_EQUAL_RET(LYD_CTX(tree), module->ctx, LY_EINVAL);
1933+
1934+
/* module is unchanged but we need to get the first module data node */
1935+
mod = lyd_mod_next_module(tree, module, module->ctx, &i, &first);
1936+
assert(mod);
1937+
1938+
/* perform final validation that assumes the data tree is final */
1939+
r = lyd_validate_final_r(first, NULL, NULL, mod, val_opts, 0, 0);
1940+
LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
1941+
1942+
cleanup:
1943+
return rc;
19201944
}
19211945

19221946
/**

0 commit comments

Comments
 (0)