diff options
Diffstat (limited to 'lib/yang.c')
| -rw-r--r-- | lib/yang.c | 110 |
1 files changed, 64 insertions, 46 deletions
diff --git a/lib/yang.c b/lib/yang.c index 757982d367..462e693549 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -71,6 +71,11 @@ static const char *yang_module_imp_clb(const char *mod_name, return NULL; } +static const char * const frr_native_modules[] = { + "frr-interface", + "frr-ripd", +}; + /* Generate the yang_modules tree. */ static inline int yang_module_compare(const struct yang_module *a, const struct yang_module *b) @@ -108,6 +113,12 @@ struct yang_module *yang_module_load(const char *module_name) return module; } +void yang_module_load_all(void) +{ + for (size_t i = 0; i < array_size(frr_native_modules); i++) + yang_module_load(frr_native_modules[i]); +} + struct yang_module *yang_module_find(const char *module_name) { struct yang_module s; @@ -116,23 +127,18 @@ struct yang_module *yang_module_find(const char *module_name) return RB_FIND(yang_modules, &yang_modules, &s); } -/* - * Helper function for yang_module_snodes_iterate() and - * yang_all_snodes_iterate(). This is a recursive function. - */ -static void yang_snodes_iterate(const struct lys_node *snode, - void (*func)(const struct lys_node *, void *, - void *), - uint16_t flags, void *arg1, void *arg2) +int yang_snodes_iterate_subtree(const struct lys_node *snode, + yang_iterate_cb cb, uint16_t flags, void *arg) { struct lys_node *child; + int ret = YANG_ITER_CONTINUE; if (CHECK_FLAG(flags, YANG_ITER_FILTER_IMPLICIT)) { switch (snode->nodetype) { case LYS_CASE: case LYS_INPUT: case LYS_OUTPUT: - if (snode->flags & LYS_IMPLICIT) + if (CHECK_FLAG(snode->flags, LYS_IMPLICIT)) goto next; break; default: @@ -162,7 +168,7 @@ static void yang_snodes_iterate(const struct lys_node *snode, break; case LYS_GROUPING: /* Return since we're not interested in the grouping subtree. */ - return; + return YANG_ITER_CONTINUE; case LYS_USES: case LYS_AUGMENT: /* Always ignore nodes of these types. */ @@ -176,50 +182,66 @@ static void yang_snodes_iterate(const struct lys_node *snode, break; } - (*func)(snode, arg1, arg2); + ret = (*cb)(snode, arg); + if (ret == YANG_ITER_STOP) + return ret; next: /* * YANG leafs and leaf-lists can't have child nodes, and trying to * access snode->child is undefined behavior. */ - if (snode->nodetype & (LYS_LEAF | LYS_LEAFLIST)) - return; + if (CHECK_FLAG(snode->nodetype, LYS_LEAF | LYS_LEAFLIST)) + return YANG_ITER_CONTINUE; LY_TREE_FOR (snode->child, child) { - if (child->parent != snode) + if (!CHECK_FLAG(flags, YANG_ITER_ALLOW_AUGMENTATIONS) + && child->parent != snode) continue; - yang_snodes_iterate(child, func, flags, arg1, arg2); + + ret = yang_snodes_iterate_subtree(child, cb, flags, arg); + if (ret == YANG_ITER_STOP) + return ret; } + + return ret; } -void yang_module_snodes_iterate(const struct lys_module *module, - void (*func)(const struct lys_node *, void *, - void *), - uint16_t flags, void *arg1, void *arg2) +int yang_snodes_iterate_module(const struct lys_module *module, + yang_iterate_cb cb, uint16_t flags, void *arg) { struct lys_node *snode; + int ret = YANG_ITER_CONTINUE; LY_TREE_FOR (module->data, snode) { - yang_snodes_iterate(snode, func, flags, arg1, arg2); + ret = yang_snodes_iterate_subtree(snode, cb, flags, arg); + if (ret == YANG_ITER_STOP) + return ret; } for (uint8_t i = 0; i < module->augment_size; i++) { - yang_snodes_iterate( - (const struct lys_node *)&module->augment[i], func, - flags, arg1, arg2); + ret = yang_snodes_iterate_subtree( + (const struct lys_node *)&module->augment[i], cb, flags, + arg); + if (ret == YANG_ITER_STOP) + return ret; } + + return ret; } -void yang_all_snodes_iterate(void (*func)(const struct lys_node *, void *, - void *), - uint16_t flags, void *arg1, void *arg2) +int yang_snodes_iterate_all(yang_iterate_cb cb, uint16_t flags, void *arg) { struct yang_module *module; + int ret = YANG_ITER_CONTINUE; - RB_FOREACH (module, yang_modules, &yang_modules) - yang_module_snodes_iterate(module->info, func, flags, arg1, - arg2); + RB_FOREACH (module, yang_modules, &yang_modules) { + ret = yang_snodes_iterate_module(module->info, cb, flags, arg); + if (ret == YANG_ITER_STOP) + return ret; + } + + return ret; } void yang_snode_get_path(const struct lys_node *snode, enum yang_path_type type, @@ -324,7 +346,7 @@ const struct lys_type *yang_snode_get_type(const struct lys_node *snode) struct lys_node_leaf *sleaf = (struct lys_node_leaf *)snode; struct lys_type *type; - if (!(sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST))) + if (!CHECK_FLAG(sleaf->nodetype, LYS_LEAF | LYS_LEAFLIST)) return NULL; type = &sleaf->type; @@ -463,7 +485,7 @@ bool yang_dnode_is_default_recursive(const struct lyd_node *dnode) struct lyd_node *root, *next, *dnode_iter; snode = dnode->schema; - if (snode->nodetype & (LYS_LEAF | LYS_LEAFLIST)) + if (CHECK_FLAG(snode->nodetype, LYS_LEAF | LYS_LEAFLIST)) return yang_dnode_is_default(dnode, NULL); if (!yang_dnode_is_default(dnode, NULL)) @@ -489,7 +511,7 @@ void yang_dnode_change_leaf(struct lyd_node *dnode, const char *value) void yang_dnode_set_entry(const struct lyd_node *dnode, void *entry) { - assert(dnode->schema->nodetype & (LYS_LIST | LYS_CONTAINER)); + assert(CHECK_FLAG(dnode->schema->nodetype, LYS_LIST | LYS_CONTAINER)); lyd_set_private(dnode, entry); } @@ -523,12 +545,18 @@ void *yang_dnode_get_entry(const struct lyd_node *dnode, abort(); } -struct lyd_node *yang_dnode_new(struct ly_ctx *ly_ctx) +struct lyd_node *yang_dnode_new(struct ly_ctx *ly_ctx, bool config_only) { struct lyd_node *dnode; + int options; + + if (config_only) + options = LYD_OPT_CONFIG; + else + options = LYD_OPT_DATA | LYD_OPT_DATA_NO_YANGLIB; dnode = NULL; - if (lyd_validate(&dnode, LYD_OPT_CONFIG, ly_ctx) != 0) { + if (lyd_validate(&dnode, options, ly_ctx) != 0) { /* Should never happen. */ flog_err(EC_LIB_LIBYANG, "%s: lyd_validate() failed", __func__); exit(1); @@ -544,27 +572,17 @@ struct lyd_node *yang_dnode_dup(const struct lyd_node *dnode) void yang_dnode_free(struct lyd_node *dnode) { + while (dnode->parent) + dnode = dnode->parent; lyd_free_withsiblings(dnode); } struct yang_data *yang_data_new(const char *xpath, const char *value) { - const struct lys_node *snode; struct yang_data *data; - snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0); - if (!snode) - snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 1); - if (!snode) { - flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH, - "%s: unknown data path: %s", __func__, xpath); - zlog_backtrace(LOG_ERR); - abort(); - } - data = XCALLOC(MTYPE_YANG_DATA, sizeof(*data)); strlcpy(data->xpath, xpath, sizeof(data->xpath)); - data->snode = snode; if (value) data->value = strdup(value); |
