2 * Copyright (C) 2018 NetDEF, Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "lib_errors.h"
25 #include "yang_translator.h"
26 #include "northbound.h"
28 DEFINE_MTYPE_STATIC(LIB
, YANG_MODULE
, "YANG module");
29 DEFINE_MTYPE_STATIC(LIB
, YANG_DATA
, "YANG data structure");
31 /* libyang container. */
32 struct ly_ctx
*ly_native_ctx
;
34 static struct yang_module_embed
*embeds
, **embedupd
= &embeds
;
36 void yang_module_embed(struct yang_module_embed
*embed
)
40 embedupd
= &embed
->next
;
43 static LY_ERR
yang_module_imp_clb(const char *mod_name
, const char *mod_rev
,
44 const char *submod_name
,
45 const char *submod_rev
, void *user_data
,
47 const char **module_data
,
48 void (**free_module_data
)(void *, void *))
50 struct yang_module_embed
*e
;
52 if (!strcmp(mod_name
, "ietf-inet-types") ||
53 !strcmp(mod_name
, "ietf-yang-types"))
54 /* libyang has these built in, don't try finding them here */
57 for (e
= embeds
; e
; e
= e
->next
) {
58 if (e
->sub_mod_name
&& submod_name
) {
59 if (strcmp(e
->sub_mod_name
, submod_name
))
62 if (submod_rev
&& strcmp(e
->sub_mod_rev
, submod_rev
))
65 if (strcmp(e
->mod_name
, mod_name
))
68 if (mod_rev
&& strcmp(e
->mod_rev
, mod_rev
))
73 *module_data
= e
->data
;
77 /* We get here for indirect modules like ietf-inet-types */
79 "YANG model \"%s@%s\" \"%s@%s\"not embedded, trying external file",
80 mod_name
, mod_rev
? mod_rev
: "*",
81 submod_name
? submod_name
: "*", submod_rev
? submod_rev
: "*");
86 /* clang-format off */
87 static const char *const frr_native_modules
[] = {
101 /* clang-format on */
103 /* Generate the yang_modules tree. */
104 static inline int yang_module_compare(const struct yang_module
*a
,
105 const struct yang_module
*b
)
107 return strcmp(a
->name
, b
->name
);
109 RB_GENERATE(yang_modules
, yang_module
, entry
, yang_module_compare
)
111 struct yang_modules yang_modules
= RB_INITIALIZER(&yang_modules
);
113 struct yang_module
*yang_module_load(const char *module_name
)
115 struct yang_module
*module
;
116 const struct lys_module
*module_info
;
119 ly_ctx_load_module(ly_native_ctx
, module_name
, NULL
, NULL
);
121 flog_err(EC_LIB_YANG_MODULE_LOAD
,
122 "%s: failed to load data model: %s", __func__
,
127 module
= XCALLOC(MTYPE_YANG_MODULE
, sizeof(*module
));
128 module
->name
= module_name
;
129 module
->info
= module_info
;
131 if (RB_INSERT(yang_modules
, &yang_modules
, module
) != NULL
) {
132 flog_err(EC_LIB_YANG_MODULE_LOADED_ALREADY
,
133 "%s: YANG module is loaded already: %s", __func__
,
141 void yang_module_load_all(void)
143 for (size_t i
= 0; i
< array_size(frr_native_modules
); i
++)
144 yang_module_load(frr_native_modules
[i
]);
147 struct yang_module
*yang_module_find(const char *module_name
)
149 struct yang_module s
;
151 s
.name
= module_name
;
152 return RB_FIND(yang_modules
, &yang_modules
, &s
);
155 int yang_snodes_iterate_subtree(const struct lysc_node
*snode
,
156 const struct lys_module
*module
,
157 yang_iterate_cb cb
, uint16_t flags
, void *arg
)
159 const struct lysc_node
*child
;
160 int ret
= YANG_ITER_CONTINUE
;
162 if (module
&& snode
->module
!= module
)
165 switch (snode
->nodetype
) {
167 if (CHECK_FLAG(flags
, YANG_ITER_FILTER_NPCONTAINERS
)) {
168 if (!CHECK_FLAG(snode
->flags
, LYS_PRESENCE
))
173 if (CHECK_FLAG(flags
, YANG_ITER_FILTER_LIST_KEYS
)) {
174 /* Ignore list keys. */
175 if (lysc_is_key(snode
))
181 if (CHECK_FLAG(flags
, YANG_ITER_FILTER_INPUT_OUTPUT
))
185 assert(snode
->nodetype
!= LYS_AUGMENT
186 && snode
->nodetype
!= LYS_GROUPING
187 && snode
->nodetype
!= LYS_USES
);
191 ret
= (*cb
)(snode
, arg
);
192 if (ret
== YANG_ITER_STOP
)
197 * YANG leafs and leaf-lists can't have child nodes.
199 if (CHECK_FLAG(snode
->nodetype
, LYS_LEAF
| LYS_LEAFLIST
))
200 return YANG_ITER_CONTINUE
;
202 LY_LIST_FOR (lysc_node_child(snode
), child
) {
203 ret
= yang_snodes_iterate_subtree(child
, module
, cb
, flags
,
205 if (ret
== YANG_ITER_STOP
)
211 int yang_snodes_iterate(const struct lys_module
*module
, yang_iterate_cb cb
,
212 uint16_t flags
, void *arg
)
214 const struct lys_module
*module_iter
;
216 int ret
= YANG_ITER_CONTINUE
;
218 idx
= ly_ctx_internal_modules_count(ly_native_ctx
);
219 while ((module_iter
= ly_ctx_get_module_iter(ly_native_ctx
, &idx
))) {
220 struct lysc_node
*snode
;
222 if (!module_iter
->implemented
)
225 LY_LIST_FOR (module_iter
->compiled
->data
, snode
) {
226 ret
= yang_snodes_iterate_subtree(snode
, module
, cb
,
228 if (ret
== YANG_ITER_STOP
)
231 LY_LIST_FOR (&module_iter
->compiled
->rpcs
->node
, snode
) {
232 ret
= yang_snodes_iterate_subtree(snode
, module
, cb
,
234 if (ret
== YANG_ITER_STOP
)
237 LY_LIST_FOR (&module_iter
->compiled
->notifs
->node
, snode
) {
238 ret
= yang_snodes_iterate_subtree(snode
, module
, cb
,
240 if (ret
== YANG_ITER_STOP
)
248 void yang_snode_get_path(const struct lysc_node
*snode
,
249 enum yang_path_type type
, char *xpath
,
253 case YANG_PATH_SCHEMA
:
254 (void)lysc_path(snode
, LYSC_PATH_LOG
, xpath
, xpath_len
);
257 (void)lysc_path(snode
, LYSC_PATH_DATA
, xpath
, xpath_len
);
260 flog_err(EC_LIB_DEVELOPMENT
, "%s: unknown yang path type: %u",
266 struct lysc_node
*yang_snode_real_parent(const struct lysc_node
*snode
)
268 struct lysc_node
*parent
= snode
->parent
;
271 switch (parent
->nodetype
) {
273 if (CHECK_FLAG(parent
->flags
, LYS_PRESENCE
))
281 parent
= parent
->parent
;
287 struct lysc_node
*yang_snode_parent_list(const struct lysc_node
*snode
)
289 struct lysc_node
*parent
= snode
->parent
;
292 switch (parent
->nodetype
) {
298 parent
= parent
->parent
;
304 bool yang_snode_is_typeless_data(const struct lysc_node
*snode
)
306 const struct lysc_node_leaf
*sleaf
;
308 switch (snode
->nodetype
) {
310 sleaf
= (struct lysc_node_leaf
*)snode
;
311 if (sleaf
->type
->basetype
== LY_TYPE_EMPTY
)
321 const char *yang_snode_get_default(const struct lysc_node
*snode
)
323 const struct lysc_node_leaf
*sleaf
;
325 switch (snode
->nodetype
) {
327 sleaf
= (const struct lysc_node_leaf
*)snode
;
328 return sleaf
->dflt
? lyd_value_get_canonical(sleaf
->module
->ctx
,
332 /* TODO: check leaf-list default values */
339 const struct lysc_type
*yang_snode_get_type(const struct lysc_node
*snode
)
341 struct lysc_node_leaf
*sleaf
= (struct lysc_node_leaf
*)snode
;
342 struct lysc_type
*type
;
344 if (!CHECK_FLAG(sleaf
->nodetype
, LYS_LEAF
| LYS_LEAFLIST
))
348 while (type
->basetype
== LY_TYPE_LEAFREF
)
349 type
= ((struct lysc_type_leafref
*)type
)->realtype
;
354 unsigned int yang_snode_num_keys(const struct lysc_node
*snode
)
356 const struct lysc_node_leaf
*skey
;
359 if (!CHECK_FLAG(snode
->nodetype
, LYS_LIST
))
362 /* Walk list of children */
363 LY_FOR_KEYS (snode
, skey
) {
369 void yang_dnode_get_path(const struct lyd_node
*dnode
, char *xpath
,
372 lyd_path(dnode
, LYD_PATH_STD
, xpath
, xpath_len
);
375 const char *yang_dnode_get_schema_name(const struct lyd_node
*dnode
,
376 const char *xpath_fmt
, ...)
380 char xpath
[XPATH_MAXLEN
];
382 va_start(ap
, xpath_fmt
);
383 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
386 dnode
= yang_dnode_get(dnode
, xpath
);
388 flog_err(EC_LIB_YANG_DNODE_NOT_FOUND
,
389 "%s: couldn't find %s", __func__
, xpath
);
390 zlog_backtrace(LOG_ERR
);
395 return dnode
->schema
->name
;
398 struct lyd_node
*yang_dnode_get(const struct lyd_node
*dnode
, const char *xpath
)
400 struct ly_set
*set
= NULL
;
401 struct lyd_node
*dnode_ret
= NULL
;
404 * XXX a lot of the code uses this for style I guess. It shouldn't, as
405 * it adds to the xpath parsing complexity in libyang.
407 if (xpath
[0] == '.' && xpath
[1] == '/')
410 if (lyd_find_xpath(dnode
, xpath
, &set
)) {
411 assert(0); /* XXX replicates old libyang1 base code */
417 if (set
->count
> 1) {
418 flog_warn(EC_LIB_YANG_DNODE_NOT_FOUND
,
419 "%s: found %u elements (expected 0 or 1) [xpath %s]",
420 __func__
, set
->count
, xpath
);
424 dnode_ret
= set
->dnodes
[0];
427 ly_set_free(set
, NULL
);
432 struct lyd_node
*yang_dnode_getf(const struct lyd_node
*dnode
,
433 const char *xpath_fmt
, ...)
436 char xpath
[XPATH_MAXLEN
];
438 va_start(ap
, xpath_fmt
);
439 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
442 return yang_dnode_get(dnode
, xpath
);
445 bool yang_dnode_exists(const struct lyd_node
*dnode
, const char *xpath
)
447 struct ly_set
*set
= NULL
;
450 if (xpath
[0] == '.' && xpath
[1] == '/')
452 if (lyd_find_xpath(dnode
, xpath
, &set
))
454 exists
= set
->count
> 0;
455 ly_set_free(set
, NULL
);
459 bool yang_dnode_existsf(const struct lyd_node
*dnode
, const char *xpath_fmt
,
463 char xpath
[XPATH_MAXLEN
];
465 va_start(ap
, xpath_fmt
);
466 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
469 return yang_dnode_exists(dnode
, xpath
);
472 void yang_dnode_iterate(yang_dnode_iter_cb cb
, void *arg
,
473 const struct lyd_node
*dnode
, const char *xpath_fmt
,
477 char xpath
[XPATH_MAXLEN
];
480 va_start(ap
, xpath_fmt
);
481 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
484 if (lyd_find_xpath(dnode
, xpath
, &set
)) {
485 assert(0); /* XXX libyang2: ly1 code asserted success */
488 for (unsigned int i
= 0; i
< set
->count
; i
++) {
491 ret
= (*cb
)(set
->dnodes
[i
], arg
);
492 if (ret
== YANG_ITER_STOP
)
496 ly_set_free(set
, NULL
);
499 bool yang_dnode_is_default(const struct lyd_node
*dnode
, const char *xpath
)
501 const struct lysc_node
*snode
;
502 struct lysc_node_leaf
*sleaf
;
505 dnode
= yang_dnode_get(dnode
, xpath
);
508 snode
= dnode
->schema
;
509 switch (snode
->nodetype
) {
511 sleaf
= (struct lysc_node_leaf
*)snode
;
512 if (sleaf
->type
->basetype
== LY_TYPE_EMPTY
)
514 return lyd_is_default(dnode
);
516 /* TODO: check leaf-list default values */
519 if (CHECK_FLAG(snode
->flags
, LYS_PRESENCE
))
527 bool yang_dnode_is_defaultf(const struct lyd_node
*dnode
, const char *xpath_fmt
,
531 return yang_dnode_is_default(dnode
, NULL
);
534 char xpath
[XPATH_MAXLEN
];
536 va_start(ap
, xpath_fmt
);
537 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
540 return yang_dnode_is_default(dnode
, xpath
);
544 bool yang_dnode_is_default_recursive(const struct lyd_node
*dnode
)
546 struct lyd_node
*root
, *dnode_iter
;
548 if (!yang_dnode_is_default(dnode
, NULL
))
551 if (CHECK_FLAG(dnode
->schema
->nodetype
, LYS_LEAF
| LYS_LEAFLIST
))
554 LY_LIST_FOR (lyd_child(dnode
), root
) {
555 LYD_TREE_DFS_BEGIN (root
, dnode_iter
) {
556 if (!yang_dnode_is_default(dnode_iter
, NULL
))
559 LYD_TREE_DFS_END(root
, dnode_iter
);
566 void yang_dnode_change_leaf(struct lyd_node
*dnode
, const char *value
)
568 assert(dnode
->schema
->nodetype
== LYS_LEAF
);
569 lyd_change_term(dnode
, value
);
572 struct lyd_node
*yang_dnode_new(struct ly_ctx
*ly_ctx
, bool config_only
)
574 struct lyd_node
*dnode
= NULL
;
575 int options
= config_only
? LYD_VALIDATE_NO_STATE
: 0;
577 if (lyd_validate_all(&dnode
, ly_ctx
, options
, NULL
) != 0) {
578 /* Should never happen. */
579 flog_err(EC_LIB_LIBYANG
, "%s: lyd_validate() failed", __func__
);
586 struct lyd_node
*yang_dnode_dup(const struct lyd_node
*dnode
)
588 struct lyd_node
*dup
= NULL
;
590 err
= lyd_dup_siblings(dnode
, NULL
, LYD_DUP_RECURSIVE
, &dup
);
595 void yang_dnode_free(struct lyd_node
*dnode
)
597 while (dnode
->parent
)
598 dnode
= lyd_parent(dnode
);
602 struct yang_data
*yang_data_new(const char *xpath
, const char *value
)
604 struct yang_data
*data
;
606 data
= XCALLOC(MTYPE_YANG_DATA
, sizeof(*data
));
607 strlcpy(data
->xpath
, xpath
, sizeof(data
->xpath
));
609 data
->value
= strdup(value
);
614 void yang_data_free(struct yang_data
*data
)
618 XFREE(MTYPE_YANG_DATA
, data
);
621 struct list
*yang_data_list_new(void)
626 list
->del
= (void (*)(void *))yang_data_free
;
631 struct yang_data
*yang_data_list_find(const struct list
*list
,
632 const char *xpath_fmt
, ...)
634 char xpath
[XPATH_MAXLEN
];
635 struct yang_data
*data
;
636 struct listnode
*node
;
639 va_start(ap
, xpath_fmt
);
640 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
643 for (ALL_LIST_ELEMENTS_RO(list
, node
, data
))
644 if (strmatch(data
->xpath
, xpath
))
650 /* Make libyang log its errors using FRR logging infrastructure. */
651 static void ly_log_cb(LY_LOG_LEVEL level
, const char *msg
, const char *path
)
653 int priority
= LOG_ERR
;
660 priority
= LOG_WARNING
;
664 priority
= LOG_DEBUG
;
669 zlog(priority
, "libyang: %s (%s)", msg
, path
);
671 zlog(priority
, "libyang: %s", msg
);
674 const char *yang_print_errors(struct ly_ctx
*ly_ctx
, char *buf
, size_t buf_len
)
676 struct ly_err_item
*ei
;
679 ei
= ly_err_first(ly_ctx
);
683 strlcpy(buf
, "YANG error(s):\n", buf_len
);
684 for (; ei
; ei
= ei
->next
) {
685 strlcat(buf
, " ", buf_len
);
686 strlcat(buf
, ei
->msg
, buf_len
);
687 strlcat(buf
, "\n", buf_len
);
690 path
= ly_errpath(ly_ctx
);
692 strlcat(buf
, " YANG path: ", buf_len
);
693 strlcat(buf
, path
, buf_len
);
694 strlcat(buf
, "\n", buf_len
);
697 ly_err_clean(ly_ctx
, NULL
);
702 void yang_debugging_set(bool enable
)
705 ly_log_level(LY_LLDBG
);
706 ly_log_dbg_groups(0xFF);
708 ly_log_level(LY_LLERR
);
709 ly_log_dbg_groups(0);
713 struct ly_ctx
*yang_ctx_new_setup(bool embedded_modules
, bool explicit_compile
)
715 struct ly_ctx
*ctx
= NULL
;
716 const char *yang_models_path
= YANG_MODELS_PATH
;
719 if (access(yang_models_path
, R_OK
| X_OK
)) {
720 yang_models_path
= NULL
;
722 zlog_info("yang model directory \"%s\" does not exist",
725 flog_err_sys(EC_LIB_LIBYANG
,
726 "cannot access yang model directory \"%s\"",
730 uint options
= LY_CTX_NO_YANGLIBRARY
| LY_CTX_DISABLE_SEARCHDIR_CWD
;
731 if (explicit_compile
)
732 options
|= LY_CTX_EXPLICIT_COMPILE
;
733 err
= ly_ctx_new(yang_models_path
, options
, &ctx
);
737 if (embedded_modules
)
738 ly_ctx_set_module_imp_clb(ctx
, yang_module_imp_clb
, NULL
);
743 void yang_init(bool embedded_modules
, bool defer_compile
)
745 /* Initialize libyang global parameters that affect all containers. */
746 ly_set_log_clb(ly_log_cb
, 1);
747 ly_log_options(LY_LOLOG
| LY_LOSTORE
);
749 /* Initialize libyang container for native models. */
750 ly_native_ctx
= yang_ctx_new_setup(embedded_modules
, defer_compile
);
751 if (!ly_native_ctx
) {
752 flog_err(EC_LIB_LIBYANG
, "%s: ly_ctx_new() failed", __func__
);
756 yang_translator_init();
759 void yang_init_loading_complete(void)
761 /* Compile everything */
762 if (ly_ctx_compile(ly_native_ctx
) != LY_SUCCESS
) {
763 flog_err(EC_LIB_YANG_MODULE_LOAD
,
764 "%s: failed to compile loaded modules: %s", __func__
,
765 ly_errmsg(ly_native_ctx
));
770 void yang_terminate(void)
772 struct yang_module
*module
;
774 yang_translator_terminate();
776 while (!RB_EMPTY(yang_modules
, &yang_modules
)) {
777 module
= RB_ROOT(yang_modules
, &yang_modules
);
780 * We shouldn't call ly_ctx_remove_module() here because this
781 * function also removes other modules that depend on it.
783 * ly_ctx_destroy() will release all memory for us.
785 RB_REMOVE(yang_modules
, &yang_modules
, module
);
786 XFREE(MTYPE_YANG_MODULE
, module
);
789 ly_ctx_destroy(ly_native_ctx
);
792 const struct lyd_node
*yang_dnode_get_parent(const struct lyd_node
*dnode
,
795 const struct lyd_node
*orig_dnode
= dnode
;
798 switch (orig_dnode
->schema
->nodetype
) {
801 if (!strcmp(orig_dnode
->schema
->name
, name
))
808 orig_dnode
= lyd_parent(orig_dnode
);
814 bool yang_is_last_list_dnode(const struct lyd_node
*dnode
)
816 return (((dnode
->next
== NULL
)
818 && (strcmp(dnode
->next
->schema
->name
, dnode
->schema
->name
)
821 && ((dnode
->prev
== dnode
)
822 || (strcmp(dnode
->prev
->schema
->name
, dnode
->schema
->name
)
826 bool yang_is_last_level_dnode(const struct lyd_node
*dnode
)
828 const struct lyd_node
*parent
;
829 const struct lyd_node
*key_leaf
;
832 switch (dnode
->schema
->nodetype
) {
834 assert(dnode
->parent
);
835 parent
= lyd_parent(dnode
);
836 uint snode_num_keys
= yang_snode_num_keys(parent
->schema
);
837 /* XXX libyang2: q: really don't understand this code. */
838 key_leaf
= dnode
->prev
;
839 for (keys_size
= 1; keys_size
< snode_num_keys
; keys_size
++)
840 key_leaf
= key_leaf
->prev
;
841 if (key_leaf
->prev
== dnode
)
853 const struct lyd_node
*
854 yang_get_subtree_with_no_sibling(const struct lyd_node
*dnode
)
857 const struct lyd_node
*node
;
860 if (node
->schema
->nodetype
!= LYS_LIST
)
864 switch (node
->schema
->nodetype
) {
866 if (!CHECK_FLAG(node
->schema
->flags
, LYS_PRESENCE
)) {
868 && (node
->parent
->schema
->module
869 == dnode
->schema
->module
))
870 node
= lyd_parent(node
);
877 if (yang_is_last_list_dnode(node
)
878 && yang_is_last_level_dnode(node
)) {
880 && (node
->parent
->schema
->module
881 == dnode
->schema
->module
))
882 node
= lyd_parent(node
);
896 uint32_t yang_get_list_pos(const struct lyd_node
*node
)
898 return lyd_list_pos(node
);
901 uint32_t yang_get_list_elements_count(const struct lyd_node
*node
)
904 const struct lysc_node
*schema
;
907 || ((node
->schema
->nodetype
!= LYS_LIST
)
908 && (node
->schema
->nodetype
!= LYS_LEAFLIST
))) {
912 schema
= node
->schema
;
915 if (node
->schema
== schema
)