]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/yang.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / yang.c
index 757982d36793d09dc4423b9c5394aa3294506561..71b41c35d8225a660650a573549b1c93617c12a2 100644 (file)
@@ -71,6 +71,13 @@ static const char *yang_module_imp_clb(const char *mod_name,
        return NULL;
 }
 
+static const char *const frr_native_modules[] = {
+       "frr-interface",
+       "frr-ripd",
+       "frr-ripngd",
+       "frr-isisd",
+};
+
 /* Generate the yang_modules tree. */
 static inline int yang_module_compare(const struct yang_module *a,
                                      const struct yang_module *b)
@@ -108,6 +115,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 +129,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 +170,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 +184,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 +348,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 +487,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 +513,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 +547,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 +574,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);