Skip to content

Commit c6ae318

Browse files
committed
IGNORE THIS COMMIT: merge libyang3 step 6 (PR sonic-net#21789)
1 parent 6367551 commit c6ae318

File tree

3 files changed

+348
-2
lines changed

3 files changed

+348
-2
lines changed

rules/sonic-mgmt-common.mk

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
MGMT_COMMON_VERSION = 1.0.0
44
SONIC_MGMT_COMMON = sonic-mgmt-common_$(MGMT_COMMON_VERSION)_$(CONFIGURED_ARCH).deb
55
$(SONIC_MGMT_COMMON)_SRC_PATH = $(SRC_PATH)/sonic-mgmt-common
6-
$(SONIC_MGMT_COMMON)_DEPENDS = $(LIBYANG_DEV) $(LIBYANG) $(LIBYANG3)
7-
$(SONIC_MGMT_COMMON)_RDEPENDS = $(LIBYANG) $(LIBYANG3)
6+
$(SONIC_MGMT_COMMON)_DEPENDS = $(LIBYANG3_DEV) $(LIBYANG3)
7+
$(SONIC_MGMT_COMMON)_RDEPENDS = $(LIBYANG3)
88
$(SONIC_MGMT_COMMON)_WHEEL_DEPENDS = $(SONIC_YANG_MODELS_PY3)
99
SONIC_DPKG_DEBS += $(SONIC_MGMT_COMMON)
1010

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
From cfc94cc0d66524f453ccd781e9d252e8fc3ae711 Mon Sep 17 00:00:00 2001
2+
From: Brad House <brad@brad-house.com>
3+
Date: Sun, 23 Feb 2025 12:25:04 -0500
4+
Subject: [PATCH] validation: Add LYD_VALIDATE_NOEXTDEPS to bypass
5+
leafref/when/must
6+
7+
In libyang v1, there was an LYD_OPT_NOEXTDEPS flag. This was
8+
removed, and this patch re-adds a flag with similar functionality.
9+
---
10+
src/parser_data.h | 3 +-
11+
src/validation.c | 85 ++++++++++++++++++++++++++---------------------
12+
2 files changed, 49 insertions(+), 39 deletions(-)
13+
14+
diff --git a/src/parser_data.h b/src/parser_data.h
15+
index ddb22781e..292eda86f 100644
16+
--- a/src/parser_data.h
17+
+++ b/src/parser_data.h
18+
@@ -222,7 +222,8 @@ struct ly_in;
19+
#define LYD_VALIDATE_NOT_FINAL 0x0020 /**< Skip final validation tasks that require for all the data nodes to
20+
either exist or not, based on the YANG constraints. Once the data
21+
satisfy this requirement, the final validation should be performed. */
22+
-
23+
+#define LYD_VALIDATE_NOEXTDEPS 0x0040 /**< Allow external dependencies (external leafrefs, instance-identifiers,
24+
+ must, and when) to not be resolved/satisfied during validation. */
25+
#define LYD_VALIDATE_OPTS_MASK 0x0000FFFF /**< Mask for all the LYD_VALIDATE_* options. */
26+
27+
/** @} datavalidationoptions */
28+
diff --git a/src/validation.c b/src/validation.c
29+
index a436816fe..ac1822ae9 100644
30+
--- a/src/validation.c
31+
+++ b/src/validation.c
32+
@@ -41,18 +41,22 @@
33+
#include "xpath.h"
34+
35+
/**
36+
- * @brief Check validation error taking into account multi-error validation.
37+
+ * @brief Check validation error taking into account multi-error validation and
38+
+ * possible skipping of external dependency validation.
39+
*
40+
* @param[in] r Local return value.
41+
* @param[in] err_cmd Command to perform on any error.
42+
+ * @param[in] err_item Optional, may be NULL. Full error to evaluate.
43+
* @param[in] val_opts Validation options.
44+
* @param[in] label Label to go to on fatal error.
45+
*/
46+
-#define LY_VAL_ERR_GOTO(r, err_cmd, val_opts, label) \
47+
+#define LY_VAL_ERR_GOTO(r, err_cmd, err_item, val_opts, label) \
48+
if (r) { \
49+
- err_cmd; \
50+
- if ((r != LY_EVALID) || !(val_opts & LYD_VALIDATE_MULTI_ERROR)) { \
51+
- goto label; \
52+
+ if (!(val_opts & LYD_VALIDATE_NOEXTDEPS) || (r != LY_EVALID) || ((err_item) == NULL) || ((err_item)->apptag == NULL) || (strcmp((err_item)->apptag, "instance-required") != 0)) { \
53+
+ err_cmd; \
54+
+ if ((r != LY_EVALID) || !(val_opts & LYD_VALIDATE_MULTI_ERROR)) { \
55+
+ goto label; \
56+
+ } \
57+
} \
58+
}
59+
60+
@@ -412,7 +416,7 @@ lyd_validate_unres_when(struct lyd_node **tree, const struct lys_module *mod, st
61+
/* invalid data */
62+
LOGVAL(LYD_CTX(node), LY_VCODE_NOWHEN, disabled->cond->expr);
63+
r = LY_EVALID;
64+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, error);
65+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(node)), val_opts, error);
66+
}
67+
} else {
68+
/* when true */
69+
@@ -423,7 +427,7 @@ lyd_validate_unres_when(struct lyd_node **tree, const struct lys_module *mod, st
70+
ly_set_rm_index_ordered(node_when, i, NULL);
71+
} else if (r != LY_EINCOMPLETE) {
72+
/* error */
73+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, error);
74+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(node)), val_opts, error);
75+
}
76+
77+
LOG_LOCBACK(1, 1);
78+
@@ -454,7 +458,7 @@ lyd_validate_unres(struct lyd_node **tree, const struct lys_module *mod, enum ly
79+
80+
/* validate extension data */
81+
r = ext_v->ext->def->plugin->validate(ext_v->ext, ext_v->sibling, *tree, data_type, val_opts, diff);
82+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
83+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(*tree)), val_opts, cleanup);
84+
85+
/* remove this item from the set */
86+
ly_set_rm_index(ext_val, i, free);
87+
@@ -471,21 +475,21 @@ lyd_validate_unres(struct lyd_node **tree, const struct lys_module *mod, enum ly
88+
89+
/* validate the node */
90+
r = ext_n->ext->def->plugin->node(ext_n->ext, ext_n->node, val_opts);
91+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
92+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(*tree)), val_opts, cleanup);
93+
94+
/* remove this item from the set */
95+
ly_set_rm_index(ext_node, i, free);
96+
} while (i);
97+
}
98+
99+
- if (node_when) {
100+
+ if (node_when && !(val_opts & LYD_VALIDATE_NOEXTDEPS)) {
101+
/* evaluate all when conditions */
102+
uint32_t prev_count;
103+
104+
do {
105+
prev_count = node_when->count;
106+
r = lyd_validate_unres_when(tree, mod, node_when, val_opts, when_xp_opts, node_types, diff);
107+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
108+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(*tree)), val_opts, cleanup);
109+
110+
/* there must have been some when conditions resolved */
111+
} while (prev_count > node_when->count);
112+
@@ -513,7 +517,7 @@ lyd_validate_unres(struct lyd_node **tree, const struct lys_module *mod, enum ly
113+
LOG_LOCSET(NULL, &node->node);
114+
r = lyd_value_validate_incomplete(LYD_CTX(node), type, &node->value, &node->node, *tree);
115+
LOG_LOCBACK(0, 1);
116+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
117+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(node)), val_opts, cleanup);
118+
119+
/* remove this node from the set */
120+
ly_set_rm_index(node_types, i, NULL);
121+
@@ -532,7 +536,7 @@ lyd_validate_unres(struct lyd_node **tree, const struct lys_module *mod, enum ly
122+
/* validate and store the value of the metadata */
123+
lyplg_ext_get_storage(meta->annotation, LY_STMT_TYPE, sizeof type, (const void **)&type);
124+
r = lyd_value_validate_incomplete(LYD_CTX(meta->parent), type, &meta->value, meta->parent, *tree);
125+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
126+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(meta->parent)), val_opts, cleanup);
127+
128+
/* remove this attr from the set */
129+
ly_set_rm_index(meta_types, i, NULL);
130+
@@ -926,11 +930,11 @@ lyd_validate_choice_r(struct lyd_node **first, const struct lysc_node *sparent,
131+
for (i = 0; *first && choices[i]; ++i) {
132+
/* check case duplicites */
133+
r = lyd_validate_cases(first, mod, (struct lysc_node_choice *)choices[i], diff);
134+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
135+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(*first)), val_opts, cleanup);
136+
137+
/* check for nested choice */
138+
r = lyd_validate_choice_r(first, choices[i], mod, ext, val_opts, int_opts, getnext_ht, diff);
139+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
140+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(*first)), val_opts, cleanup);
141+
}
142+
143+
cleanup:
144+
@@ -950,7 +954,7 @@ lyd_validate_new(struct lyd_node **first, const struct lysc_node *sparent, const
145+
146+
/* validate choices */
147+
r = lyd_validate_choice_r(first, sparent, mod, ext, val_opts, int_opts, getnext_ht, diff);
148+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
149+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(*first)), val_opts, cleanup);
150+
151+
node = *first;
152+
while (node) {
153+
@@ -982,7 +986,7 @@ lyd_validate_new(struct lyd_node **first, const struct lysc_node *sparent, const
154+
if (node->flags & LYD_NEW) {
155+
/* then check new node instance duplicities */
156+
r = lyd_validate_duplicates(*first, node, val_opts);
157+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
158+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(*first)), val_opts, cleanup);
159+
160+
/* this node is valid */
161+
node->flags &= ~LYD_NEW;
162+
@@ -1100,7 +1104,7 @@ lyd_validate_mandatory(const struct lyd_node *first, const struct lyd_node *pare
163+
}
164+
165+
disabled = NULL;
166+
- if (lysc_has_when(snode)) {
167+
+ if (lysc_has_when(snode) && !(val_opts & LYD_VALIDATE_NOEXTDEPS)) {
168+
/* if there are any when conditions, they must be true for a validation error */
169+
LY_CHECK_RET(lyd_validate_dummy_when(first, parent, snode, &disabled));
170+
}
171+
@@ -1177,7 +1181,7 @@ lyd_validate_minmax(const struct lyd_node *first, const struct lyd_node *parent,
172+
assert(count < min);
173+
174+
disabled = NULL;
175+
- if (lysc_has_when(snode)) {
176+
+ if (lysc_has_when(snode) && !(val_opts & LYD_VALIDATE_NOEXTDEPS)) {
177+
/* if there are any when conditions, they must be true for a validation error */
178+
LY_CHECK_RET(lyd_validate_dummy_when(first, parent, snode, &disabled));
179+
}
180+
@@ -1553,7 +1557,7 @@ lyd_validate_siblings_schema_r(const struct lyd_node *first, const struct lyd_no
181+
if (snode->flags & LYS_MAND_TRUE) {
182+
/* check generic mandatory existence */
183+
r = lyd_validate_mandatory(first, parent, snode, val_opts);
184+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
185+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(first)), val_opts, cleanup);
186+
}
187+
188+
/* find the existing case, if any */
189+
@@ -1561,7 +1565,7 @@ lyd_validate_siblings_schema_r(const struct lyd_node *first, const struct lyd_no
190+
if (lys_getnext_data(NULL, first, NULL, scase, NULL)) {
191+
/* validate only this case */
192+
r = lyd_validate_siblings_schema_r(first, parent, scase, mod, ext, val_opts, int_opts, getnext_ht);
193+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
194+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(first)), val_opts, cleanup);
195+
break;
196+
}
197+
}
198+
@@ -1580,25 +1584,25 @@ lyd_validate_siblings_schema_r(const struct lyd_node *first, const struct lyd_no
199+
slist = (struct lysc_node_list *)snode;
200+
if (slist->min || (slist->max < UINT32_MAX)) {
201+
r = lyd_validate_minmax(first, parent, snode, slist->min, slist->max, val_opts);
202+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
203+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(first)), val_opts, cleanup);
204+
}
205+
206+
/* check unique */
207+
if (slist->uniques) {
208+
r = lyd_validate_unique(first, snode, (const struct lysc_node_leaf ***)slist->uniques, val_opts);
209+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
210+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(first)), val_opts, cleanup);
211+
}
212+
} else if (snode->nodetype == LYS_LEAFLIST) {
213+
sllist = (struct lysc_node_leaflist *)snode;
214+
if (sllist->min || (sllist->max < UINT32_MAX)) {
215+
r = lyd_validate_minmax(first, parent, snode, sllist->min, sllist->max, val_opts);
216+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
217+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(first)), val_opts, cleanup);
218+
}
219+
220+
} else if (snode->flags & LYS_MAND_TRUE) {
221+
/* check generic mandatory existence */
222+
r = lyd_validate_mandatory(first, parent, snode, val_opts);
223+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
224+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(first)), val_opts, cleanup);
225+
}
226+
}
227+
228+
@@ -1649,6 +1653,11 @@ lyd_validate_must(const struct lyd_node *node, uint32_t val_opts, uint32_t int_o
229+
const char *emsg, *eapptag;
230+
LY_ARRAY_COUNT_TYPE u;
231+
232+
+ /* Must validation has been bypassed */
233+
+ if (val_opts & LYD_VALIDATE_NOEXTDEPS) {
234+
+ return LY_SUCCESS;
235+
+ }
236+
+
237+
assert((int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_REPLY)) != (LYD_INTOPT_RPC | LYD_INTOPT_REPLY));
238+
assert((int_opts & (LYD_INTOPT_ACTION | LYD_INTOPT_REPLY)) != (LYD_INTOPT_ACTION | LYD_INTOPT_REPLY));
239+
240+
@@ -1710,7 +1719,7 @@ lyd_validate_must(const struct lyd_node *node, uint32_t val_opts, uint32_t int_o
241+
}
242+
LOG_LOCBACK(0, 1);
243+
r = LY_EVALID;
244+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
245+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(node)), val_opts, cleanup);
246+
}
247+
}
248+
}
249+
@@ -1794,12 +1803,12 @@ lyd_validate_final_r(struct lyd_node *first, const struct lyd_node *parent, cons
250+
/* node value was checked by plugins */
251+
252+
next_iter:
253+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
254+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(node)), val_opts, cleanup);
255+
}
256+
257+
/* validate schema-based restrictions */
258+
r = lyd_validate_siblings_schema_r(first, parent, sparent, mod, ext, val_opts, int_opts, getnext_ht);
259+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
260+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(first)), val_opts, cleanup);
261+
262+
LY_LIST_FOR(first, node) {
263+
if (!node->schema || (!node->parent && mod && (lyd_owner_module(node) != mod))) {
264+
@@ -1810,7 +1819,7 @@ lyd_validate_final_r(struct lyd_node *first, const struct lyd_node *parent, cons
265+
/* validate all children recursively */
266+
r = lyd_validate_final_r(lyd_child(node), node, node->schema, NULL, NULL, val_opts, int_opts, must_xp_opts,
267+
getnext_ht);
268+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
269+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(node)), val_opts, cleanup);
270+
271+
/* set default for containers */
272+
lyd_np_cont_dflt_set(node);
273+
@@ -1947,7 +1956,7 @@ lyd_validate_subtree(struct lyd_node *root, struct ly_set *node_when, struct ly_
274+
} else if (node->schema->nodetype & LYD_NODE_INNER) {
275+
/* new node validation, autodelete */
276+
r = lyd_validate_new(lyd_node_child_p(node), node->schema, NULL, NULL, val_opts, int_opts, getnext_ht, diff);
277+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
278+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(root)), val_opts, cleanup);
279+
280+
/* add nested defaults */
281+
impl_opts = 0;
282+
@@ -2027,7 +2036,7 @@ lyd_validate(struct lyd_node **tree, const struct lys_module *module, const stru
283+
/* validate new top-level nodes of this module, autodelete */
284+
r = lyd_validate_new(first2, *first2 ? lysc_data_parent((*first2)->schema) : NULL, mod, NULL, val_opts, 0,
285+
getnext_ht, diff);
286+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
287+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(ctx), val_opts, cleanup);
288+
289+
/* add all top-level defaults for this module, if going to validate subtree, do not add into unres sets
290+
* (lyd_validate_subtree() adds all the nodes in that case) */
291+
@@ -2066,19 +2075,19 @@ lyd_validate(struct lyd_node **tree, const struct lys_module *module, const stru
292+
293+
r = lyd_validate_subtree(iter, node_when_p, node_types_p, meta_types_p, ext_node_p, ext_val_p,
294+
val_opts, 0, getnext_ht, diff);
295+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
296+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(ctx), val_opts, cleanup);
297+
}
298+
}
299+
300+
/* finish incompletely validated terminal values/attributes and when conditions */
301+
r = lyd_validate_unres(first2, mod, LYD_TYPE_DATA_YANG, node_when_p, 0, node_types_p, meta_types_p,
302+
ext_node_p, ext_val_p, val_opts, diff);
303+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
304+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(ctx), val_opts, cleanup);
305+
306+
if (!(val_opts & LYD_VALIDATE_NOT_FINAL)) {
307+
/* perform final validation that assumes the data tree is final */
308+
r = lyd_validate_final_r(*first2, NULL, NULL, mod, NULL, val_opts, 0, 0, getnext_ht);
309+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
310+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(ctx), val_opts, cleanup);
311+
}
312+
313+
/* free the getnext hash table */
314+
@@ -2127,19 +2136,19 @@ lyd_validate_ext(struct lyd_node **tree, const struct lysc_ext_instance *ext, ui
315+
LY_LIST_FOR(*tree, iter) {
316+
r = lyd_validate_subtree(iter, node_when_p, node_types_p, meta_types_p, ext_node_p, ext_val_p,
317+
val_opts, 0, getnext_ht, diff);
318+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
319+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(iter)), val_opts, cleanup);
320+
}
321+
}
322+
323+
/* finish incompletely validated terminal values/attributes and when conditions */
324+
r = lyd_validate_unres(tree, NULL, LYD_TYPE_DATA_YANG, node_when_p, 0, node_types_p, meta_types_p,
325+
ext_node_p, ext_val_p, val_opts, diff);
326+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
327+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(*tree)), val_opts, cleanup);
328+
329+
if (!(val_opts & LYD_VALIDATE_NOT_FINAL)) {
330+
/* perform final validation that assumes the data tree is final */
331+
r = lyd_validate_final_r(*tree, NULL, NULL, NULL, ext, val_opts, 0, 0, getnext_ht);
332+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
333+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(*tree)), val_opts, cleanup);
334+
}
335+
336+
cleanup:
337+
@@ -2201,7 +2210,7 @@ lyd_validate_module_final(struct lyd_node *tree, const struct lys_module *module
338+
339+
/* perform final validation that assumes the data tree is final */
340+
r = lyd_validate_final_r(first, NULL, NULL, mod, NULL, val_opts, 0, 0, getnext_ht);
341+
- LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
342+
+ LY_VAL_ERR_GOTO(r, rc = r, ly_err_last(LYD_CTX(tree)), val_opts, cleanup);
343+
344+
cleanup:
345+
lyd_val_getnext_ht_free(getnext_ht);

src/libyang3/patch/series

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
0004-union-apptag-529a594.patch
55
0005-pr2360-validate-union-errors.patch
66
0006-pr2361-union-sort-assert.patch
7+
0007-pr2362-lyd_validate_noextdeps.patch

0 commit comments

Comments
 (0)