summaryrefslogtreecommitdiff
path: root/lib/yang.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2020-09-10 17:12:09 -0300
committerRenato Westphal <renato@opensourcerouting.org>2020-09-11 15:46:40 -0300
commit8a923b48513316bda9ab9868ebe4f9ff4865c8a9 (patch)
tree49aad94aa0ca0f857bbb3f580ad29c0c6b575b5c /lib/yang.c
parenta77bd0f4e6b7d63e6f66288d7ea715ae8c55feee (diff)
lib: better support for nested YANG augmentations
Change the way the YANG schema node iteration functions work so that the northbound layer won't have issues with more complex YANG modules that contain multiple levels of YANG augmentations or modules that augment themselves indirectly (by augmenting groupings). Summary of the changes: * Change the yang_snodes_iterate_subtree() function to always follow augmentations and add an optional "module" parameter to narrow down the iteration to nodes of a single module (which is necessary in some cases). Also, remove the YANG_ITER_ALLOW_AUGMENTATIONS flag as it's no longer necessary. * Change yang_snodes_iterate_all() to do a DFS iteration on the resolved YANG data hierarchy instead of iterating over each module and their augmentations sequentially. Reported-by: Rafael Zalamena <rzalamena@opensourcerouting.org> Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'lib/yang.c')
-rw-r--r--lib/yang.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/lib/yang.c b/lib/yang.c
index 9bfdcb858c..5bf7758e18 100644
--- a/lib/yang.c
+++ b/lib/yang.c
@@ -147,11 +147,15 @@ struct yang_module *yang_module_find(const char *module_name)
}
int yang_snodes_iterate_subtree(const struct lys_node *snode,
+ const struct lys_module *module,
yang_iterate_cb cb, uint16_t flags, void *arg)
{
struct lys_node *child;
int ret = YANG_ITER_CONTINUE;
+ if (module && snode->module != module)
+ goto next;
+
if (CHECK_FLAG(flags, YANG_ITER_FILTER_IMPLICIT)) {
switch (snode->nodetype) {
case LYS_CASE:
@@ -214,11 +218,8 @@ next:
return YANG_ITER_CONTINUE;
LY_TREE_FOR (snode->child, child) {
- if (!CHECK_FLAG(flags, YANG_ITER_ALLOW_AUGMENTATIONS)
- && child->parent != snode)
- continue;
-
- ret = yang_snodes_iterate_subtree(child, cb, flags, arg);
+ ret = yang_snodes_iterate_subtree(child, module, cb, flags,
+ arg);
if (ret == YANG_ITER_STOP)
return ret;
}
@@ -233,15 +234,16 @@ int yang_snodes_iterate_module(const struct lys_module *module,
int ret = YANG_ITER_CONTINUE;
LY_TREE_FOR (module->data, snode) {
- ret = yang_snodes_iterate_subtree(snode, cb, flags, arg);
+ ret = yang_snodes_iterate_subtree(snode, module, cb, flags,
+ arg);
if (ret == YANG_ITER_STOP)
return ret;
}
for (uint8_t i = 0; i < module->augment_size; i++) {
ret = yang_snodes_iterate_subtree(
- (const struct lys_node *)&module->augment[i], cb, flags,
- arg);
+ (const struct lys_node *)&module->augment[i], module,
+ cb, flags, arg);
if (ret == YANG_ITER_STOP)
return ret;
}
@@ -255,9 +257,14 @@ int yang_snodes_iterate_all(yang_iterate_cb cb, uint16_t flags, void *arg)
int ret = YANG_ITER_CONTINUE;
RB_FOREACH (module, yang_modules, &yang_modules) {
- ret = yang_snodes_iterate_module(module->info, cb, flags, arg);
- if (ret == YANG_ITER_STOP)
- return ret;
+ struct lys_node *snode;
+
+ LY_TREE_FOR (module->info->data, snode) {
+ ret = yang_snodes_iterate_subtree(snode, NULL, cb,
+ flags, arg);
+ if (ret == YANG_ITER_STOP)
+ return ret;
+ }
}
return ret;