Skip to content

Commit cc58719

Browse files
committed
plugins ext UPDATE use validate callback also for data nodes
Refs #2452
1 parent 8b34ed5 commit cc58719

File tree

10 files changed

+102
-21
lines changed

10 files changed

+102
-21
lines changed

src/parser_common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ lyd_parser_validate_new_implicit(struct lyd_ctx *lydctx, struct lyd_node *node)
466466

467467
/* add any missing default children */
468468
r = lyd_new_implicit_r(node, lyd_node_child_p(node), NULL, NULL, lydctx->ext, &lydctx->node_when, &lydctx->node_types,
469-
(lydctx->val_opts & LYD_VALIDATE_NO_STATE) ? LYD_IMPLICIT_NO_STATE : 0, lydctx->val_getnext_ht, NULL);
469+
&lydctx->ext_val, (lydctx->val_opts & LYD_VALIDATE_NO_STATE) ? LYD_IMPLICIT_NO_STATE : 0, lydctx->val_getnext_ht, NULL);
470470
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
471471

472472
cleanup:

src/parser_json.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,12 @@ lydjson_parse_instance(struct lyd_json_ctx *lydctx, struct lyd_node *parent, str
15401540
/* add/correct flags */
15411541
r = lyd_parser_set_data_flags(*node, &(*node)->meta, (struct lyd_ctx *)lydctx, ext);
15421542
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
1543+
1544+
if (!(lydctx->parse_opts & LYD_PARSE_ONLY)) {
1545+
/* store for ext instance node validation, if needed */
1546+
r = lyd_validate_node_ext(*node, &lydctx->ext_val);
1547+
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
1548+
}
15431549
} else if (r == LY_ENOT) {
15441550
/* parse it again as an opaq node */
15451551
r = lydjson_parse_opaq(lydctx, name, name_len, prefix, prefix_len, parent, status, status, first_p, node);

src/parser_lyb.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,11 @@ lyb_finish_node(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, uint32_t fl
936936
/* insert into parent */
937937
lyb_insert_node(lybctx, parent, *node, first_p, parsed);
938938

939+
if (!(lybctx->parse_opts & LYD_PARSE_ONLY)) {
940+
/* store for ext instance node validation, if needed */
941+
(void)lyd_validate_node_ext(*node, &lybctx->ext_val);
942+
}
943+
939944
*node = NULL;
940945
}
941946

src/parser_xml.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,12 @@ lydxml_subtree_r(struct lyd_xml_ctx *lydctx, struct lyd_node *parent, struct lyd
11111111
/* add/correct flags */
11121112
r = lyd_parser_set_data_flags(node, &meta, (struct lyd_ctx *)lydctx, ext);
11131113
LY_CHECK_ERR_GOTO(r, rc = r; lyd_free_tree(node), cleanup);
1114+
1115+
if (!(lydctx->parse_opts & LYD_PARSE_ONLY)) {
1116+
/* store for ext instance node validation, if needed */
1117+
r = lyd_validate_node_ext(node, &lydctx->ext_val);
1118+
LY_DPARSER_ERR_GOTO(r, rc = r, lydctx, cleanup);
1119+
}
11141120
}
11151121

11161122
/* parser next */

src/plugins_exts.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,10 +892,12 @@ typedef LY_ERR (*lyplg_ext_data_snode_clb)(struct lysc_ext_instance *ext, const
892892
/**
893893
* @brief Callback for validating parsed YANG instance data described by an extension instance.
894894
*
895-
* This callback is used only for nested data definition (with a standard YANG schema parent).
895+
* This callback is called both for nested data definition (with a standard YANG schema parent) when all @p sibling
896+
* nodes have ::LYD_EXT flag set and for data nodes of schema nodes with the extension instance (no special flag).
896897
*
897898
* @param[in] ext Compiled extension instance.
898-
* @param[in] sibling First sibling with schema node returned by ::lyplg_ext_data_snode_clb.
899+
* @param[in] sibling First sibling with schema node returned by ::lyplg_ext_data_snode_clb for nested data, otherwise
900+
* the data node with the extension instance.
899901
* @param[in] dep_tree Tree to be used for validating references from the operation subtree, if operation.
900902
* @param[in] data_type Validated data type, can be ::LYD_TYPE_DATA_YANG, ::LYD_TYPE_RPC_YANG, ::LYD_TYPE_NOTIF_YANG,
901903
* or ::LYD_TYPE_REPLY_YANG.

src/plugins_exts/schema_mount.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,11 @@ schema_mount_validate(struct lysc_ext_instance *ext, struct lyd_node *sibling, c
11751175
EXT_LOGERR_INT_RET(NULL, ext);
11761176
}
11771177

1178+
if (!(sibling->flags & LYD_EXT)) {
1179+
/* no validation of the node with the mount-point */
1180+
goto cleanup;
1181+
}
1182+
11781183
/* get operational data with ietf-yang-library and ietf-yang-schema-mount data */
11791184
if ((ret = lyplg_ext_get_data(ext->module->ctx, ext, lyd_parent(sibling), (void **)&ext_data, &ext_data_free))) {
11801185
goto cleanup;

src/tree_data_internal.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,16 @@ LY_ERR lyd_change_term_val(struct lyd_node *term, struct lyd_value *val, ly_bool
367367
* @param[in] top_ext Extension instance containing the definition of the data being created.
368368
* @param[in] node_when Optional set to add nodes with "when" conditions into.
369369
* @param[in] node_types Optional set to add nodes with unresolved types into.
370+
* @param[in] ext_val Optional set to add nodes with extension instances into.
370371
* @param[in] impl_opts Implicit options (@ref implicitoptions).
371372
* @param[in,out] getnext_ht Getnext HT to use, new @p sparent is added to it.
372373
* @param[in,out] diff Validation diff.
373374
* @return LY_ERR value.
374375
*/
375376
LY_ERR lyd_new_implicit(struct lyd_node *parent, struct lyd_node **first, const struct lysc_node *sparent,
376377
const struct lys_module *mod, const struct lysc_ext_instance *top_ext, struct ly_set *node_when,
377-
struct ly_set *node_types, uint32_t impl_opts, struct ly_ht *getnext_ht, struct lyd_node **diff);
378+
struct ly_set *node_types, struct ly_set *ext_val, uint32_t impl_opts, struct ly_ht *getnext_ht,
379+
struct lyd_node **diff);
378380

379381
/**
380382
* @brief Check the existence and create any non-existing implicit children, recursively for containers.
@@ -386,14 +388,16 @@ LY_ERR lyd_new_implicit(struct lyd_node *parent, struct lyd_node **first, const
386388
* @param[in] top_ext Extension instance containing the definition of the data being created.
387389
* @param[in] node_when Optional set to add nodes with "when" conditions into.
388390
* @param[in] node_types Optional set to add nodes with unresolved types into.
391+
* @param[in] ext_val Optional set to add nodes with extension instances into.
389392
* @param[in] impl_opts Implicit options (@ref implicitoptions).
390393
* @param[in,out] getnext_ht Getnext HT to use, new @p sparent is added to it.
391394
* @param[in,out] diff Validation diff.
392395
* @return LY_ERR value.
393396
*/
394397
LY_ERR lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struct lysc_node *sparent,
395398
const struct lys_module *mod, const struct lysc_ext_instance *top_ext, struct ly_set *node_when,
396-
struct ly_set *node_types, uint32_t impl_opts, struct ly_ht *getnext_ht, struct lyd_node **diff);
399+
struct ly_set *node_types, struct ly_set *ext_val, uint32_t impl_opts, struct ly_ht *getnext_ht,
400+
struct lyd_node **diff);
397401

398402
/**
399403
* @brief Find the next node, before which to insert the new node.

src/tree_data_new.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,7 +1920,8 @@ lyd_new_ext_path(struct lyd_node *parent, const struct lysc_ext_instance *ext, c
19201920
LY_ERR
19211921
lyd_new_implicit(struct lyd_node *parent, struct lyd_node **first, const struct lysc_node *sparent,
19221922
const struct lys_module *mod, const struct lysc_ext_instance *top_ext, struct ly_set *node_when,
1923-
struct ly_set *node_types, uint32_t impl_opts, struct ly_ht *getnext_ht, struct lyd_node **diff)
1923+
struct ly_set *node_types, struct ly_set *ext_val, uint32_t impl_opts, struct ly_ht *getnext_ht,
1924+
struct lyd_node **diff)
19241925
{
19251926
const struct lysc_node *snode, **choices, **snodes;
19261927
struct lyd_node *node = NULL;
@@ -1954,12 +1955,12 @@ lyd_new_implicit(struct lyd_node *parent, struct lyd_node **first, const struct
19541955
if (!node && ((struct lysc_node_choice *)snode)->dflt) {
19551956
/* create default case data */
19561957
LY_CHECK_RET(lyd_new_implicit(parent, first, &((struct lysc_node_choice *)snode)->dflt->node,
1957-
NULL, top_ext, node_when, node_types, impl_opts, getnext_ht, diff));
1958+
NULL, top_ext, node_when, node_types, ext_val, impl_opts, getnext_ht, diff));
19581959
} else if (node) {
19591960
/* create any default data in the existing case */
19601961
assert(node->schema->parent->nodetype == LYS_CASE);
19611962
LY_CHECK_RET(lyd_new_implicit(parent, first, node->schema->parent, NULL, top_ext, node_when, node_types,
1962-
impl_opts, getnext_ht, diff));
1963+
ext_val, impl_opts, getnext_ht, diff));
19631964
}
19641965
}
19651966

@@ -1987,6 +1988,10 @@ lyd_new_implicit(struct lyd_node *parent, struct lyd_node **first, const struct
19871988
/* remember to resolve when */
19881989
LY_CHECK_RET(ly_set_add(node_when, node, 1, NULL));
19891990
}
1991+
if (ext_val) {
1992+
/* store for ext instance node validation, if needed */
1993+
LY_CHECK_RET(lyd_validate_node_ext(node, ext_val));
1994+
}
19901995
if (diff) {
19911996
/* add into diff */
19921997
LY_CHECK_RET(lyd_val_diff_add(node, LYD_DIFF_OP_CREATE, diff));
@@ -2011,6 +2016,10 @@ lyd_new_implicit(struct lyd_node *parent, struct lyd_node **first, const struct
20112016
/* remember to resolve when */
20122017
LY_CHECK_RET(ly_set_add(node_when, node, 1, NULL));
20132018
}
2019+
if (ext_val) {
2020+
/* store for ext instance node validation, if needed */
2021+
LY_CHECK_RET(lyd_validate_node_ext(node, ext_val));
2022+
}
20142023
if (diff) {
20152024
/* add into diff */
20162025
LY_CHECK_RET(lyd_val_diff_add(node, LYD_DIFF_OP_CREATE, diff));
@@ -2036,6 +2045,10 @@ lyd_new_implicit(struct lyd_node *parent, struct lyd_node **first, const struct
20362045
/* remember to resolve when */
20372046
LY_CHECK_RET(ly_set_add(node_when, node, 1, NULL));
20382047
}
2048+
if (ext_val) {
2049+
/* store for ext instance node validation, if needed */
2050+
LY_CHECK_RET(lyd_validate_node_ext(node, ext_val));
2051+
}
20392052
if (diff) {
20402053
/* add into diff */
20412054
LY_CHECK_RET(lyd_val_diff_add(node, LYD_DIFF_OP_CREATE, diff));
@@ -2055,18 +2068,20 @@ lyd_new_implicit(struct lyd_node *parent, struct lyd_node **first, const struct
20552068
LY_ERR
20562069
lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struct lysc_node *sparent,
20572070
const struct lys_module *mod, const struct lysc_ext_instance *top_ext, struct ly_set *node_when,
2058-
struct ly_set *node_types, uint32_t impl_opts, struct ly_ht *getnext_ht, struct lyd_node **diff)
2071+
struct ly_set *node_types, struct ly_set *ext_val, uint32_t impl_opts, struct ly_ht *getnext_ht,
2072+
struct lyd_node **diff)
20592073
{
20602074
struct lyd_node *child;
20612075

20622076
/* parent children */
2063-
LY_CHECK_RET(lyd_new_implicit(parent, first, sparent, mod, top_ext, node_when, node_types, impl_opts, getnext_ht, diff));
2077+
LY_CHECK_RET(lyd_new_implicit(parent, first, sparent, mod, top_ext, node_when, node_types, ext_val, impl_opts,
2078+
getnext_ht, diff));
20642079

20652080
LY_LIST_FOR(parent ? lyd_child_no_keys(parent) : *first, child) {
20662081
/* recursively for all the containers */
20672082
if ((child->flags & LYD_DEFAULT) && (child->schema->nodetype == LYS_CONTAINER)) {
20682083
LY_CHECK_RET(lyd_new_implicit_r(child, lyd_node_child_p(child), NULL, mod, top_ext, node_when, node_types,
2069-
impl_opts, getnext_ht, diff));
2084+
ext_val, impl_opts, getnext_ht, diff));
20702085
}
20712086
}
20722087

@@ -2091,7 +2106,7 @@ lyd_new_implicit_tree(struct lyd_node *tree, uint32_t implicit_options, struct l
20912106

20922107
LYD_TREE_DFS_BEGIN(tree, node) {
20932108
if (node->schema && (node->schema->nodetype & LYD_NODE_INNER)) {
2094-
LY_CHECK_GOTO(rc = lyd_new_implicit(node, lyd_node_child_p(node), NULL, NULL, NULL, &node_when, NULL,
2109+
LY_CHECK_GOTO(rc = lyd_new_implicit(node, lyd_node_child_p(node), NULL, NULL, NULL, &node_when, NULL, NULL,
20952110
implicit_options, getnext_ht, diff), cleanup);
20962111
}
20972112

@@ -2171,7 +2186,7 @@ lyd_new_implicit_module(struct lyd_node **tree, const struct lys_module *module,
21712186
LY_CHECK_GOTO(rc = lyd_val_getnext_ht_new(&getnext_ht), cleanup);
21722187

21732188
/* add all top-level defaults for this module */
2174-
rc = lyd_new_implicit(NULL, tree, NULL, module, NULL, &node_when, NULL, implicit_options, getnext_ht, diff);
2189+
rc = lyd_new_implicit(NULL, tree, NULL, module, NULL, &node_when, NULL, NULL, implicit_options, getnext_ht, diff);
21752190
LY_CHECK_GOTO(rc, cleanup);
21762191

21772192
/* resolve when and remove any invalid defaults */

src/validation.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,6 +1896,31 @@ lyd_validate_nested_ext(struct lyd_node *sibling, struct ly_set *ext_val)
18961896
return LY_SUCCESS;
18971897
}
18981898

1899+
LY_ERR
1900+
lyd_validate_node_ext(struct lyd_node *node, struct ly_set *ext_val)
1901+
{
1902+
struct lyd_ctx_ext_val *ext_v;
1903+
struct lysc_ext_instance *exts;
1904+
struct lyplg_ext *ext_plg;
1905+
LY_ARRAY_COUNT_TYPE u;
1906+
1907+
/* try to find a relevant extension instance with validation callback */
1908+
exts = node->schema->exts;
1909+
LY_ARRAY_FOR(exts, u) {
1910+
ext_plg = LYSC_GET_EXT_PLG(exts[u].def->plugin_ref);
1911+
if (ext_plg && ext_plg->validate) {
1912+
/* store for validation */
1913+
ext_v = malloc(sizeof *ext_v);
1914+
LY_CHECK_ERR_RET(!ext_v, LOGMEM(LYD_CTX(node)), LY_EMEM);
1915+
ext_v->ext = &exts[u];
1916+
ext_v->sibling = node;
1917+
LY_CHECK_RET(ly_set_add(ext_val, ext_v, 1, NULL));
1918+
}
1919+
}
1920+
1921+
return LY_SUCCESS;
1922+
}
1923+
18991924
/**
19001925
* @brief Validate the whole data subtree.
19011926
*
@@ -1975,7 +2000,7 @@ lyd_validate_tree(struct lyd_node *root, const struct lysc_ext_instance *ext, st
19752000
if (val_opts & LYD_VALIDATE_NO_DEFAULTS) {
19762001
impl_opts |= LYD_IMPLICIT_NO_DEFAULTS;
19772002
}
1978-
r = lyd_new_implicit(node, lyd_node_child_p(node), NULL, NULL, ext, NULL, NULL, impl_opts, getnext_ht, diff);
2003+
r = lyd_new_implicit(node, lyd_node_child_p(node), NULL, NULL, ext, NULL, NULL, NULL, impl_opts, getnext_ht, diff);
19792004
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
19802005
}
19812006

@@ -1985,6 +2010,10 @@ lyd_validate_tree(struct lyd_node *root, const struct lysc_ext_instance *ext, st
19852010
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
19862011
}
19872012

2013+
/* store for ext instance node validation, if needed */
2014+
r = lyd_validate_node_ext(node, ext_val);
2015+
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
2016+
19882017
next_node:
19892018
LYD_TREE_DFS_END(root, node);
19902019
}
@@ -2058,12 +2087,12 @@ lyd_validate(struct lyd_node **tree, const struct lys_module *module, const stru
20582087
impl_opts |= LYD_IMPLICIT_NO_DEFAULTS;
20592088
}
20602089
if (validate_subtree) {
2061-
r = lyd_new_implicit(lyd_parent(*first2), first2, NULL, mod, NULL, NULL, NULL, impl_opts, getnext_ht, diff);
2090+
r = lyd_new_implicit(lyd_parent(*first2), first2, NULL, mod, NULL, NULL, NULL, NULL, impl_opts, getnext_ht, diff);
20622091
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
20632092
} else {
20642093
/* descendants will not be validated, create them all */
2065-
r = lyd_new_implicit_r(lyd_parent(*first2), first2, NULL, mod, NULL, node_when_p, node_types_p, impl_opts,
2066-
getnext_ht, diff);
2094+
r = lyd_new_implicit_r(lyd_parent(*first2), first2, NULL, mod, NULL, node_when_p, node_types_p, ext_val_p,
2095+
impl_opts, getnext_ht, diff);
20672096
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
20682097
}
20692098

@@ -2415,8 +2444,8 @@ _lyd_validate_op(struct lyd_node *op_tree, struct lyd_node *op_node, const struc
24152444
if (int_opts & LYD_INTOPT_REPLY) {
24162445
if (validate_subtree) {
24172446
/* add output children defaults */
2418-
rc = lyd_new_implicit(op_node, lyd_node_child_p(op_node), NULL, NULL, NULL, NULL, NULL, LYD_IMPLICIT_OUTPUT,
2419-
getnext_ht, diff);
2447+
rc = lyd_new_implicit(op_node, lyd_node_child_p(op_node), NULL, NULL, NULL, NULL, NULL, NULL,
2448+
LYD_IMPLICIT_OUTPUT, getnext_ht, diff);
24202449
LY_CHECK_GOTO(rc, cleanup);
24212450

24222451
/* skip validating the operation itself, go to children directly */
@@ -2428,7 +2457,7 @@ _lyd_validate_op(struct lyd_node *op_tree, struct lyd_node *op_node, const struc
24282457
} else {
24292458
/* add output children defaults and their descendants */
24302459
rc = lyd_new_implicit_r(op_node, lyd_node_child_p(op_node), NULL, NULL, NULL, node_when_p, node_types_p,
2431-
LYD_IMPLICIT_OUTPUT, getnext_ht, diff);
2460+
ext_val_p, LYD_IMPLICIT_OUTPUT, getnext_ht, diff);
24322461
LY_CHECK_GOTO(rc, cleanup);
24332462
}
24342463
} else {

src/validation.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @author Michal Vasko <[email protected]>
44
* @brief Validation routines.
55
*
6-
* Copyright (c) 2019 - 2022 CESNET, z.s.p.o.
6+
* Copyright (c) 2019 - 2025 CESNET, z.s.p.o.
77
*
88
* This source code is licensed under BSD 3-Clause License (the "License").
99
* You may not use this file except in compliance with the License.
@@ -122,6 +122,15 @@ LY_ERR lyd_validate_new(struct lyd_node **first, const struct lysc_node *sparent
122122
const struct lysc_ext_instance *ext, uint32_t val_opts, uint32_t int_opts, struct ly_ht *getnext_ht,
123123
struct lyd_node **diff);
124124

125+
/**
126+
* @brief Validate data node with an extension instance, if any, by storing it in its unres set.
127+
*
128+
* @param[in] node Node to check for an extension instance with a validate callback.
129+
* @param[in,out] ext_val Set with data nodes to validate.
130+
* @return LY_ERR value.
131+
*/
132+
LY_ERR lyd_validate_node_ext(struct lyd_node *node, struct ly_set *ext_val);
133+
125134
/**
126135
* @brief Validate a data tree.
127136
*

0 commit comments

Comments
 (0)