summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/grammar_sandbox_main.c1
-rw-r--r--lib/if.c6
-rw-r--r--lib/if.h3
-rw-r--r--lib/libfrr.c6
-rw-r--r--lib/northbound.c377
-rw-r--r--lib/northbound.h15
-rw-r--r--lib/northbound_cli.c93
-rw-r--r--lib/northbound_confd.c16
-rw-r--r--lib/northbound_db.c17
-rw-r--r--lib/northbound_grpc.cpp102
-rw-r--r--lib/northbound_sysrepo.c22
-rw-r--r--lib/vrf.c3
-rw-r--r--lib/xref.h1
-rw-r--r--lib/yang.c400
-rw-r--r--lib/yang.h143
-rw-r--r--lib/yang_translator.c129
-rw-r--r--lib/yang_wrappers.c546
17 files changed, 962 insertions, 918 deletions
diff --git a/lib/grammar_sandbox_main.c b/lib/grammar_sandbox_main.c
index 2066e4c96d..6469b49262 100644
--- a/lib/grammar_sandbox_main.c
+++ b/lib/grammar_sandbox_main.c
@@ -54,7 +54,6 @@ int main(int argc, char **argv)
vty_init(master, true);
lib_cmd_init();
- yang_init(true);
nb_init(master, NULL, 0, false);
vty_stdio(vty_do_exit);
diff --git a/lib/if.c b/lib/if.c
index f8a693d8f3..de2af435f6 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -266,16 +266,16 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
char oldpath[XPATH_MAXLEN];
char newpath[XPATH_MAXLEN];
- if_dnode = yang_dnode_get(
+ if_dnode = yang_dnode_getf(
running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']/vrf",
ifp->name, old_vrf->name);
if (if_dnode) {
- yang_dnode_get_path(if_dnode->parent, oldpath,
+ yang_dnode_get_path(lyd_parent(if_dnode), oldpath,
sizeof(oldpath));
yang_dnode_change_leaf(if_dnode, vrf->name);
- yang_dnode_get_path(if_dnode->parent, newpath,
+ yang_dnode_get_path(lyd_parent(if_dnode), newpath,
sizeof(newpath));
nb_running_move_tree(oldpath, newpath);
running_config->version++;
diff --git a/lib/if.h b/lib/if.h
index f425ba8bce..0d689fe14b 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -393,6 +393,7 @@ struct connected {
#define ZEBRA_IFC_REAL (1 << 0)
#define ZEBRA_IFC_CONFIGURED (1 << 1)
#define ZEBRA_IFC_QUEUED (1 << 2)
+#define ZEBRA_IFC_DOWN (1 << 3)
/*
The ZEBRA_IFC_REAL flag should be set if and only if this address
exists in the kernel and is actually usable. (A case where it exists
@@ -406,6 +407,8 @@ struct connected {
in the kernel. It may and should be set although the address might
not be
usable yet. (compare with ZEBRA_IFC_REAL)
+ The ZEBRA_IFC_DOWN flag is used to record that an address is
+ present, but down/unavailable.
*/
/* Flags for connected address. */
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 970e82c064..0817182f7a 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -765,16 +765,14 @@ struct thread_master *frr_init(void)
log_ref_vty_init();
lib_error_init();
- yang_init(true);
-
- debug_init_cli();
-
nb_init(master, di->yang_modules, di->n_yang_modules, true);
if (nb_db_init() != NB_OK)
flog_warn(EC_LIB_NB_DATABASE,
"%s: failed to initialize northbound database",
__func__);
+ debug_init_cli();
+
return master;
}
diff --git a/lib/northbound.c b/lib/northbound.c
index 34ad5dbfa9..3634fed04f 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -83,14 +83,14 @@ static int nb_transaction_process(enum nb_event event,
char *errmsg, size_t errmsg_len);
static void nb_transaction_apply_finish(struct nb_transaction *transaction,
char *errmsg, size_t errmsg_len);
-static int nb_oper_data_iter_node(const struct lys_node *snode,
+static int nb_oper_data_iter_node(const struct lysc_node *snode,
const char *xpath, const void *list_entry,
const struct yang_list_keys *list_keys,
struct yang_translator *translator,
bool first, uint32_t flags,
nb_oper_data_cb cb, void *arg);
-static int nb_node_check_config_only(const struct lys_node *snode, void *arg)
+static int nb_node_check_config_only(const struct lysc_node *snode, void *arg)
{
bool *config_only = arg;
@@ -102,10 +102,10 @@ static int nb_node_check_config_only(const struct lys_node *snode, void *arg)
return YANG_ITER_CONTINUE;
}
-static int nb_node_new_cb(const struct lys_node *snode, void *arg)
+static int nb_node_new_cb(const struct lysc_node *snode, void *arg)
{
struct nb_node *nb_node;
- struct lys_node *sparent, *sparent_list;
+ struct lysc_node *sparent, *sparent_list;
nb_node = XCALLOC(MTYPE_NB_NODE, sizeof(*nb_node));
yang_snode_get_path(snode, YANG_PATH_DATA, nb_node->xpath,
@@ -129,10 +129,7 @@ static int nb_node_new_cb(const struct lys_node *snode, void *arg)
SET_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY);
}
if (CHECK_FLAG(snode->nodetype, LYS_LIST)) {
- struct lys_node_list *slist;
-
- slist = (struct lys_node_list *)snode;
- if (slist->keys_size == 0)
+ if (yang_snode_num_keys(snode) == 0)
SET_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST);
}
@@ -142,18 +139,18 @@ static int nb_node_new_cb(const struct lys_node *snode, void *arg)
*/
nb_node->snode = snode;
assert(snode->priv == NULL);
- lys_set_private(snode, nb_node);
+ ((struct lysc_node *)snode)->priv = nb_node;
return YANG_ITER_CONTINUE;
}
-static int nb_node_del_cb(const struct lys_node *snode, void *arg)
+static int nb_node_del_cb(const struct lysc_node *snode, void *arg)
{
struct nb_node *nb_node;
nb_node = snode->priv;
if (nb_node) {
- lys_set_private(snode, NULL);
+ ((struct lysc_node *)snode)->priv = NULL;
XFREE(MTYPE_NB_NODE, nb_node);
}
@@ -170,15 +167,15 @@ void nb_nodes_delete(void)
yang_snodes_iterate(NULL, nb_node_del_cb, 0, NULL);
}
-struct nb_node *nb_node_find(const char *xpath)
+struct nb_node *nb_node_find(const char *path)
{
- const struct lys_node *snode;
+ const struct lysc_node *snode;
/*
- * Use libyang to find the schema node associated to the xpath and get
+ * Use libyang to find the schema node associated to the path and get
* the northbound node from there (snode private pointer).
*/
- snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
+ snode = lys_find_path(ly_native_ctx, NULL, path, 0);
if (!snode)
return NULL;
@@ -288,7 +285,7 @@ static unsigned int nb_node_validate_priority(const struct nb_node *nb_node)
return 0;
}
-static int nb_node_validate(const struct lys_node *snode, void *arg)
+static int nb_node_validate(const struct lysc_node *snode, void *arg)
{
struct nb_node *nb_node = snode->priv;
unsigned int *errors = arg;
@@ -339,7 +336,7 @@ int nb_config_merge(struct nb_config *config_dst, struct nb_config *config_src,
{
int ret;
- ret = lyd_merge(config_dst->dnode, config_src->dnode, LYD_OPT_EXPLICIT);
+ ret = lyd_merge_tree(&config_dst->dnode, config_src->dnode, 0);
if (ret != 0)
flog_warn(EC_LIB_LIBYANG, "%s: lyd_merge() failed", __func__);
@@ -451,7 +448,7 @@ static void nb_config_diff_created(const struct lyd_node *dnode, uint32_t *seq,
switch (dnode->schema->nodetype) {
case LYS_LEAF:
case LYS_LEAFLIST:
- if (lyd_wd_default((struct lyd_node_leaf_list *)dnode))
+ if (lyd_is_default(dnode))
break;
if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema))
@@ -470,7 +467,7 @@ static void nb_config_diff_created(const struct lyd_node *dnode, uint32_t *seq,
dnode);
/* Process child nodes recursively. */
- LY_TREE_FOR (dnode->child, child) {
+ LY_LIST_FOR (lyd_child(dnode), child) {
nb_config_diff_created(child, seq, changes);
}
break;
@@ -497,52 +494,142 @@ static void nb_config_diff_deleted(const struct lyd_node *dnode, uint32_t *seq,
* do is to call the "destroy" callbacks of their child nodes
* when applicable (i.e. optional nodes).
*/
- LY_TREE_FOR (dnode->child, child) {
+ LY_LIST_FOR (lyd_child(dnode), child) {
nb_config_diff_deleted(child, seq, changes);
}
}
}
+static int nb_lyd_diff_get_op(const struct lyd_node *dnode)
+{
+ const struct lyd_meta *meta;
+ LY_LIST_FOR (dnode->meta, meta) {
+ if (strcmp(meta->name, "operation")
+ || strcmp(meta->annotation->module->name, "yang"))
+ continue;
+ return lyd_get_meta_value(meta)[0];
+ }
+ return 'n';
+}
+
+static inline void nb_config_diff_dnode_log_path(const char *context,
+ const char *path,
+ const struct lyd_node *dnode)
+{
+ if (dnode->schema->nodetype & LYD_NODE_TERM)
+ zlog_debug("nb_config_diff: %s: %s: %s", context, path,
+ lyd_get_value(dnode));
+ else
+ zlog_debug("nb_config_diff: %s: %s", context, path);
+}
+
+static inline void nb_config_diff_dnode_log(const char *context,
+ const struct lyd_node *dnode)
+{
+ if (!dnode) {
+ zlog_debug("nb_config_diff: %s: NULL", context);
+ return;
+ }
+
+ char *path = lyd_path(dnode, LYD_PATH_STD, NULL, 0);
+ nb_config_diff_dnode_log_path(context, path, dnode);
+ free(path);
+}
+
/* Calculate the delta between two different configurations. */
static void nb_config_diff(const struct nb_config *config1,
const struct nb_config *config2,
struct nb_config_cbs *changes)
{
- struct lyd_difflist *diff;
- uint32_t seq = 0;
+ struct lyd_node *diff = NULL;
+ const struct lyd_node *root, *dnode;
+ struct lyd_node *target;
+ int op;
+ LY_ERR err;
+ char *path;
+
+#if 0 /* Useful (but noisy) when debugging diff code, and for improving later \
+ */
+ if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) {
+ LY_LIST_FOR(config1->dnode, root) {
+ LYD_TREE_DFS_BEGIN(root, dnode) {
+ nb_config_diff_dnode_log("from", dnode);
+ LYD_TREE_DFS_END(root, dnode);
+ }
+ }
+ LY_LIST_FOR(config2->dnode, root) {
+ LYD_TREE_DFS_BEGIN(root, dnode) {
+ nb_config_diff_dnode_log("to", dnode);
+ LYD_TREE_DFS_END(root, dnode);
+ }
+ }
+ }
+#endif
- diff = lyd_diff(config1->dnode, config2->dnode,
- LYD_DIFFOPT_WITHDEFAULTS);
- assert(diff);
+ err = lyd_diff_siblings(config1->dnode, config2->dnode,
+ LYD_DIFF_DEFAULTS, &diff);
+ assert(!err);
- for (int i = 0; diff->type[i] != LYD_DIFF_END; i++) {
- LYD_DIFFTYPE type;
- struct lyd_node *dnode;
+ if (diff && DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL))
+ nb_config_diff_dnode_log("iterating diff", diff);
- type = diff->type[i];
+ uint32_t seq = 0;
+ LY_LIST_FOR (diff, root) {
+ LYD_TREE_DFS_BEGIN (root, dnode) {
+ op = nb_lyd_diff_get_op(dnode);
+
+ path = lyd_path(dnode, LYD_PATH_STD, NULL, 0);
+
+#if 0 /* Useful (but noisy) when debugging diff code, and for improving later \
+ */
+ if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) {
+ char context[80];
+ snprintf(context, sizeof(context),
+ "iterating diff: oper: %c seq: %u", op, seq);
+ nb_config_diff_dnode_log_path(context, path, dnode);
+ }
+#endif
+ switch (op) {
+ case 'c': /* create */
+ /*
+ * This is rather inefficient, but when we use
+ * dnode from the diff instead of the
+ * candidate config node we get failures when
+ * looking up default values, etc, based on
+ * the diff tree.
+ */
+ target = yang_dnode_get(config2->dnode, path);
+ nb_config_diff_created(target, &seq, changes);
+
+ /* Skip rest of sub-tree, move to next sibling
+ */
+ LYD_TREE_DFS_continue = 1;
+ break;
+ case 'd': /* delete */
+ target = yang_dnode_get(config1->dnode, path);
+ nb_config_diff_deleted(target, &seq, changes);
- switch (type) {
- case LYD_DIFF_CREATED:
- dnode = diff->second[i];
- nb_config_diff_created(dnode, &seq, changes);
- break;
- case LYD_DIFF_DELETED:
- dnode = diff->first[i];
- nb_config_diff_deleted(dnode, &seq, changes);
- break;
- case LYD_DIFF_CHANGED:
- dnode = diff->second[i];
- nb_config_diff_add_change(changes, NB_OP_MODIFY, &seq,
- dnode);
- break;
- case LYD_DIFF_MOVEDAFTER1:
- case LYD_DIFF_MOVEDAFTER2:
- default:
- continue;
+ /* Skip rest of sub-tree, move to next sibling
+ */
+ LYD_TREE_DFS_continue = 1;
+ break;
+ case 'r': /* replace */
+ /* either moving an entry or changing a value */
+ target = yang_dnode_get(config2->dnode, path);
+ assert(target);
+ nb_config_diff_add_change(changes, NB_OP_MODIFY,
+ &seq, target);
+ break;
+ case 'n': /* none */
+ default:
+ break;
+ }
+ free(path);
+ LYD_TREE_DFS_END(root, dnode);
}
}
- lyd_free_diff(diff);
+ lyd_free_tree(diff);
}
int nb_candidate_edit(struct nb_config *candidate,
@@ -554,6 +641,7 @@ int nb_candidate_edit(struct nb_config *candidate,
struct lyd_node *dnode, *dep_dnode;
char xpath_edit[XPATH_MAXLEN];
char dep_xpath[XPATH_MAXLEN];
+ LY_ERR err;
/* Use special notation for leaf-lists (RFC 6020, section 9.13.5). */
if (nb_node->snode->nodetype == LYS_LEAFLIST)
@@ -565,11 +653,15 @@ int nb_candidate_edit(struct nb_config *candidate,
switch (operation) {
case NB_OP_CREATE:
case NB_OP_MODIFY:
- ly_errno = 0;
- dnode = lyd_new_path(candidate->dnode, ly_native_ctx,
- xpath_edit, (void *)data->value, 0,
- LYD_PATH_OPT_UPDATE);
- if (dnode) {
+ err = lyd_new_path(candidate->dnode, ly_native_ctx, xpath_edit,
+ (void *)data->value, LYD_NEW_PATH_UPDATE,
+ &dnode);
+ if (err) {
+ flog_warn(EC_LIB_LIBYANG,
+ "%s: lyd_new_path(%s) failed: %d", __func__,
+ xpath_edit, err);
+ return NB_ERR;
+ } else if (dnode) {
/*
* create dependency
*
@@ -581,22 +673,18 @@ int nb_candidate_edit(struct nb_config *candidate,
nb_node->dep_cbs.get_dependency_xpath(
dnode, dep_xpath);
- ly_errno = 0;
- dep_dnode = lyd_new_path(candidate->dnode,
- ly_native_ctx,
- dep_xpath, NULL, 0,
- LYD_PATH_OPT_UPDATE);
- if (!dep_dnode && ly_errno) {
- flog_warn(EC_LIB_LIBYANG,
- "%s: lyd_new_path(%s) failed",
- __func__, dep_xpath);
+ err = lyd_new_path(candidate->dnode,
+ ly_native_ctx, dep_xpath,
+ NULL, LYD_NEW_PATH_UPDATE,
+ &dep_dnode);
+ if (err) {
+ flog_warn(
+ EC_LIB_LIBYANG,
+ "%s: lyd_new_path(%s) failed: %d",
+ __func__, dep_xpath, err);
return NB_ERR;
}
}
- } else if (ly_errno) {
- flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path(%s) failed",
- __func__, xpath_edit);
- return NB_ERR;
}
break;
case NB_OP_DESTROY:
@@ -613,9 +701,9 @@ int nb_candidate_edit(struct nb_config *candidate,
dep_dnode = yang_dnode_get(candidate->dnode, dep_xpath);
if (dep_dnode)
- lyd_free(dep_dnode);
+ lyd_free_tree(dep_dnode);
}
- lyd_free(dnode);
+ lyd_free_tree(dnode);
break;
case NB_OP_MOVE:
/* TODO: update configuration. */
@@ -660,9 +748,8 @@ int nb_candidate_update(struct nb_config *candidate)
static int nb_candidate_validate_yang(struct nb_config *candidate, char *errmsg,
size_t errmsg_len)
{
- if (lyd_validate(&candidate->dnode,
- LYD_OPT_STRICT | LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL,
- ly_native_ctx)
+ if (lyd_validate_all(&candidate->dnode, ly_native_ctx,
+ LYD_VALIDATE_NO_STATE, NULL)
!= 0) {
yang_print_errors(ly_native_ctx, errmsg, errmsg_len);
return NB_ERR_VALIDATION;
@@ -678,12 +765,12 @@ static int nb_candidate_validate_code(struct nb_context *context,
char *errmsg, size_t errmsg_len)
{
struct nb_config_cb *cb;
- struct lyd_node *root, *next, *child;
+ struct lyd_node *root, *child;
int ret;
/* First validate the candidate as a whole. */
- LY_TREE_FOR (candidate->dnode, root) {
- LY_TREE_DFS_BEGIN (root, next, child) {
+ LY_LIST_FOR (candidate->dnode, root) {
+ LYD_TREE_DFS_BEGIN (root, child) {
struct nb_node *nb_node;
nb_node = child->schema->priv;
@@ -696,7 +783,7 @@ static int nb_candidate_validate_code(struct nb_context *context,
return NB_ERR_VALIDATION;
next:
- LY_TREE_DFS_END(root, next, child);
+ LYD_TREE_DFS_END(root, child);
}
}
@@ -1439,7 +1526,7 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction,
if (change->cb.operation == NB_OP_DESTROY) {
char xpath[XPATH_MAXLEN];
- dnode = dnode->parent;
+ dnode = lyd_parent(dnode);
if (!dnode)
break;
@@ -1470,7 +1557,7 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction,
nb_apply_finish_cb_new(&cbs, nb_node, dnode);
next:
- dnode = dnode->parent;
+ dnode = lyd_parent(dnode);
}
}
@@ -1487,16 +1574,16 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction,
}
}
-static int nb_oper_data_iter_children(const struct lys_node *snode,
+static int nb_oper_data_iter_children(const struct lysc_node *snode,
const char *xpath, const void *list_entry,
const struct yang_list_keys *list_keys,
struct yang_translator *translator,
bool first, uint32_t flags,
nb_oper_data_cb cb, void *arg)
{
- struct lys_node *child;
+ const struct lysc_node *child;
- LY_TREE_FOR (snode->child, child) {
+ LY_LIST_FOR (lysc_node_child(snode), child) {
int ret;
ret = nb_oper_data_iter_node(child, xpath, list_entry,
@@ -1521,7 +1608,7 @@ static int nb_oper_data_iter_leaf(const struct nb_node *nb_node,
return NB_OK;
/* Ignore list keys. */
- if (lys_is_key((struct lys_node_leaf *)nb_node->snode, NULL))
+ if (lysc_is_key(nb_node->snode))
return NB_OK;
data = nb_callback_get_elem(nb_node, xpath, list_entry);
@@ -1605,7 +1692,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
struct yang_translator *translator,
uint32_t flags, nb_oper_data_cb cb, void *arg)
{
- struct lys_node_list *slist = (struct lys_node_list *)nb_node->snode;
+ const struct lysc_node *snode = nb_node->snode;
const void *list_entry = NULL;
uint32_t position = 1;
@@ -1614,6 +1701,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
/* Iterate over all list entries. */
do {
+ const struct lysc_node_leaf *skey;
struct yang_list_keys list_keys;
char xpath[XPATH_MAXLEN * 2];
int ret;
@@ -1638,12 +1726,16 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
/* Build XPath of the list entry. */
strlcpy(xpath, xpath_list, sizeof(xpath));
- for (unsigned int i = 0; i < list_keys.num; i++) {
+ unsigned int i = 0;
+ LY_FOR_KEYS (snode, skey) {
+ assert(i < list_keys.num);
snprintf(xpath + strlen(xpath),
sizeof(xpath) - strlen(xpath),
- "[%s='%s']", slist->keys[i]->name,
+ "[%s='%s']", skey->name,
list_keys.key[i]);
+ i++;
}
+ assert(i == list_keys.num);
} else {
/*
* Keyless list - build XPath using a positional index.
@@ -1664,7 +1756,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
return NB_OK;
}
-static int nb_oper_data_iter_node(const struct lys_node *snode,
+static int nb_oper_data_iter_node(const struct lysc_node *snode,
const char *xpath_parent,
const void *list_entry,
const struct yang_list_keys *list_keys,
@@ -1683,18 +1775,16 @@ static int nb_oper_data_iter_node(const struct lys_node *snode,
/* Update XPath. */
strlcpy(xpath, xpath_parent, sizeof(xpath));
if (!first && snode->nodetype != LYS_USES) {
- struct lys_node *parent;
+ struct lysc_node *parent;
/* Get the real parent. */
parent = snode->parent;
- while (parent && parent->nodetype == LYS_USES)
- parent = parent->parent;
/*
* When necessary, include the namespace of the augmenting
* module.
*/
- if (parent && parent->nodetype == LYS_AUGMENT)
+ if (parent && parent->module != snode->module)
snprintf(xpath + strlen(xpath),
sizeof(xpath) - strlen(xpath), "/%s:%s",
snode->module->name, snode->name);
@@ -1769,12 +1859,14 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
* Create a data tree from the XPath so that we can parse the keys of
* all YANG lists (if any).
*/
- ly_errno = 0;
- dnode = lyd_new_path(NULL, ly_native_ctx, xpath, NULL, 0,
- LYD_PATH_OPT_UPDATE | LYD_PATH_OPT_NOPARENTRET);
- if (!dnode) {
- flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed",
- __func__);
+
+ LY_ERR err = lyd_new_path(NULL, ly_native_ctx, xpath, NULL,
+ LYD_NEW_PATH_UPDATE, &dnode);
+ if (err || !dnode) {
+ const char *errmsg =
+ err ? ly_errmsg(ly_native_ctx) : "node not found";
+ flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed %s",
+ __func__, errmsg);
return NB_ERR;
}
@@ -1782,8 +1874,8 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
* Create a linked list to sort the data nodes starting from the root.
*/
list_dnodes = list_new();
- for (dn = dnode; dn; dn = dn->parent) {
- if (dn->schema->nodetype != LYS_LIST || !dn->child)
+ for (dn = dnode; dn; dn = lyd_parent(dn)) {
+ if (dn->schema->nodetype != LYS_LIST || !lyd_child(dn))
continue;
listnode_add_head(list_dnodes, dn);
}
@@ -1798,18 +1890,16 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
/* Obtain the list entry keys. */
memset(&list_keys, 0, sizeof(list_keys));
- LY_TREE_FOR (dn->child, child) {
- if (!lys_is_key((struct lys_node_leaf *)child->schema,
- NULL))
- continue;
+ LY_LIST_FOR (lyd_child(dn), child) {
+ if (!lysc_is_key(child->schema))
+ break;
strlcpy(list_keys.key[n],
yang_dnode_get_string(child, NULL),
sizeof(list_keys.key[n]));
n++;
}
list_keys.num = n;
- if (list_keys.num
- != ((struct lys_node_list *)dn->schema)->keys_size) {
+ if (list_keys.num != yang_snode_num_keys(dn->schema)) {
list_delete(&list_dnodes);
yang_dnode_free(dnode);
return NB_ERR_NOT_FOUND;
@@ -1837,7 +1927,7 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
}
/* If a list entry was given, iterate over that list entry only. */
- if (dnode->schema->nodetype == LYS_LIST && dnode->child)
+ if (dnode->schema->nodetype == LYS_LIST && lyd_child(dnode))
ret = nb_oper_data_iter_children(
nb_node->snode, xpath, list_entry, &list_keys,
translator, true, flags, cb, arg);
@@ -1853,11 +1943,11 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
}
bool nb_operation_is_valid(enum nb_operation operation,
- const struct lys_node *snode)
+ const struct lysc_node *snode)
{
struct nb_node *nb_node = snode->priv;
- struct lys_node_container *scontainer;
- struct lys_node_leaf *sleaf;
+ struct lysc_node_container *scontainer;
+ struct lysc_node_leaf *sleaf;
switch (operation) {
case NB_OP_CREATE:
@@ -1866,13 +1956,13 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
- if (sleaf->type.base != LY_TYPE_EMPTY)
+ sleaf = (struct lysc_node_leaf *)snode;
+ if (sleaf->type->basetype != LY_TYPE_EMPTY)
return false;
break;
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)snode;
- if (!scontainer->presence)
+ scontainer = (struct lysc_node_container *)snode;
+ if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return false;
break;
case LYS_LIST:
@@ -1888,12 +1978,12 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
- if (sleaf->type.base == LY_TYPE_EMPTY)
+ sleaf = (struct lysc_node_leaf *)snode;
+ if (sleaf->type->basetype == LY_TYPE_EMPTY)
return false;
/* List keys can't be modified. */
- if (lys_is_key(sleaf, NULL))
+ if (lysc_is_key(sleaf))
return false;
break;
default:
@@ -1906,10 +1996,10 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
+ sleaf = (struct lysc_node_leaf *)snode;
/* List keys can't be deleted. */
- if (lys_is_key(sleaf, NULL))
+ if (lysc_is_key(sleaf))
return false;
/*
@@ -1925,8 +2015,8 @@ bool nb_operation_is_valid(enum nb_operation operation,
return false;
break;
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)snode;
- if (!scontainer->presence)
+ scontainer = (struct lysc_node_container *)snode;
+ if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return false;
break;
case LYS_LIST:
@@ -1943,7 +2033,7 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) {
case LYS_LIST:
case LYS_LEAFLIST:
- if (!CHECK_FLAG(snode->flags, LYS_USERORDERED))
+ if (!CHECK_FLAG(snode->flags, LYS_ORDBY_USER))
return false;
break;
default:
@@ -1964,8 +2054,8 @@ bool nb_operation_is_valid(enum nb_operation operation,
case LYS_LEAFLIST:
break;
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)snode;
- if (!scontainer->presence)
+ scontainer = (struct lysc_node_container *)snode;
+ if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return false;
break;
default:
@@ -2114,7 +2204,7 @@ static void *nb_running_unset_entry_helper(const struct lyd_node *dnode)
/* Unset user pointers from the child nodes. */
if (CHECK_FLAG(dnode->schema->nodetype, LYS_LIST | LYS_CONTAINER)) {
- LY_TREE_FOR (dnode->child, child) {
+ LY_LIST_FOR (lyd_child(dnode), child) {
(void)nb_running_unset_entry_helper(child);
}
}
@@ -2156,7 +2246,7 @@ static void *nb_running_get_entry_worker(const struct lyd_node *dnode,
rec_flag = rec_search;
- dnode = dnode->parent;
+ dnode = lyd_parent(dnode);
}
if (!abort_if_not_found)
@@ -2312,27 +2402,42 @@ void nb_validate_callbacks(void)
}
}
-void nb_load_module(const struct frr_yang_module_info *module_info)
-{
- struct yang_module *module;
-
- DEBUGD(&nb_dbg_events, "northbound: loading %s.yang",
- module_info->name);
-
- module = yang_module_load(module_info->name);
- yang_snodes_iterate(module->info, nb_node_new_cb, 0, NULL);
- nb_load_callbacks(module_info);
-}
void nb_init(struct thread_master *tm,
const struct frr_yang_module_info *const modules[],
size_t nmodules, bool db_enabled)
{
+ struct yang_module *loaded[nmodules], **loadedp = loaded;
+ bool explicit_compile;
+
+ /*
+ * Currently using this explicit compile feature in libyang2 leads to
+ * incorrect behavior in FRR. The functionality suppresses the compiling
+ * of modules until they have all been loaded into the context. This
+ * avoids multiple recompiles of the same modules as they are
+ * imported/augmented etc.
+ */
+ explicit_compile = false;
+
nb_db_enabled = db_enabled;
+ yang_init(true, explicit_compile);
+
/* Load YANG modules and their corresponding northbound callbacks. */
- for (size_t i = 0; i < nmodules; i++)
- nb_load_module(modules[i]);
+ for (size_t i = 0; i < nmodules; i++) {
+ DEBUGD(&nb_dbg_events, "northbound: loading %s.yang",
+ modules[i]->name);
+ *loadedp++ = yang_module_load(modules[i]->name);
+ }
+
+ if (explicit_compile)
+ yang_init_loading_complete();
+
+ /* Initialize the compiled nodes with northbound data */
+ for (size_t i = 0; i < nmodules; i++) {
+ yang_snodes_iterate(loaded[i]->info, nb_node_new_cb, 0, NULL);
+ nb_load_callbacks(modules[i]);
+ }
/* Validate northbound callbacks. */
nb_validate_callbacks();
diff --git a/lib/northbound.h b/lib/northbound.h
index 417ecc81ea..7ccab5cad5 100644
--- a/lib/northbound.h
+++ b/lib/northbound.h
@@ -537,7 +537,7 @@ struct nb_dependency_callbacks {
*/
struct nb_node {
/* Back pointer to the libyang schema node. */
- const struct lys_node *snode;
+ const struct lysc_node *snode;
/* Data path of this YANG node. */
char xpath[XPATH_MAXLEN];
@@ -685,7 +685,7 @@ struct nb_transaction {
};
/* Callback function used by nb_oper_data_iterate(). */
-typedef int (*nb_oper_data_cb)(const struct lys_node *snode,
+typedef int (*nb_oper_data_cb)(const struct lysc_node *snode,
struct yang_translator *translator,
struct yang_data *data, void *arg);
@@ -1114,7 +1114,7 @@ extern int nb_oper_data_iterate(const char *xpath,
* true if the operation is valid, false otherwise.
*/
extern bool nb_operation_is_valid(enum nb_operation operation,
- const struct lys_node *snode);
+ const struct lysc_node *snode);
/*
* Send a YANG notification. This is a no-op unless the 'nb_notification_send'
@@ -1285,15 +1285,6 @@ extern const char *nb_client_name(enum nb_client client);
void nb_validate_callbacks(void);
/*
- * Load a YANG module with its corresponding northbound callbacks.
- *
- * module_info
- * Pointer to structure containing the module name and its northbound
- * callbacks.
- */
-void nb_load_module(const struct frr_yang_module_info *module_info);
-
-/*
* Initialize the northbound layer. Should be called only once during the
* daemon initialization process.
*
diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c
index 81e30bce49..d291a1f24d 100644
--- a/lib/northbound_cli.c
+++ b/lib/northbound_cli.c
@@ -448,6 +448,7 @@ static int nb_cli_candidate_load_file(struct vty *vty,
struct ly_ctx *ly_ctx;
int ly_format;
char buf[BUFSIZ];
+ LY_ERR err;
switch (format) {
case NB_CFG_FMT_CMDS:
@@ -465,8 +466,10 @@ static int nb_cli_candidate_load_file(struct vty *vty,
ly_format = (format == NB_CFG_FMT_JSON) ? LYD_JSON : LYD_XML;
ly_ctx = translator ? translator->ly_ctx : ly_native_ctx;
- dnode = lyd_parse_path(ly_ctx, path, ly_format, LYD_OPT_EDIT);
- if (!dnode) {
+ err = lyd_parse_data_path(ly_ctx, path, ly_format,
+ LYD_PARSE_ONLY | LYD_PARSE_NO_STATE,
+ 0, &dnode);
+ if (err || !dnode) {
flog_warn(EC_LIB_LIBYANG, "%s: lyd_parse_path() failed",
__func__);
vty_out(vty, "%% Failed to load configuration:\n\n");
@@ -536,8 +539,6 @@ void nb_cli_show_config_prepare(struct nb_config *config, bool with_defaults)
if (config->dnode == NULL)
return;
- lyd_schema_sort(config->dnode, 1);
-
/*
* Call lyd_validate() only to create default child nodes, ignoring
* any possible validation error. This doesn't need to be done when
@@ -545,9 +546,8 @@ void nb_cli_show_config_prepare(struct nb_config *config, bool with_defaults)
* validated.
*/
if (config != running_config)
- (void)lyd_validate(&config->dnode,
- LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL,
- ly_native_ctx);
+ (void)lyd_validate_all(&config->dnode, ly_native_ctx,
+ LYD_VALIDATE_NO_STATE, NULL);
}
static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root,
@@ -559,7 +559,7 @@ static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root,
struct list *sort_list;
void *data;
- LY_TREE_FOR (root->child, child) {
+ LY_LIST_FOR (lyd_child(root), child) {
nb_node = child->schema->priv;
/*
@@ -634,8 +634,9 @@ static void nb_cli_show_config_cmds(struct vty *vty, struct nb_config *config,
vty_out(vty, "frr version %s\n", FRR_VER_SHORT);
vty_out(vty, "frr defaults %s\n", frr_defaults_profile());
- LY_TREE_FOR (config->dnode, root)
+ LY_LIST_FOR (config->dnode, root) {
nb_cli_show_dnode_cmds(vty, root, with_defaults);
+ }
vty_out(vty, "!\n");
vty_out(vty, "end\n");
@@ -660,11 +661,11 @@ static int nb_cli_show_config_libyang(struct vty *vty, LYD_FORMAT format,
return CMD_WARNING;
}
- SET_FLAG(options, LYP_FORMAT | LYP_WITHSIBLINGS);
+ SET_FLAG(options, LYD_PRINT_WITHSIBLINGS);
if (with_defaults)
- SET_FLAG(options, LYP_WD_ALL);
+ SET_FLAG(options, LYD_PRINT_WD_ALL);
else
- SET_FLAG(options, LYP_WD_TRIM);
+ SET_FLAG(options, LYD_PRINT_WD_TRIM);
if (lyd_print_mem(&strp, dnode, format, options) == 0 && strp) {
vty_out(vty, "%s", strp);
@@ -1401,7 +1402,7 @@ DEFPY (show_config_transaction,
#endif /* HAVE_CONFIG_ROLLBACKS */
}
-static int nb_cli_oper_data_cb(const struct lys_node *snode,
+static int nb_cli_oper_data_cb(const struct lysc_node *snode,
struct yang_translator *translator,
struct yang_data *data, void *arg)
{
@@ -1427,12 +1428,12 @@ static int nb_cli_oper_data_cb(const struct lys_node *snode,
} else
ly_ctx = ly_native_ctx;
- ly_errno = 0;
- dnode = lyd_new_path(dnode, ly_ctx, data->xpath, (void *)data->value, 0,
- LYD_PATH_OPT_UPDATE);
- if (!dnode && ly_errno) {
- flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed",
- __func__);
+ LY_ERR err =
+ lyd_new_path(dnode, ly_ctx, data->xpath, (void *)data->value,
+ LYD_NEW_PATH_UPDATE, &dnode);
+ if (err) {
+ flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path(%s) failed: %s",
+ __func__, data->xpath, ly_errmsg(ly_native_ctx));
goto error;
}
@@ -1494,11 +1495,11 @@ DEFPY (show_yang_operational_data,
yang_dnode_free(dnode);
return CMD_WARNING;
}
- lyd_validate(&dnode, LYD_OPT_GET, ly_ctx);
+ (void)lyd_validate_all(&dnode, ly_ctx, 0, NULL);
/* Display the data. */
if (lyd_print_mem(&strp, dnode, format,
- LYP_FORMAT | LYP_WITHSIBLINGS | LYP_WD_ALL)
+ LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL)
!= 0
|| !strp) {
vty_out(vty, "%% Failed to display operational data.\n");
@@ -1551,13 +1552,12 @@ DEFPY (show_yang_module,
snprintf(flags, sizeof(flags), "%c%c",
module->implemented ? 'I' : ' ',
- (module->deviated == 1) ? 'D' : ' ');
+ LY_ARRAY_COUNT(module->deviated_by) ? 'D' : ' ');
ttable_add_row(tt, "%s|%s|%s|%s|%s", module->name,
- (module->version == 2) ? "1.1" : "1.0",
- (module->rev_size > 0) ? module->rev[0].date
- : "-",
- flags, module->ns);
+ (module->parsed->version == 2) ? "1.1" : "1.0",
+ module->revision ? module->revision : "-", flags,
+ module->ns);
}
/* Dump the generated table. */
@@ -1577,21 +1577,21 @@ DEFPY (show_yang_module,
return CMD_SUCCESS;
}
-DEFPY (show_yang_module_detail,
- show_yang_module_detail_cmd,
- "show yang module\
+DEFPY(show_yang_module_detail, show_yang_module_detail_cmd,
+ "show yang module\
[module-translator WORD$translator_family]\
- WORD$module_name <summary|tree$tree|yang$yang|yin$yin>",
- SHOW_STR
- "YANG information\n"
- "Show loaded modules\n"
- "YANG module translator\n"
- "YANG module translator\n"
- "Module name\n"
- "Display summary information about the module\n"
- "Display module in the tree (RFC 8340) format\n"
- "Display module in the YANG format\n"
- "Display module in the YIN format\n")
+ WORD$module_name <compiled$compiled|summary|tree$tree|yang$yang|yin$yin>",
+ SHOW_STR
+ "YANG information\n"
+ "Show loaded modules\n"
+ "YANG module translator\n"
+ "YANG module translator\n"
+ "Module name\n"
+ "Display compiled module in YANG format\n"
+ "Display summary information about the module\n"
+ "Display module in the tree (RFC 8340) format\n"
+ "Display module in the YANG format\n"
+ "Display module in the YIN format\n")
{
struct ly_ctx *ly_ctx;
struct yang_translator *translator = NULL;
@@ -1610,7 +1610,7 @@ DEFPY (show_yang_module_detail,
} else
ly_ctx = ly_native_ctx;
- module = ly_ctx_get_module(ly_ctx, module_name, NULL, 0);
+ module = ly_ctx_get_module_latest(ly_ctx, module_name);
if (!module) {
vty_out(vty, "%% Module \"%s\" not found\n", module_name);
return CMD_WARNING;
@@ -1620,12 +1620,17 @@ DEFPY (show_yang_module_detail,
format = LYS_OUT_YANG;
else if (yin)
format = LYS_OUT_YIN;
+ else if (compiled)
+ format = LYS_OUT_YANG_COMPILED;
else if (tree)
format = LYS_OUT_TREE;
- else
- format = LYS_OUT_INFO;
+ else {
+ vty_out(vty,
+ "%% libyang v2 does not currently support summary\n");
+ return CMD_WARNING;
+ }
- if (lys_print_mem(&strp, module, format, NULL, 0, 0) == 0) {
+ if (lys_print_mem(&strp, module, format, 0) == 0) {
vty_out(vty, "%s\n", strp);
free(strp);
} else {
diff --git a/lib/northbound_confd.c b/lib/northbound_confd.c
index 403537e043..76af494e30 100644
--- a/lib/northbound_confd.c
+++ b/lib/northbound_confd.c
@@ -515,7 +515,7 @@ static int frr_confd_init_cdb(void)
/* Subscribe to all loaded YANG data modules. */
confd_spoints = list_new();
RB_FOREACH (module, yang_modules, &yang_modules) {
- struct lys_node *snode;
+ struct lysc_node *snode;
module->confd_hash = confd_str2hash(module->info->ns);
if (module->confd_hash == 0) {
@@ -531,7 +531,7 @@ static int frr_confd_init_cdb(void)
* entire YANG module. So we have to find the top level
* nodes ourselves and subscribe to their paths.
*/
- LY_TREE_FOR (module->info->data, snode) {
+ LY_LIST_FOR (module->info->data, snode) {
struct nb_node *nb_node;
int *spoint;
int ret;
@@ -762,7 +762,7 @@ static int frr_confd_data_get_object(struct confd_trans_ctx *tctx,
confd_hkeypath_t *kp)
{
struct nb_node *nb_node;
- const struct lys_node *child;
+ const struct lysc_node *child;
char xpath[XPATH_MAXLEN];
char xpath_child[XPATH_MAXLEN * 2];
struct list *elements;
@@ -789,7 +789,7 @@ static int frr_confd_data_get_object(struct confd_trans_ctx *tctx,
elements = yang_data_list_new();
/* Loop through list child nodes. */
- LY_TREE_FOR (nb_node->snode->child, child) {
+ LY_LIST_FOR (lysc_node_child(nb_node->snode), child) {
struct nb_node *nb_node_child = child->priv;
confd_value_t *v;
@@ -869,7 +869,7 @@ static int frr_confd_data_get_next_object(struct confd_trans_ctx *tctx,
memset(objects, 0, sizeof(objects));
for (int j = 0; j < CONFD_OBJECTS_PER_TIME; j++) {
struct confd_next_object *object;
- struct lys_node *child;
+ struct lysc_node *child;
struct yang_data *data;
size_t nvalues = 0;
@@ -919,7 +919,7 @@ static int frr_confd_data_get_next_object(struct confd_trans_ctx *tctx,
}
/* Loop through list child nodes. */
- LY_TREE_FOR (nb_node->snode->child, child) {
+ LY_LIST_FOR (lysc_node_child(nb_node->snode), child) {
struct nb_node *nb_node_child = child->priv;
char xpath_child[XPATH_MAXLEN * 2];
confd_value_t *v;
@@ -1187,7 +1187,7 @@ static int frr_confd_dp_read(struct thread *thread)
return 0;
}
-static int frr_confd_subscribe_state(const struct lys_node *snode, void *arg)
+static int frr_confd_subscribe_state(const struct lysc_node *snode, void *arg)
{
struct nb_node *nb_node = snode->priv;
struct confd_data_cbs *data_cbs = arg;
@@ -1391,7 +1391,7 @@ static void frr_confd_cli_init(void)
/* ------------ Main ------------ */
-static int frr_confd_calculate_snode_hash(const struct lys_node *snode,
+static int frr_confd_calculate_snode_hash(const struct lysc_node *snode,
void *arg)
{
struct nb_node *nb_node = snode->priv;
diff --git a/lib/northbound_db.c b/lib/northbound_db.c
index 244e760b2b..dce9b2ec24 100644
--- a/lib/northbound_db.c
+++ b/lib/northbound_db.c
@@ -87,9 +87,12 @@ int nb_db_transaction_save(const struct nb_transaction *transaction,
goto exit;
client_name = nb_client_name(transaction->context->client);
- /* Always record configurations in the XML format. */
+ /*
+ * Always record configurations in the XML format, save the default
+ * values too, as this covers the case where defaults may change.
+ */
if (lyd_print_mem(&config_str, transaction->config->dnode, LYD_XML,
- LYP_FORMAT | LYP_WITHSIBLINGS)
+ LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL)
!= 0)
goto exit;
@@ -149,6 +152,7 @@ struct nb_config *nb_db_transaction_load(uint32_t transaction_id)
struct lyd_node *dnode;
const char *config_str;
struct sqlite3_stmt *ss;
+ LY_ERR err;
ss = db_prepare(
"SELECT\n"
@@ -169,10 +173,11 @@ struct nb_config *nb_db_transaction_load(uint32_t transaction_id)
if (db_loadf(ss, "%s", &config_str) != 0)
goto exit;
- dnode = lyd_parse_mem(ly_native_ctx, config_str, LYD_XML,
- LYD_OPT_CONFIG);
- if (!dnode)
- flog_warn(EC_LIB_LIBYANG, "%s: lyd_parse_mem() failed",
+ err = lyd_parse_data_mem(ly_native_ctx, config_str, LYD_XML,
+ LYD_PARSE_STRICT | LYD_PARSE_NO_STATE,
+ LYD_VALIDATE_NO_STATE, &dnode);
+ if (err || !dnode)
+ flog_warn(EC_LIB_LIBYANG, "%s: lyd_parse_data_mem() failed",
__func__);
else
config = nb_config_new(dnode);
diff --git a/lib/northbound_grpc.cpp b/lib/northbound_grpc.cpp
index 58f4e42516..c61effdda5 100644
--- a/lib/northbound_grpc.cpp
+++ b/lib/northbound_grpc.cpp
@@ -199,9 +199,8 @@ class NorthboundImpl
auto m = tag->response.add_supported_modules();
m->set_name(module->name);
- if (module->info->rev_size)
- m->set_revision(
- module->info->rev[0].date);
+ if (module->info->revision)
+ m->set_revision(module->info->revision);
m->set_organization(module->info->org);
}
@@ -1068,14 +1067,13 @@ class NorthboundImpl
const std::string &path,
const std::string &value)
{
- ly_errno = LY_SUCCESS;
- dnode = lyd_new_path(dnode, ly_native_ctx, path.c_str(),
- (void *)value.c_str(),
- (LYD_ANYDATA_VALUETYPE)0,
- LYD_PATH_OPT_UPDATE);
- if (!dnode && ly_errno != LY_SUCCESS) {
- flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed",
- __func__);
+ LY_ERR err = lyd_new_path(dnode, ly_native_ctx, path.c_str(),
+ value.c_str(), LYD_NEW_PATH_UPDATE,
+ &dnode);
+ if (err != LY_SUCCESS) {
+ flog_warn(EC_LIB_LIBYANG,
+ "%s: lyd_new_path() failed: %s", __func__,
+ ly_errmsg(ly_native_ctx));
return -1;
}
@@ -1089,7 +1087,7 @@ class NorthboundImpl
if (!dnode)
return -1;
- lyd_free(dnode);
+ lyd_free_tree(dnode);
return 0;
}
@@ -1109,7 +1107,7 @@ class NorthboundImpl
}
}
- static int get_oper_data_cb(const struct lys_node *snode,
+ static int get_oper_data_cb(const struct lysc_node *snode,
struct yang_translator *translator,
struct yang_data *data, void *arg)
{
@@ -1132,46 +1130,53 @@ class NorthboundImpl
std::string(date), std::string(comment)));
}
- static int data_tree_from_dnode(frr::DataTree *dt,
- const struct lyd_node *dnode,
- LYD_FORMAT lyd_format,
- bool with_defaults)
+ static LY_ERR data_tree_from_dnode(frr::DataTree *dt,
+ const struct lyd_node *dnode,
+ LYD_FORMAT lyd_format,
+ bool with_defaults)
{
char *strp;
int options = 0;
- SET_FLAG(options, LYP_FORMAT | LYP_WITHSIBLINGS);
+ SET_FLAG(options, LYD_PRINT_WITHSIBLINGS);
if (with_defaults)
- SET_FLAG(options, LYP_WD_ALL);
+ SET_FLAG(options, LYD_PRINT_WD_ALL);
else
- SET_FLAG(options, LYP_WD_TRIM);
+ SET_FLAG(options, LYD_PRINT_WD_TRIM);
- if (lyd_print_mem(&strp, dnode, lyd_format, options) == 0) {
+ LY_ERR err = lyd_print_mem(&strp, dnode, lyd_format, options);
+ if (err == LY_SUCCESS) {
if (strp) {
dt->set_data(strp);
free(strp);
}
- return 0;
}
-
- return -1;
+ return err;
}
static struct lyd_node *dnode_from_data_tree(const frr::DataTree *dt,
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 = lyd_parse_mem(ly_native_ctx, dt->data().c_str(),
- encoding2lyd_format(dt->encoding()),
- options);
+ int options, opt2;
+ LY_ERR err;
+
+ if (config_only) {
+ options = LYD_PARSE_STRICT | LYD_PARSE_NO_STATE;
+ opt2 = LYD_VALIDATE_NO_STATE;
+ } else {
+ options = LYD_PARSE_STRICT;
+ opt2 = 0;
+ }
+ err = lyd_parse_data_mem(ly_native_ctx, dt->data().c_str(),
+ encoding2lyd_format(dt->encoding()),
+ options, opt2, &dnode);
+ if (err != LY_SUCCESS) {
+ flog_warn(EC_LIB_LIBYANG,
+ "%s: lyd_parse_mem() failed: %s", __func__,
+ ly_errmsg(ly_native_ctx));
+ }
return dnode;
}
@@ -1239,14 +1244,15 @@ class NorthboundImpl
// Combine configuration and state data into a single
// dnode.
//
- if (lyd_merge(dnode_state, dnode_config,
- LYD_OPT_EXPLICIT)
- != 0) {
+ if (lyd_merge_tree(&dnode_state, dnode_config,
+ LYD_MERGE_DESTRUCT)
+ != LY_SUCCESS) {
yang_dnode_free(dnode_state);
yang_dnode_free(dnode_config);
return grpc::Status(
grpc::StatusCode::INTERNAL,
- "Failed to merge configuration and state data");
+ "Failed to merge configuration and state data",
+ ly_errmsg(ly_native_ctx));
}
dnode_final = dnode_state;
@@ -1262,19 +1268,25 @@ class NorthboundImpl
// Validate data to create implicit default nodes if necessary.
int validate_opts = 0;
if (type == frr::GetRequest_DataType_CONFIG)
- validate_opts = LYD_OPT_CONFIG;
+ validate_opts = LYD_VALIDATE_NO_STATE;
else
- validate_opts = LYD_OPT_DATA | LYD_OPT_DATA_NO_YANGLIB;
- lyd_validate(&dnode_final, validate_opts, ly_native_ctx);
+ validate_opts = 0;
+ LY_ERR err = lyd_validate_all(&dnode_final, ly_native_ctx,
+ validate_opts, NULL);
+
+ if (err)
+ flog_warn(EC_LIB_LIBYANG,
+ "%s: lyd_validate_all() failed: %s", __func__,
+ ly_errmsg(ly_native_ctx));
// Dump data using the requested format.
- int ret = data_tree_from_dnode(dt, dnode_final, lyd_format,
- with_defaults);
+ if (!err)
+ err = data_tree_from_dnode(dt, dnode_final, lyd_format,
+ with_defaults);
yang_dnode_free(dnode_final);
- if (ret != 0)
+ if (err)
return grpc::Status(grpc::StatusCode::INTERNAL,
"Failed to dump data");
-
return grpc::Status::OK;
}
diff --git a/lib/northbound_sysrepo.c b/lib/northbound_sysrepo.c
index 63fd40f8d3..7c463dd61f 100644
--- a/lib/northbound_sysrepo.c
+++ b/lib/northbound_sysrepo.c
@@ -48,10 +48,10 @@ static int frr_sr_finish(void);
static int yang_data_frr2sr(struct yang_data *frr_data, sr_val_t *sr_data)
{
struct nb_node *nb_node;
- const struct lys_node *snode;
- struct lys_node_container *scontainer;
- struct lys_node_leaf *sleaf;
- struct lys_node_leaflist *sleaflist;
+ const struct lysc_node *snode;
+ struct lysc_node_container *scontainer;
+ struct lysc_node_leaf *sleaf;
+ struct lysc_node_leaflist *sleaflist;
LY_DATA_TYPE type;
sr_val_set_xpath(sr_data, frr_data->xpath);
@@ -67,8 +67,8 @@ static int yang_data_frr2sr(struct yang_data *frr_data, sr_val_t *sr_data)
snode = nb_node->snode;
switch (snode->nodetype) {
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)snode;
- if (!scontainer->presence)
+ scontainer = (struct lysc_node_container *)snode;
+ if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return -1;
sr_data->type = SR_CONTAINER_PRESENCE_T;
return 0;
@@ -76,11 +76,11 @@ static int yang_data_frr2sr(struct yang_data *frr_data, sr_val_t *sr_data)
sr_data->type = SR_LIST_T;
return 0;
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
+ sleaf = (struct lysc_node_leaf *)snode;
type = sleaf->type.base;
break;
case LYS_LEAFLIST:
- sleaflist = (struct lys_node_leaflist *)snode;
+ sleaflist = (struct lysc_node_leaflist *)snode;
type = sleaflist->type.base;
break;
default:
@@ -359,7 +359,7 @@ static int frr_sr_config_change_cb(sr_session_ctx_t *session,
}
}
-static int frr_sr_state_data_iter_cb(const struct lys_node *snode,
+static int frr_sr_state_data_iter_cb(const struct lysc_node *snode,
struct yang_translator *translator,
struct yang_data *data, void *arg)
{
@@ -562,7 +562,7 @@ static void frr_sr_subscribe_config(struct yang_module *module)
sr_strerror(ret));
}
-static int frr_sr_subscribe_state(const struct lys_node *snode, void *arg)
+static int frr_sr_subscribe_state(const struct lysc_node *snode, void *arg)
{
struct yang_module *module = arg;
struct nb_node *nb_node;
@@ -591,7 +591,7 @@ static int frr_sr_subscribe_state(const struct lys_node *snode, void *arg)
return YANG_ITER_CONTINUE;
}
-static int frr_sr_subscribe_rpc(const struct lys_node *snode, void *arg)
+static int frr_sr_subscribe_rpc(const struct lysc_node *snode, void *arg)
{
struct yang_module *module = arg;
struct nb_node *nb_node;
diff --git a/lib/vrf.c b/lib/vrf.c
index 7888d435f5..b6a53839cf 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -1214,7 +1214,8 @@ const struct frr_yang_module_info frr_vrf_info = {
.get_next = lib_vrf_get_next,
.get_keys = lib_vrf_get_keys,
.lookup_entry = lib_vrf_lookup_entry,
- }
+ },
+ .priority = NB_DFLT_PRIORITY - 2,
},
{
.xpath = "/frr-vrf:lib/vrf/state/id",
diff --git a/lib/xref.h b/lib/xref.h
index 949458b313..6cff1a3769 100644
--- a/lib/xref.h
+++ b/lib/xref.h
@@ -169,6 +169,7 @@ extern const struct xref * const __stop_xref_array[1] DSO_LOCAL;
static void __attribute__((used, _CONSTRUCTOR(1100))) \
_xref_init(void) { \
static struct xref_block _xref_block = { \
+ .next = NULL, \
.start = __start_xref_array, \
.stop = __stop_xref_array, \
}; \
diff --git a/lib/yang.c b/lib/yang.c
index df3b07fb09..1e241f049e 100644
--- a/lib/yang.c
+++ b/lib/yang.c
@@ -25,8 +25,6 @@
#include "yang_translator.h"
#include "northbound.h"
-#include <libyang/user_types.h>
-
DEFINE_MTYPE_STATIC(LIB, YANG_MODULE, "YANG module");
DEFINE_MTYPE_STATIC(LIB, YANG_DATA, "YANG data structure");
@@ -42,14 +40,12 @@ void yang_module_embed(struct yang_module_embed *embed)
embedupd = &embed->next;
}
-static const char *yang_module_imp_clb(const char *mod_name,
- const char *mod_rev,
- const char *submod_name,
- const char *submod_rev,
- void *user_data,
- LYS_INFORMAT *format,
- void (**free_module_data)
- (void *, void*))
+static LY_ERR yang_module_imp_clb(const char *mod_name, const char *mod_rev,
+ const char *submod_name,
+ const char *submod_rev, void *user_data,
+ LYS_INFORMAT *format,
+ const char **module_data,
+ void (**free_module_data)(void *, void *))
{
struct yang_module_embed *e;
@@ -69,15 +65,17 @@ static const char *yang_module_imp_clb(const char *mod_name,
}
*format = e->format;
- return e->data;
+ *module_data = e->data;
+ return LY_SUCCESS;
}
- flog_warn(
- EC_LIB_YANG_MODULE_LOAD,
+ /* We get here for indirect modules like ietf-inet-types */
+ zlog_debug(
"YANG model \"%s@%s\" \"%s@%s\"not embedded, trying external file",
mod_name, mod_rev ? mod_rev : "*",
submod_name ? submod_name : "*", submod_rev ? submod_rev : "*");
- return NULL;
+
+ return LY_ENOTFOUND;
}
/* clang-format off */
@@ -111,7 +109,8 @@ struct yang_module *yang_module_load(const char *module_name)
struct yang_module *module;
const struct lys_module *module_info;
- module_info = ly_ctx_load_module(ly_native_ctx, module_name, NULL);
+ module_info =
+ ly_ctx_load_module(ly_native_ctx, module_name, NULL, NULL);
if (!module_info) {
flog_err(EC_LIB_YANG_MODULE_LOAD,
"%s: failed to load data model: %s", __func__,
@@ -147,62 +146,39 @@ struct yang_module *yang_module_find(const char *module_name)
return RB_FIND(yang_modules, &yang_modules, &s);
}
-int yang_snodes_iterate_subtree(const struct lys_node *snode,
+int yang_snodes_iterate_subtree(const struct lysc_node *snode,
const struct lys_module *module,
yang_iterate_cb cb, uint16_t flags, void *arg)
{
- struct lys_node *child;
+ const struct lysc_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:
- case LYS_INPUT:
- case LYS_OUTPUT:
- if (CHECK_FLAG(snode->flags, LYS_IMPLICIT))
- goto next;
- break;
- default:
- break;
- }
- }
-
switch (snode->nodetype) {
case LYS_CONTAINER:
if (CHECK_FLAG(flags, YANG_ITER_FILTER_NPCONTAINERS)) {
- struct lys_node_container *scontainer;
-
- scontainer = (struct lys_node_container *)snode;
- if (!scontainer->presence)
+ if (!CHECK_FLAG(snode->flags, LYS_PRESENCE))
goto next;
}
break;
case LYS_LEAF:
if (CHECK_FLAG(flags, YANG_ITER_FILTER_LIST_KEYS)) {
- struct lys_node_leaf *sleaf;
-
/* Ignore list keys. */
- sleaf = (struct lys_node_leaf *)snode;
- if (lys_is_key(sleaf, NULL))
+ if (lysc_is_key(snode))
goto next;
}
break;
- case LYS_GROUPING:
- /* Return since we're not interested in the grouping subtree. */
- return YANG_ITER_CONTINUE;
- case LYS_USES:
- case LYS_AUGMENT:
- /* Always ignore nodes of these types. */
- goto next;
case LYS_INPUT:
case LYS_OUTPUT:
if (CHECK_FLAG(flags, YANG_ITER_FILTER_INPUT_OUTPUT))
goto next;
break;
default:
+ assert(snode->nodetype != LYS_AUGMENT
+ && snode->nodetype != LYS_GROUPING
+ && snode->nodetype != LYS_USES);
break;
}
@@ -212,19 +188,17 @@ int yang_snodes_iterate_subtree(const struct lys_node *snode,
next:
/*
- * YANG leafs and leaf-lists can't have child nodes, and trying to
- * access snode->child is undefined behavior.
+ * YANG leafs and leaf-lists can't have child nodes.
*/
if (CHECK_FLAG(snode->nodetype, LYS_LEAF | LYS_LEAFLIST))
return YANG_ITER_CONTINUE;
- LY_TREE_FOR (snode->child, child) {
+ LY_LIST_FOR (lysc_node_child(snode), child) {
ret = yang_snodes_iterate_subtree(child, module, cb, flags,
arg);
if (ret == YANG_ITER_STOP)
return ret;
}
-
return ret;
}
@@ -237,12 +211,24 @@ int yang_snodes_iterate(const struct lys_module *module, yang_iterate_cb cb,
idx = ly_ctx_internal_modules_count(ly_native_ctx);
while ((module_iter = ly_ctx_get_module_iter(ly_native_ctx, &idx))) {
- struct lys_node *snode;
+ struct lysc_node *snode;
if (!module_iter->implemented)
continue;
- LY_TREE_FOR (module_iter->data, snode) {
+ LY_LIST_FOR (module_iter->compiled->data, snode) {
+ ret = yang_snodes_iterate_subtree(snode, module, cb,
+ flags, arg);
+ if (ret == YANG_ITER_STOP)
+ return ret;
+ }
+ LY_LIST_FOR (&module_iter->compiled->rpcs->node, snode) {
+ ret = yang_snodes_iterate_subtree(snode, module, cb,
+ flags, arg);
+ if (ret == YANG_ITER_STOP)
+ return ret;
+ }
+ LY_LIST_FOR (&module_iter->compiled->notifs->node, snode) {
ret = yang_snodes_iterate_subtree(snode, module, cb,
flags, arg);
if (ret == YANG_ITER_STOP)
@@ -253,38 +239,32 @@ int yang_snodes_iterate(const struct lys_module *module, yang_iterate_cb cb,
return ret;
}
-void yang_snode_get_path(const struct lys_node *snode, enum yang_path_type type,
- char *xpath, size_t xpath_len)
+void yang_snode_get_path(const struct lysc_node *snode,
+ enum yang_path_type type, char *xpath,
+ size_t xpath_len)
{
- char *xpath_ptr;
-
switch (type) {
case YANG_PATH_SCHEMA:
- xpath_ptr = lys_path(snode, 0);
+ (void)lysc_path(snode, LYSC_PATH_LOG, xpath, xpath_len);
break;
case YANG_PATH_DATA:
- xpath_ptr = lys_data_path(snode);
+ (void)lysc_path(snode, LYSC_PATH_DATA, xpath, xpath_len);
break;
default:
flog_err(EC_LIB_DEVELOPMENT, "%s: unknown yang path type: %u",
__func__, type);
exit(1);
}
- strlcpy(xpath, xpath_ptr, xpath_len);
- free(xpath_ptr);
}
-struct lys_node *yang_snode_real_parent(const struct lys_node *snode)
+struct lysc_node *yang_snode_real_parent(const struct lysc_node *snode)
{
- struct lys_node *parent = snode->parent;
+ struct lysc_node *parent = snode->parent;
while (parent) {
- struct lys_node_container *scontainer;
-
switch (parent->nodetype) {
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)parent;
- if (scontainer->presence)
+ if (CHECK_FLAG(parent->flags, LYS_PRESENCE))
return parent;
break;
case LYS_LIST:
@@ -298,9 +278,9 @@ struct lys_node *yang_snode_real_parent(const struct lys_node *snode)
return NULL;
}
-struct lys_node *yang_snode_parent_list(const struct lys_node *snode)
+struct lysc_node *yang_snode_parent_list(const struct lysc_node *snode)
{
- struct lys_node *parent = snode->parent;
+ struct lysc_node *parent = snode->parent;
while (parent) {
switch (parent->nodetype) {
@@ -315,14 +295,14 @@ struct lys_node *yang_snode_parent_list(const struct lys_node *snode)
return NULL;
}
-bool yang_snode_is_typeless_data(const struct lys_node *snode)
+bool yang_snode_is_typeless_data(const struct lysc_node *snode)
{
- struct lys_node_leaf *sleaf;
+ const struct lysc_node_leaf *sleaf;
switch (snode->nodetype) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
- if (sleaf->type.base == LY_TYPE_EMPTY)
+ sleaf = (struct lysc_node_leaf *)snode;
+ if (sleaf->type->basetype == LY_TYPE_EMPTY)
return true;
return false;
case LYS_LEAFLIST:
@@ -332,16 +312,16 @@ bool yang_snode_is_typeless_data(const struct lys_node *snode)
}
}
-const char *yang_snode_get_default(const struct lys_node *snode)
+const char *yang_snode_get_default(const struct lysc_node *snode)
{
- struct lys_node_leaf *sleaf;
+ const struct lysc_node_leaf *sleaf;
switch (snode->nodetype) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
-
- /* NOTE: this might be null. */
- return sleaf->dflt;
+ sleaf = (const struct lysc_node_leaf *)snode;
+ return sleaf->dflt ? lyd_value_get_canonical(sleaf->module->ctx,
+ sleaf->dflt)
+ : NULL;
case LYS_LEAFLIST:
/* TODO: check leaf-list default values */
return NULL;
@@ -350,29 +330,40 @@ const char *yang_snode_get_default(const struct lys_node *snode)
}
}
-const struct lys_type *yang_snode_get_type(const struct lys_node *snode)
+const struct lysc_type *yang_snode_get_type(const struct lysc_node *snode)
{
- struct lys_node_leaf *sleaf = (struct lys_node_leaf *)snode;
- struct lys_type *type;
+ struct lysc_node_leaf *sleaf = (struct lysc_node_leaf *)snode;
+ struct lysc_type *type;
if (!CHECK_FLAG(sleaf->nodetype, LYS_LEAF | LYS_LEAFLIST))
return NULL;
- type = &sleaf->type;
- while (type->base == LY_TYPE_LEAFREF)
- type = &type->info.lref.target->type;
+ type = sleaf->type;
+ while (type->basetype == LY_TYPE_LEAFREF)
+ type = ((struct lysc_type_leafref *)type)->realtype;
return type;
}
+unsigned int yang_snode_num_keys(const struct lysc_node *snode)
+{
+ const struct lysc_node_leaf *skey;
+ uint count = 0;
+
+ if (!CHECK_FLAG(snode->nodetype, LYS_LIST))
+ return 0;
+
+ /* Walk list of children */
+ LY_FOR_KEYS (snode, skey) {
+ count++;
+ }
+ return count;
+}
+
void yang_dnode_get_path(const struct lyd_node *dnode, char *xpath,
size_t xpath_len)
{
- char *xpath_ptr;
-
- xpath_ptr = lyd_path(dnode);
- strlcpy(xpath, xpath_ptr, xpath_len);
- free(xpath_ptr);
+ lyd_path(dnode, LYD_PATH_STD, xpath, xpath_len);
}
const char *yang_dnode_get_schema_name(const struct lyd_node *dnode,
@@ -398,55 +389,78 @@ const char *yang_dnode_get_schema_name(const struct lyd_node *dnode,
return dnode->schema->name;
}
-struct lyd_node *yang_dnode_get(const struct lyd_node *dnode,
- const char *xpath_fmt, ...)
+struct lyd_node *yang_dnode_get(const struct lyd_node *dnode, const char *xpath)
{
- va_list ap;
- char xpath[XPATH_MAXLEN];
- struct ly_set *set;
+ struct ly_set *set = NULL;
struct lyd_node *dnode_ret = NULL;
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
+ /*
+ * XXX a lot of the code uses this for style I guess. It shouldn't, as
+ * it adds to the xpath parsing complexity in libyang.
+ */
+ if (xpath[0] == '.' && xpath[1] == '/')
+ xpath += 2;
- set = lyd_find_path(dnode, xpath);
- assert(set);
- if (set->number == 0)
+ if (lyd_find_xpath(dnode, xpath, &set)) {
+ assert(0); /* XXX replicates old libyang1 base code */
+ goto exit;
+ }
+ if (set->count == 0)
goto exit;
- if (set->number > 1) {
+ if (set->count > 1) {
flog_warn(EC_LIB_YANG_DNODE_NOT_FOUND,
"%s: found %u elements (expected 0 or 1) [xpath %s]",
- __func__, set->number, xpath);
+ __func__, set->count, xpath);
goto exit;
}
- dnode_ret = set->set.d[0];
+ dnode_ret = set->dnodes[0];
exit:
- ly_set_free(set);
+ ly_set_free(set, NULL);
return dnode_ret;
}
-bool yang_dnode_exists(const struct lyd_node *dnode, const char *xpath_fmt, ...)
+struct lyd_node *yang_dnode_getf(const struct lyd_node *dnode,
+ const char *xpath_fmt, ...)
{
va_list ap;
char xpath[XPATH_MAXLEN];
- struct ly_set *set;
- bool found;
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
- set = lyd_find_path(dnode, xpath);
- assert(set);
- found = (set->number > 0);
- ly_set_free(set);
+ return yang_dnode_get(dnode, xpath);
+}
+
+bool yang_dnode_exists(const struct lyd_node *dnode, const char *xpath)
+{
+ struct ly_set *set = NULL;
+ bool exists = false;
- return found;
+ if (xpath[0] == '.' && xpath[1] == '/')
+ xpath += 2;
+ if (lyd_find_xpath(dnode, xpath, &set))
+ return false;
+ exists = set->count > 0;
+ ly_set_free(set, NULL);
+ return exists;
+}
+
+bool yang_dnode_existsf(const struct lyd_node *dnode, const char *xpath_fmt,
+ ...)
+{
+ va_list ap;
+ char xpath[XPATH_MAXLEN];
+
+ va_start(ap, xpath_fmt);
+ vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
+ va_end(ap);
+
+ return yang_dnode_exists(dnode, xpath);
}
void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
@@ -461,52 +475,42 @@ void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
- set = lyd_find_path(dnode, xpath);
- assert(set);
- for (unsigned int i = 0; i < set->number; i++) {
+ if (lyd_find_xpath(dnode, xpath, &set)) {
+ assert(0); /* XXX libyang2: ly1 code asserted success */
+ return;
+ }
+ for (unsigned int i = 0; i < set->count; i++) {
int ret;
- dnode = set->set.d[i];
- ret = (*cb)(dnode, arg);
+ ret = (*cb)(set->dnodes[i], arg);
if (ret == YANG_ITER_STOP)
break;
}
- ly_set_free(set);
+ ly_set_free(set, NULL);
}
-bool yang_dnode_is_default(const struct lyd_node *dnode, const char *xpath_fmt,
- ...)
+bool yang_dnode_is_default(const struct lyd_node *dnode, const char *xpath)
{
- struct lys_node *snode;
- struct lys_node_leaf *sleaf;
- struct lys_node_container *scontainer;
-
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
+ const struct lysc_node *snode;
+ struct lysc_node_leaf *sleaf;
+ if (xpath)
dnode = yang_dnode_get(dnode, xpath);
- }
assert(dnode);
snode = dnode->schema;
switch (snode->nodetype) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
- if (sleaf->type.base == LY_TYPE_EMPTY)
+ sleaf = (struct lysc_node_leaf *)snode;
+ if (sleaf->type->basetype == LY_TYPE_EMPTY)
return false;
- return lyd_wd_default((struct lyd_node_leaf_list *)dnode);
+ return lyd_is_default(dnode);
case LYS_LEAFLIST:
/* TODO: check leaf-list default values */
return false;
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)snode;
- if (scontainer->presence)
+ if (CHECK_FLAG(snode->flags, LYS_PRESENCE))
return false;
return true;
default:
@@ -514,24 +518,39 @@ bool yang_dnode_is_default(const struct lyd_node *dnode, const char *xpath_fmt,
}
}
-bool yang_dnode_is_default_recursive(const struct lyd_node *dnode)
+bool yang_dnode_is_defaultf(const struct lyd_node *dnode, const char *xpath_fmt,
+ ...)
{
- struct lys_node *snode;
- struct lyd_node *root, *next, *dnode_iter;
-
- snode = dnode->schema;
- if (CHECK_FLAG(snode->nodetype, LYS_LEAF | LYS_LEAFLIST))
+ if (!xpath_fmt)
return yang_dnode_is_default(dnode, NULL);
+ else {
+ va_list ap;
+ char xpath[XPATH_MAXLEN];
+
+ va_start(ap, xpath_fmt);
+ vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
+ va_end(ap);
+
+ return yang_dnode_is_default(dnode, xpath);
+ }
+}
+
+bool yang_dnode_is_default_recursive(const struct lyd_node *dnode)
+{
+ struct lyd_node *root, *dnode_iter;
if (!yang_dnode_is_default(dnode, NULL))
return false;
- LY_TREE_FOR (dnode->child, root) {
- LY_TREE_DFS_BEGIN (root, next, dnode_iter) {
+ if (CHECK_FLAG(dnode->schema->nodetype, LYS_LEAF | LYS_LEAFLIST))
+ return true;
+
+ LY_LIST_FOR (lyd_child(dnode), root) {
+ LYD_TREE_DFS_BEGIN (root, dnode_iter) {
if (!yang_dnode_is_default(dnode_iter, NULL))
return false;
- LY_TREE_DFS_END(root, next, dnode_iter);
+ LYD_TREE_DFS_END(root, dnode_iter);
}
}
@@ -541,21 +560,15 @@ bool yang_dnode_is_default_recursive(const struct lyd_node *dnode)
void yang_dnode_change_leaf(struct lyd_node *dnode, const char *value)
{
assert(dnode->schema->nodetype == LYS_LEAF);
- lyd_change_leaf((struct lyd_node_leaf_list *)dnode, value);
+ lyd_change_term(dnode, value);
}
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;
+ struct lyd_node *dnode = NULL;
+ int options = config_only ? LYD_VALIDATE_NO_STATE : 0;
- dnode = NULL;
- if (lyd_validate(&dnode, options, ly_ctx) != 0) {
+ if (lyd_validate_all(&dnode, ly_ctx, options, NULL) != 0) {
/* Should never happen. */
flog_err(EC_LIB_LIBYANG, "%s: lyd_validate() failed", __func__);
exit(1);
@@ -566,14 +579,18 @@ struct lyd_node *yang_dnode_new(struct ly_ctx *ly_ctx, bool config_only)
struct lyd_node *yang_dnode_dup(const struct lyd_node *dnode)
{
- return lyd_dup_withsiblings(dnode, 1);
+ struct lyd_node *dup = NULL;
+ LY_ERR err;
+ err = lyd_dup_siblings(dnode, NULL, LYD_DUP_RECURSIVE, &dup);
+ assert(!err);
+ return dup;
}
void yang_dnode_free(struct lyd_node *dnode)
{
while (dnode->parent)
- dnode = dnode->parent;
- lyd_free_withsiblings(dnode);
+ dnode = lyd_parent(dnode);
+ lyd_free_all(dnode);
}
struct yang_data *yang_data_new(const char *xpath, const char *value)
@@ -679,18 +696,19 @@ const char *yang_print_errors(struct ly_ctx *ly_ctx, char *buf, size_t buf_len)
void yang_debugging_set(bool enable)
{
if (enable) {
- ly_verb(LY_LLDBG);
- ly_verb_dbg(0xFF);
+ ly_log_level(LY_LLDBG);
+ ly_log_dbg_groups(0xFF);
} else {
- ly_verb(LY_LLERR);
- ly_verb_dbg(0);
+ ly_log_level(LY_LLERR);
+ ly_log_dbg_groups(0);
}
}
-struct ly_ctx *yang_ctx_new_setup(bool embedded_modules)
+struct ly_ctx *yang_ctx_new_setup(bool embedded_modules, bool explicit_compile)
{
- struct ly_ctx *ctx;
+ struct ly_ctx *ctx = NULL;
const char *yang_models_path = YANG_MODELS_PATH;
+ LY_ERR err;
if (access(yang_models_path, R_OK | X_OK)) {
yang_models_path = NULL;
@@ -703,8 +721,11 @@ struct ly_ctx *yang_ctx_new_setup(bool embedded_modules)
YANG_MODELS_PATH);
}
- ctx = ly_ctx_new(yang_models_path, LY_CTX_DISABLE_SEARCHDIR_CWD);
- if (!ctx)
+ uint options = LY_CTX_NO_YANGLIBRARY | LY_CTX_DISABLE_SEARCHDIR_CWD;
+ if (explicit_compile)
+ options |= LY_CTX_EXPLICIT_COMPILE;
+ err = ly_ctx_new(yang_models_path, options, &ctx);
+ if (err)
return NULL;
if (embedded_modules)
@@ -713,14 +734,14 @@ struct ly_ctx *yang_ctx_new_setup(bool embedded_modules)
return ctx;
}
-void yang_init(bool embedded_modules)
+void yang_init(bool embedded_modules, bool defer_compile)
{
/* Initialize libyang global parameters that affect all containers. */
ly_set_log_clb(ly_log_cb, 1);
ly_log_options(LY_LOLOG | LY_LOSTORE);
/* Initialize libyang container for native models. */
- ly_native_ctx = yang_ctx_new_setup(embedded_modules);
+ ly_native_ctx = yang_ctx_new_setup(embedded_modules, defer_compile);
if (!ly_native_ctx) {
flog_err(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);
exit(1);
@@ -729,6 +750,17 @@ void yang_init(bool embedded_modules)
yang_translator_init();
}
+void yang_init_loading_complete(void)
+{
+ /* Compile everything */
+ if (ly_ctx_compile(ly_native_ctx) != LY_SUCCESS) {
+ flog_err(EC_LIB_YANG_MODULE_LOAD,
+ "%s: failed to compile loaded modules: %s", __func__,
+ ly_errmsg(ly_native_ctx));
+ exit(1);
+ }
+}
+
void yang_terminate(void)
{
struct yang_module *module;
@@ -748,7 +780,7 @@ void yang_terminate(void)
XFREE(MTYPE_YANG_MODULE, module);
}
- ly_ctx_destroy(ly_native_ctx, NULL);
+ ly_ctx_destroy(ly_native_ctx);
}
const struct lyd_node *yang_dnode_get_parent(const struct lyd_node *dnode,
@@ -767,7 +799,7 @@ const struct lyd_node *yang_dnode_get_parent(const struct lyd_node *dnode,
break;
}
- orig_dnode = orig_dnode->parent;
+ orig_dnode = lyd_parent(orig_dnode);
}
return NULL;
@@ -788,17 +820,17 @@ bool yang_is_last_list_dnode(const struct lyd_node *dnode)
bool yang_is_last_level_dnode(const struct lyd_node *dnode)
{
const struct lyd_node *parent;
- const struct lys_node_list *snode;
const struct lyd_node *key_leaf;
uint8_t keys_size;
switch (dnode->schema->nodetype) {
case LYS_LIST:
assert(dnode->parent);
- parent = dnode->parent;
- snode = (struct lys_node_list *)parent->schema;
+ parent = lyd_parent(dnode);
+ uint snode_num_keys = yang_snode_num_keys(parent->schema);
+ /* XXX libyang2: q: really don't understand this code. */
key_leaf = dnode->prev;
- for (keys_size = 1; keys_size < snode->keys_size; keys_size++)
+ for (keys_size = 1; keys_size < snode_num_keys; keys_size++)
key_leaf = key_leaf->prev;
if (key_leaf->prev == dnode)
return true;
@@ -812,13 +844,11 @@ bool yang_is_last_level_dnode(const struct lyd_node *dnode)
return false;
}
-
const struct lyd_node *
yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
{
bool parent = true;
const struct lyd_node *node;
- const struct lys_node_container *snode;
node = dnode;
if (node->schema->nodetype != LYS_LIST)
@@ -827,13 +857,11 @@ yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
while (parent) {
switch (node->schema->nodetype) {
case LYS_CONTAINER:
- snode = (struct lys_node_container *)node->schema;
- if ((!snode->presence)
- && yang_is_last_level_dnode(node)) {
+ if (!CHECK_FLAG(node->schema->flags, LYS_PRESENCE)) {
if (node->parent
&& (node->parent->schema->module
== dnode->schema->module))
- node = node->parent;
+ node = lyd_parent(node);
else
parent = false;
} else
@@ -845,7 +873,7 @@ yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
if (node->parent
&& (node->parent->schema->module
== dnode->schema->module))
- node = node->parent;
+ node = lyd_parent(node);
else
parent = false;
} else
@@ -867,7 +895,7 @@ uint32_t yang_get_list_pos(const struct lyd_node *node)
uint32_t yang_get_list_elements_count(const struct lyd_node *node)
{
unsigned int count;
- struct lys_node *schema;
+ const struct lysc_node *schema;
if (!node
|| ((node->schema->nodetype != LYS_LIST)
@@ -884,11 +912,3 @@ uint32_t yang_get_list_elements_count(const struct lyd_node *node)
} while (node);
return count;
}
-
-
-const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode)
-{
- if (dnode)
- return dnode->child;
- return NULL;
-}
diff --git a/lib/yang.h b/lib/yang.h
index b8bf07ee7e..d4517f969a 100644
--- a/lib/yang.h
+++ b/lib/yang.h
@@ -99,13 +99,10 @@ enum yang_iter_flags {
/* Filter RPC input/output nodes. */
YANG_ITER_FILTER_INPUT_OUTPUT = (1<<2),
-
- /* Filter implicitely created nodes. */
- YANG_ITER_FILTER_IMPLICIT = (1<<3),
};
/* Callback used by the yang_snodes_iterate_*() family of functions. */
-typedef int (*yang_iterate_cb)(const struct lys_node *snode, void *arg);
+typedef int (*yang_iterate_cb)(const struct lysc_node *snode, void *arg);
/* Callback used by the yang_dnode_iterate() function. */
typedef int (*yang_dnode_iter_cb)(const struct lyd_node *dnode, void *arg);
@@ -180,7 +177,7 @@ extern void yang_module_embed(struct yang_module_embed *embed);
* Returns:
* The return value of the last called callback.
*/
-extern int yang_snodes_iterate_subtree(const struct lys_node *snode,
+extern int yang_snodes_iterate_subtree(const struct lysc_node *snode,
const struct lys_module *module,
yang_iterate_cb cb, uint16_t flags,
void *arg);
@@ -222,7 +219,7 @@ extern int yang_snodes_iterate(const struct lys_module *module,
* xpath_len
* Size of the xpath buffer.
*/
-extern void yang_snode_get_path(const struct lys_node *snode,
+extern void yang_snode_get_path(const struct lysc_node *snode,
enum yang_path_type type, char *xpath,
size_t xpath_len);
@@ -236,7 +233,7 @@ extern void yang_snode_get_path(const struct lys_node *snode,
* Returns:
* The parent libyang schema node if found, or NULL if not found.
*/
-extern struct lys_node *yang_snode_real_parent(const struct lys_node *snode);
+extern struct lysc_node *yang_snode_real_parent(const struct lysc_node *snode);
/*
* Find first parent schema node which is a list.
@@ -247,7 +244,7 @@ extern struct lys_node *yang_snode_real_parent(const struct lys_node *snode);
* Returns:
* The parent libyang schema node (list) if found, or NULL if not found.
*/
-extern struct lys_node *yang_snode_parent_list(const struct lys_node *snode);
+extern struct lysc_node *yang_snode_parent_list(const struct lysc_node *snode);
/*
* Check if the libyang schema node represents typeless data (e.g. containers,
@@ -259,7 +256,7 @@ extern struct lys_node *yang_snode_parent_list(const struct lys_node *snode);
* Returns:
* true if the schema node represents typeless data, false otherwise.
*/
-extern bool yang_snode_is_typeless_data(const struct lys_node *snode);
+extern bool yang_snode_is_typeless_data(const struct lysc_node *snode);
/*
* Get the default value associated to a YANG leaf or leaf-list.
@@ -270,7 +267,7 @@ extern bool yang_snode_is_typeless_data(const struct lys_node *snode);
* Returns:
* The default value if it exists, NULL otherwise.
*/
-extern const char *yang_snode_get_default(const struct lys_node *snode);
+extern const char *yang_snode_get_default(const struct lysc_node *snode);
/*
* Get the type structure of a leaf of leaf-list. If the type is a leafref, the
@@ -283,7 +280,27 @@ extern const char *yang_snode_get_default(const struct lys_node *snode);
* The found type if the schema node represents a leaf or a leaf-list, NULL
* otherwise.
*/
-extern const struct lys_type *yang_snode_get_type(const struct lys_node *snode);
+extern const struct lysc_type *
+yang_snode_get_type(const struct lysc_node *snode);
+
+/*
+ * Get the number of key nodes for the given list.
+ *
+ * snode
+ * libyang (LYS_LIST) schema node to operate on.
+ *
+ * Returns:
+ * The number of key LYS_LEAFs as children of this list node.
+ */
+extern unsigned int yang_snode_num_keys(const struct lysc_node *snode);
+
+#define LY_FOR_KEYS(snode, skey) \
+ for ((skey) = (const struct lysc_node_leaf *)lysc_node_child((snode)); \
+ (skey); (skey) = (const struct lysc_node_leaf *)((skey)->next)) \
+ if (!lysc_is_key(skey)) { \
+ break; \
+ } else
+
/*
* Build data path of the data node.
@@ -322,14 +339,49 @@ extern const char *yang_dnode_get_schema_name(const struct lyd_node *dnode,
* dnode
* Base libyang data node to operate on.
*
- * xpath_fmt
- * XPath expression (absolute or relative).
+ * xpath
+ * Limited XPath (absolute or relative) string. See Path in libyang
+ * documentation for restrictions.
*
* Returns:
* The libyang data node if found, or NULL if not found.
*/
extern struct lyd_node *yang_dnode_get(const struct lyd_node *dnode,
- const char *xpath_fmt, ...);
+ const char *xpath);
+
+/*
+ * Find a libyang data node by its YANG data path.
+ *
+ * dnode
+ * Base libyang data node to operate on.
+ *
+ * xpath_fmt
+ * Limited XPath (absolute or relative) format string. See Path in libyang
+ * documentation for restrictions.
+ *
+ * ...
+ * any parameters for xpath_fmt.
+ *
+ * Returns:
+ * The libyang data node if found, or NULL if not found.
+ */
+extern struct lyd_node *yang_dnode_getf(const struct lyd_node *dnode,
+ const char *path_fmt, ...);
+
+/*
+ * Check if a libyang data node exists.
+ *
+ * dnode
+ * Base libyang data node to operate on.
+ *
+ * xpath
+ * Limited XPath (absolute or relative) string. See Path in libyang
+ * documentation for restrictions.
+ *
+ * Returns:
+ * true if a libyang data node was found, false otherwise.
+ */
+extern bool yang_dnode_exists(const struct lyd_node *dnode, const char *xpath);
/*
* Check if a libyang data node exists.
@@ -338,13 +390,17 @@ extern struct lyd_node *yang_dnode_get(const struct lyd_node *dnode,
* Base libyang data node to operate on.
*
* xpath_fmt
- * XPath expression (absolute or relative).
+ * Limited XPath (absolute or relative) format string. See Path in
+ * libyang documentation for restrictions.
+ *
+ * ...
+ * any parameters for xpath_fmt.
*
* Returns:
- * true if the libyang data node was found, false otherwise.
+ * true if a libyang data node was found, false otherwise.
*/
-extern bool yang_dnode_exists(const struct lyd_node *dnode,
- const char *xpath_fmt, ...);
+extern bool yang_dnode_existsf(const struct lyd_node *dnode,
+ const char *xpath_fmt, ...);
/*
* Iterate over all libyang data nodes that satisfy an XPath query.
@@ -360,6 +416,9 @@ extern bool yang_dnode_exists(const struct lyd_node *dnode,
*
* xpath_fmt
* XPath expression (absolute or relative).
+ *
+ * ...
+ * any parameters for xpath_fmt.
*/
void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
const struct lyd_node *dnode, const char *xpath_fmt,
@@ -372,7 +431,7 @@ void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
* dnode
* Base libyang data node to operate on.
*
- * xpath_fmt
+ * xpath
* Optional XPath expression (absolute or relative) to specify a different
* data node to operate on in the same data tree.
*
@@ -380,7 +439,27 @@ void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
* true if the data node contains the default value, false otherwise.
*/
extern bool yang_dnode_is_default(const struct lyd_node *dnode,
- const char *xpath_fmt, ...);
+ const char *xpath);
+
+/*
+ * Check if the libyang data node contains a default value. Non-presence
+ * containers are assumed to always contain a default value.
+ *
+ * dnode
+ * Base libyang data node to operate on.
+ *
+ * xpath
+ * Optional limited XPath (absolute or relative) format string. See Path in
+ * libyang documentation for restrictions.
+ *
+ * ...
+ * any parameters for xpath_fmt.
+ *
+ * Returns:
+ * true if the data node contains the default value, false otherwise.
+ */
+extern bool yang_dnode_is_defaultf(const struct lyd_node *dnode,
+ const char *xpath_fmt, ...);
/*
* Check if the libyang data node and all of its children contain default
@@ -437,7 +516,8 @@ extern struct lyd_node *yang_dnode_dup(const struct lyd_node *dnode);
* Delete a libyang data node.
*
* dnode
- * Pointer to the libyang data node that is going to be deleted.
+ * Pointer to the libyang data node that is going to be deleted along with
+ * the entire tree it belongs to.
*/
extern void yang_dnode_free(struct lyd_node *dnode);
@@ -493,8 +573,13 @@ extern struct yang_data *yang_data_list_find(const struct list *list,
*
* embedded_modules
* Specify whether libyang should attempt to look for embedded YANG modules.
+ *
+ * explicit_compile
+ * True if the caller will later call ly_ctx_compile to compile all loaded
+ * modules at once.
*/
-extern struct ly_ctx *yang_ctx_new_setup(bool embedded_modules);
+extern struct ly_ctx *yang_ctx_new_setup(bool embedded_modules,
+ bool explicit_compile);
/*
* Enable or disable libyang verbose debugging.
@@ -528,8 +613,16 @@ extern const char *yang_print_errors(struct ly_ctx *ly_ctx, char *buf,
*
* embedded_modules
* Specify whether libyang should attempt to look for embedded YANG modules.
+ * defer_compile
+ * Hold off on compiling modules until yang_init_loading_complete is called.
*/
-extern void yang_init(bool embedded_modules);
+extern void yang_init(bool embedded_modules, bool defer_compile);
+
+/*
+ * Should be called after yang_init and all yang_module_load()s have been done,
+ * compiles all modules loaded into the yang context.
+ */
+extern void yang_init_loading_complete(void);
/*
* Finish the YANG subsystem gracefully. Should be called only when the daemon
@@ -583,10 +676,6 @@ extern uint32_t yang_get_list_pos(const struct lyd_node *node);
*/
extern uint32_t yang_get_list_elements_count(const struct lyd_node *node);
-
-/* To get the immediate child of a dnode */
-const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode);
-
/* API to check if the given node is last node in the list */
bool yang_is_last_list_dnode(const struct lyd_node *dnode);
diff --git a/lib/yang_translator.c b/lib/yang_translator.c
index 5b1d96f24c..d562e4d29e 100644
--- a/lib/yang_translator.c
+++ b/lib/yang_translator.c
@@ -93,7 +93,7 @@ yang_mapping_lookup(const struct yang_translator *translator, int dir,
}
static void yang_mapping_add(struct yang_translator *translator, int dir,
- const struct lys_node *snode,
+ const struct lysc_node *snode,
const char *xpath_from_fmt,
const char *xpath_to_fmt)
{
@@ -135,13 +135,15 @@ struct yang_translator *yang_translator_load(const char *path)
struct lyd_node *dnode;
struct ly_set *set;
struct listnode *ln;
+ LY_ERR err;
/* Load module translator (JSON file). */
- dnode = lyd_parse_path(ly_translator_ctx, path, LYD_JSON,
- LYD_OPT_CONFIG);
- if (!dnode) {
+ err = lyd_parse_data_path(ly_translator_ctx, path, LYD_JSON,
+ LYD_PARSE_NO_STATE, LYD_VALIDATE_NO_STATE,
+ &dnode);
+ if (err) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
- "%s: lyd_parse_path() failed", __func__);
+ "%s: lyd_parse_path() failed: %d", __func__, err);
return NULL;
}
dnode = yang_dnode_get(dnode,
@@ -171,89 +173,94 @@ struct yang_translator *yang_translator_load(const char *path)
RB_INSERT(yang_translators, &yang_translators, translator);
/* Initialize the translator libyang context. */
- translator->ly_ctx = yang_ctx_new_setup(false);
+ translator->ly_ctx = yang_ctx_new_setup(false, false);
if (!translator->ly_ctx) {
flog_warn(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);
goto error;
}
- /* Load modules and deviations. */
- set = lyd_find_path(dnode, "./module");
- assert(set);
- for (size_t i = 0; i < set->number; i++) {
+ /* Load modules */
+ if (lyd_find_xpath(dnode, "./module", &set) != LY_SUCCESS)
+ assert(0); /* XXX libyang2: old ly1 code asserted success */
+
+ for (size_t i = 0; i < set->count; i++) {
const char *module_name;
tmodule =
XCALLOC(MTYPE_YANG_TRANSLATOR_MODULE, sizeof(*tmodule));
- module_name = yang_dnode_get_string(set->set.d[i], "./name");
+ module_name = yang_dnode_get_string(set->dnodes[i], "./name");
tmodule->module = ly_ctx_load_module(translator->ly_ctx,
- module_name, NULL);
+ module_name, NULL, NULL);
if (!tmodule->module) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: failed to load module: %s", __func__,
module_name);
- ly_set_free(set);
+ ly_set_free(set, NULL);
goto error;
}
+ }
- module_name =
- yang_dnode_get_string(set->set.d[i], "./deviations");
- tmodule->deviations = ly_ctx_load_module(translator->ly_ctx,
- module_name, NULL);
+ /* Count nodes in modules. */
+ for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) {
+ tmodule->nodes_before_deviations =
+ yang_module_nodes_count(tmodule->module);
+ }
+
+ /* Load the deviations and count nodes again */
+ for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) {
+ const char *module_name = tmodule->module->name;
+ tmodule->deviations = ly_ctx_load_module(
+ translator->ly_ctx, module_name, NULL, NULL);
if (!tmodule->deviations) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: failed to load module: %s", __func__,
module_name);
- ly_set_free(set);
+ ly_set_free(set, NULL);
goto error;
}
- lys_set_disabled(tmodule->deviations);
- listnode_add(translator->modules, tmodule);
+ tmodule->nodes_after_deviations =
+ yang_module_nodes_count(tmodule->module);
}
- ly_set_free(set);
+ ly_set_free(set, NULL);
/* Calculate the coverage. */
for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) {
- tmodule->nodes_before_deviations =
- yang_module_nodes_count(tmodule->module);
-
- lys_set_enabled(tmodule->deviations);
-
- tmodule->nodes_after_deviations =
- yang_module_nodes_count(tmodule->module);
tmodule->coverage = ((double)tmodule->nodes_after_deviations
/ (double)tmodule->nodes_before_deviations)
* 100;
}
/* Load mappings. */
- set = lyd_find_path(dnode, "./module/mappings");
- assert(set);
- for (size_t i = 0; i < set->number; i++) {
+ if (lyd_find_xpath(dnode, "./module/mappings", &set) != LY_SUCCESS)
+ assert(0); /* XXX libyang2: old ly1 code asserted success */
+ for (size_t i = 0; i < set->count; i++) {
const char *xpath_custom, *xpath_native;
- const struct lys_node *snode_custom, *snode_native;
+ const struct lysc_node *snode_custom, *snode_native;
+
+ xpath_custom =
+ yang_dnode_get_string(set->dnodes[i], "./custom");
- xpath_custom = yang_dnode_get_string(set->set.d[i], "./custom");
- snode_custom = ly_ctx_get_node(translator->ly_ctx, NULL,
- xpath_custom, 0);
+ snode_custom = lys_find_path(translator->ly_ctx, NULL,
+ xpath_custom, 0);
if (!snode_custom) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: unknown data path: %s", __func__,
xpath_custom);
- ly_set_free(set);
+ ly_set_free(set, NULL);
goto error;
}
- xpath_native = yang_dnode_get_string(set->set.d[i], "./native");
+ xpath_native =
+ yang_dnode_get_string(set->dnodes[i], "./native");
snode_native =
- ly_ctx_get_node(ly_native_ctx, NULL, xpath_native, 0);
+ lys_find_path(ly_native_ctx, NULL, xpath_native, 0);
if (!snode_native) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: unknown data path: %s", __func__,
xpath_native);
- ly_set_free(set);
+ ly_set_free(set, NULL);
goto error;
}
@@ -262,7 +269,7 @@ struct yang_translator *yang_translator_load(const char *path)
yang_mapping_add(translator, YANG_TRANSLATE_FROM_NATIVE,
snode_native, xpath_native, xpath_custom);
}
- ly_set_free(set);
+ ly_set_free(set, NULL);
/* Validate mappings. */
if (yang_translator_validate(translator) != 0)
@@ -290,7 +297,7 @@ void yang_translator_unload(struct yang_translator *translator)
hash_clean(translator->mappings[i], yang_mapping_hash_free);
translator->modules->del = (void (*)(void *))yang_tmodule_delete;
list_delete(&translator->modules);
- ly_ctx_destroy(translator->ly_ctx, NULL);
+ ly_ctx_destroy(translator->ly_ctx);
RB_REMOVE(yang_translators, &yang_translators, translator);
XFREE(MTYPE_YANG_TRANSLATOR, translator);
}
@@ -308,7 +315,7 @@ yang_translate_xpath(const struct yang_translator *translator, int dir,
char *xpath, size_t xpath_len)
{
struct ly_ctx *ly_ctx;
- const struct lys_node *snode;
+ const struct lysc_node *snode;
struct yang_mapping_node *mapping;
char xpath_canonical[XPATH_MAXLEN];
char keys[4][LIST_MAXKEYLEN];
@@ -319,7 +326,7 @@ yang_translate_xpath(const struct yang_translator *translator, int dir,
else
ly_ctx = ly_native_ctx;
- snode = ly_ctx_get_node(ly_ctx, NULL, xpath, 0);
+ snode = lys_find_path(ly_ctx, NULL, xpath, 0);
if (!snode) {
flog_warn(EC_LIB_YANG_TRANSLATION_ERROR,
"%s: unknown data path: %s", __func__, xpath);
@@ -352,7 +359,7 @@ int yang_translate_dnode(const struct yang_translator *translator, int dir,
{
struct ly_ctx *ly_ctx;
struct lyd_node *new;
- struct lyd_node *root, *next, *dnode_iter;
+ struct lyd_node *root, *dnode_iter;
/* Create new libyang data node to hold the translated data. */
if (dir == YANG_TRANSLATE_TO_NATIVE)
@@ -362,8 +369,8 @@ int yang_translate_dnode(const struct yang_translator *translator, int dir,
new = yang_dnode_new(ly_ctx, false);
/* Iterate over all nodes from the data tree. */
- LY_TREE_FOR (*dnode, root) {
- LY_TREE_DFS_BEGIN (root, next, dnode_iter) {
+ LY_LIST_FOR (*dnode, root) {
+ LYD_TREE_DFS_BEGIN (root, dnode_iter) {
char xpath[XPATH_MAXLEN];
enum yang_translate_result ret;
@@ -380,19 +387,17 @@ int yang_translate_dnode(const struct yang_translator *translator, int dir,
}
/* Create new node in the tree of translated data. */
- ly_errno = 0;
- if (!lyd_new_path(new, ly_ctx, xpath,
- (void *)yang_dnode_get_string(
- dnode_iter, NULL),
- 0, LYD_PATH_OPT_UPDATE)
- && ly_errno) {
+ if (lyd_new_path(new, ly_ctx, xpath,
+ (void *)yang_dnode_get_string(
+ dnode_iter, NULL),
+ LYD_NEW_PATH_UPDATE, NULL)) {
flog_err(EC_LIB_LIBYANG,
"%s: lyd_new_path() failed", __func__);
goto error;
}
next:
- LY_TREE_DFS_END(root, next, dnode_iter);
+ LYD_TREE_DFS_END(root, dnode_iter);
}
}
@@ -413,13 +418,13 @@ struct translator_validate_args {
unsigned int errors;
};
-static int yang_translator_validate_cb(const struct lys_node *snode_custom,
+static int yang_translator_validate_cb(const struct lysc_node *snode_custom,
void *arg)
{
struct translator_validate_args *args = arg;
struct yang_mapping_node *mapping;
- const struct lys_node *snode_native;
- const struct lys_type *stype_custom, *stype_native;
+ const struct lysc_node *snode_native;
+ const struct lysc_type *stype_custom, *stype_native;
char xpath[XPATH_MAXLEN];
yang_snode_get_path(snode_custom, YANG_PATH_DATA, xpath, sizeof(xpath));
@@ -433,14 +438,14 @@ static int yang_translator_validate_cb(const struct lys_node *snode_custom,
}
snode_native =
- ly_ctx_get_node(ly_native_ctx, NULL, mapping->xpath_to_fmt, 0);
+ lys_find_path(ly_native_ctx, NULL, mapping->xpath_to_fmt, 0);
assert(snode_native);
/* Check if the YANG types are compatible. */
stype_custom = yang_snode_get_type(snode_custom);
stype_native = yang_snode_get_type(snode_native);
if (stype_custom && stype_native) {
- if (stype_custom->base != stype_native->base) {
+ if (stype_custom->basetype != stype_native->basetype) {
flog_warn(
EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: YANG types are incompatible (xpath: \"%s\")",
@@ -486,7 +491,7 @@ static unsigned int yang_translator_validate(struct yang_translator *translator)
return args.errors;
}
-static int yang_module_nodes_count_cb(const struct lys_node *snode, void *arg)
+static int yang_module_nodes_count_cb(const struct lysc_node *snode, void *arg)
{
unsigned int *total = arg;
@@ -511,14 +516,14 @@ static unsigned int yang_module_nodes_count(const struct lys_module *module)
void yang_translator_init(void)
{
- ly_translator_ctx = yang_ctx_new_setup(true);
+ ly_translator_ctx = yang_ctx_new_setup(true, false);
if (!ly_translator_ctx) {
flog_err(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);
exit(1);
}
if (!ly_ctx_load_module(ly_translator_ctx, "frr-module-translator",
- NULL)) {
+ NULL, NULL)) {
flog_err(
EC_LIB_YANG_MODULE_LOAD,
"%s: failed to load the \"frr-module-translator\" module",
@@ -536,5 +541,5 @@ void yang_translator_terminate(void)
yang_translator_unload(translator);
}
- ly_ctx_destroy(ly_translator_ctx, NULL);
+ ly_ctx_destroy(ly_translator_ctx);
}
diff --git a/lib/yang_wrappers.c b/lib/yang_wrappers.c
index 98f8fea0fe..85aa003db7 100644
--- a/lib/yang_wrappers.c
+++ b/lib/yang_wrappers.c
@@ -26,12 +26,80 @@
#include "nexthop.h"
#include "printfrr.h"
+
+#define YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt) \
+ ({ \
+ va_list __ap; \
+ va_start(__ap, (xpath_fmt)); \
+ const struct lyd_value *__dvalue = \
+ yang_dnode_xpath_get_value(dnode, xpath_fmt, __ap); \
+ va_end(__ap); \
+ __dvalue; \
+ })
+
+#define YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt) \
+ ({ \
+ va_list __ap; \
+ va_start(__ap, (xpath_fmt)); \
+ const char *__canon = \
+ yang_dnode_xpath_get_canon(dnode, xpath_fmt, __ap); \
+ va_end(__ap); \
+ __canon; \
+ })
+
+#define YANG_DNODE_GET_ASSERT(dnode, xpath) \
+ do { \
+ if ((dnode) == NULL) { \
+ flog_err(EC_LIB_YANG_DNODE_NOT_FOUND, \
+ "%s: couldn't find %s", __func__, (xpath)); \
+ zlog_backtrace(LOG_ERR); \
+ abort(); \
+ } \
+ } while (0)
+
+static inline const char *
+yang_dnode_xpath_get_canon(const struct lyd_node *dnode, const char *xpath_fmt,
+ va_list ap)
+{
+ const struct lyd_node_term *__dleaf =
+ (const struct lyd_node_term *)dnode;
+ assert(__dleaf);
+ if (xpath_fmt) {
+ char __xpath[XPATH_MAXLEN];
+ vsnprintf(__xpath, sizeof(__xpath), xpath_fmt, ap);
+ __dleaf = (const struct lyd_node_term *)yang_dnode_get(dnode,
+ __xpath);
+ YANG_DNODE_GET_ASSERT(__dleaf, __xpath);
+ }
+ return lyd_get_value(&__dleaf->node);
+}
+
+static inline const struct lyd_value *
+yang_dnode_xpath_get_value(const struct lyd_node *dnode, const char *xpath_fmt,
+ va_list ap)
+{
+ const struct lyd_node_term *__dleaf =
+ (const struct lyd_node_term *)dnode;
+ assert(__dleaf);
+ if (xpath_fmt) {
+ char __xpath[XPATH_MAXLEN];
+ vsnprintf(__xpath, sizeof(__xpath), xpath_fmt, ap);
+ __dleaf = (const struct lyd_node_term *)yang_dnode_get(dnode,
+ __xpath);
+ YANG_DNODE_GET_ASSERT(__dleaf, __xpath);
+ }
+ const struct lyd_value *__dvalue = &__dleaf->value;
+ if (__dvalue->realtype->basetype == LY_TYPE_UNION)
+ __dvalue = &__dvalue->subvalue->value;
+ return __dvalue;
+}
+
static const char *yang_get_default_value(const char *xpath)
{
- const struct lys_node *snode;
+ const struct lysc_node *snode;
const char *value;
- snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
+ snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
if (snode == NULL) {
flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
"%s: unknown data path: %s", __func__, xpath);
@@ -45,16 +113,6 @@ static const char *yang_get_default_value(const char *xpath)
return value;
}
-#define YANG_DNODE_GET_ASSERT(dnode, xpath) \
- do { \
- if ((dnode) == NULL) { \
- flog_err(EC_LIB_YANG_DNODE_NOT_FOUND, \
- "%s: couldn't find %s", __func__, (xpath)); \
- zlog_backtrace(LOG_ERR); \
- abort(); \
- } \
- } while (0)
-
/*
* Primitive type: bool.
*/
@@ -71,23 +129,10 @@ struct yang_data *yang_data_new_bool(const char *xpath, bool value)
bool yang_dnode_get_bool(const struct lyd_node *dnode, const char *xpath_fmt,
...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_BOOL);
- return dleaf->value.bln;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_BOOL);
+ return dvalue->boolean;
}
bool yang_get_default_bool(const char *xpath_fmt, ...)
@@ -133,24 +178,18 @@ struct yang_data *yang_data_new_dec64(const char *xpath, double value)
double yang_dnode_get_dec64(const struct lyd_node *dnode, const char *xpath_fmt,
...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
+ const double denom[19] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4,
+ 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
+ 1e-10, 1e-11, 1e-12, 1e-13, 1e-14,
+ 1e-15, 1e-16, 1e-17, 1e-18};
+ const struct lysc_type_dec *dectype;
+ const struct lyd_value *dvalue;
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_DEC64);
-
- return lyd_dec64_to_double(dnode);
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ dectype = (const struct lysc_type_dec *)dvalue->realtype;
+ assert(dectype->basetype == LY_TYPE_DEC64);
+ assert(dectype->fraction_digits < sizeof(denom) / sizeof(*denom));
+ return (double)dvalue->dec64 * denom[dectype->fraction_digits];
}
double yang_get_default_dec64(const char *xpath_fmt, ...)
@@ -172,12 +211,12 @@ double yang_get_default_dec64(const char *xpath_fmt, ...)
*/
int yang_str2enum(const char *xpath, const char *value)
{
- const struct lys_node *snode;
- const struct lys_node_leaf *sleaf;
- const struct lys_type *type;
- const struct lys_type_info_enums *enums;
+ const struct lysc_node *snode;
+ const struct lysc_node_leaf *sleaf;
+ const struct lysc_type_enum *type;
+ const struct lysc_type_bitenum_item *enums;
- snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
+ snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
if (snode == NULL) {
flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
"%s: unknown data path: %s", __func__, xpath);
@@ -185,18 +224,17 @@ int yang_str2enum(const char *xpath, const char *value)
abort();
}
- sleaf = (const struct lys_node_leaf *)snode;
- type = &sleaf->type;
- enums = &type->info.enums;
- while (enums->count == 0 && type->der) {
- type = &type->der->type;
- enums = &type->info.enums;
- }
- for (unsigned int i = 0; i < enums->count; i++) {
- const struct lys_type_enum *enm = &enums->enm[i];
-
- if (strmatch(value, enm->name))
- return enm->value;
+ assert(snode->nodetype == LYS_LEAF);
+ sleaf = (const struct lysc_node_leaf *)snode;
+ type = (const struct lysc_type_enum *)sleaf->type;
+ assert(type->basetype == LY_TYPE_ENUM);
+ enums = type->enums;
+ unsigned int count = LY_ARRAY_COUNT(enums);
+ for (unsigned int i = 0; i < count; i++) {
+ if (strmatch(value, enums[i].name)) {
+ assert(CHECK_FLAG(enums[i].flags, LYS_SET_VALUE));
+ return enums[i].value;
+ }
}
flog_err(EC_LIB_YANG_DATA_CONVERT,
@@ -208,12 +246,12 @@ int yang_str2enum(const char *xpath, const char *value)
struct yang_data *yang_data_new_enum(const char *xpath, int value)
{
- const struct lys_node *snode;
- const struct lys_node_leaf *sleaf;
- const struct lys_type *type;
- const struct lys_type_info_enums *enums;
+ const struct lysc_node *snode;
+ const struct lysc_node_leaf *sleaf;
+ const struct lysc_type_enum *type;
+ const struct lysc_type_bitenum_item *enums;
- snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
+ snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
if (snode == NULL) {
flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
"%s: unknown data path: %s", __func__, xpath);
@@ -221,18 +259,16 @@ struct yang_data *yang_data_new_enum(const char *xpath, int value)
abort();
}
- sleaf = (const struct lys_node_leaf *)snode;
- type = &sleaf->type;
- enums = &type->info.enums;
- while (enums->count == 0 && type->der) {
- type = &type->der->type;
- enums = &type->info.enums;
- }
- for (unsigned int i = 0; i < enums->count; i++) {
- const struct lys_type_enum *enm = &enums->enm[i];
-
- if (value == enm->value)
- return yang_data_new(xpath, enm->name);
+ assert(snode->nodetype == LYS_LEAF);
+ sleaf = (const struct lysc_node_leaf *)snode;
+ type = (const struct lysc_type_enum *)sleaf->type;
+ assert(type->basetype == LY_TYPE_ENUM);
+ enums = type->enums;
+ unsigned int count = LY_ARRAY_COUNT(enums);
+ for (unsigned int i = 0; i < count; i++) {
+ if (CHECK_FLAG(enums[i].flags, LYS_SET_VALUE)
+ && value == enums[i].value)
+ return yang_data_new(xpath, enums[i].name);
}
flog_err(EC_LIB_YANG_DATA_CONVERT,
@@ -245,23 +281,12 @@ struct yang_data *yang_data_new_enum(const char *xpath, int value)
int yang_dnode_get_enum(const struct lyd_node *dnode, const char *xpath_fmt,
...)
{
- const struct lyd_node_leaf_list *dleaf;
+ const struct lyd_value *dvalue;
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_ENUM);
- return dleaf->value.enm->value;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_ENUM);
+ assert(dvalue->enum_item->flags & LYS_SET_VALUE);
+ return dvalue->enum_item->value;
}
int yang_get_default_enum(const char *xpath_fmt, ...)
@@ -297,23 +322,10 @@ struct yang_data *yang_data_new_int8(const char *xpath, int8_t value)
int8_t yang_dnode_get_int8(const struct lyd_node *dnode, const char *xpath_fmt,
...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_INT8);
- return dleaf->value.int8;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_INT8);
+ return dvalue->int8;
}
int8_t yang_get_default_int8(const char *xpath_fmt, ...)
@@ -349,23 +361,10 @@ struct yang_data *yang_data_new_int16(const char *xpath, int16_t value)
int16_t yang_dnode_get_int16(const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_INT16);
- return dleaf->value.int16;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_INT16);
+ return dvalue->int16;
}
int16_t yang_get_default_int16(const char *xpath_fmt, ...)
@@ -401,23 +400,10 @@ struct yang_data *yang_data_new_int32(const char *xpath, int32_t value)
int32_t yang_dnode_get_int32(const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_INT32);
- return dleaf->value.int32;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_INT32);
+ return dvalue->int32;
}
int32_t yang_get_default_int32(const char *xpath_fmt, ...)
@@ -453,23 +439,10 @@ struct yang_data *yang_data_new_int64(const char *xpath, int64_t value)
int64_t yang_dnode_get_int64(const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_INT64);
- return dleaf->value.int64;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_INT64);
+ return dvalue->int64;
}
int64_t yang_get_default_int64(const char *xpath_fmt, ...)
@@ -505,23 +478,10 @@ struct yang_data *yang_data_new_uint8(const char *xpath, uint8_t value)
uint8_t yang_dnode_get_uint8(const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_UINT8);
- return dleaf->value.uint8;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_UINT8);
+ return dvalue->uint8;
}
uint8_t yang_get_default_uint8(const char *xpath_fmt, ...)
@@ -557,23 +517,10 @@ struct yang_data *yang_data_new_uint16(const char *xpath, uint16_t value)
uint16_t yang_dnode_get_uint16(const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_UINT16);
- return dleaf->value.uint16;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_UINT16);
+ return dvalue->uint16;
}
uint16_t yang_get_default_uint16(const char *xpath_fmt, ...)
@@ -609,23 +556,10 @@ struct yang_data *yang_data_new_uint32(const char *xpath, uint32_t value)
uint32_t yang_dnode_get_uint32(const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_UINT32);
- return dleaf->value.uint32;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_UINT32);
+ return dvalue->uint32;
}
uint32_t yang_get_default_uint32(const char *xpath_fmt, ...)
@@ -661,23 +595,10 @@ struct yang_data *yang_data_new_uint64(const char *xpath, uint64_t value)
uint64_t yang_dnode_get_uint64(const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_UINT64);
- return dleaf->value.uint64;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_UINT64);
+ return dvalue->uint64;
}
uint64_t yang_get_default_uint64(const char *xpath_fmt, ...)
@@ -707,44 +628,15 @@ struct yang_data *yang_data_new_string(const char *xpath, const char *value)
const char *yang_dnode_get_string(const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- return dleaf->value_str;
+ return YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
}
void yang_dnode_get_string_buf(char *buf, size_t size,
const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- if (strlcpy(buf, dleaf->value_str, size) >= size) {
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ if (strlcpy(buf, canon, size) >= size) {
char xpath[XPATH_MAXLEN];
yang_dnode_get_path(dnode, xpath, sizeof(xpath));
@@ -797,7 +689,7 @@ bool yang_dnode_get_empty(const struct lyd_node *dnode, const char *xpath_fmt,
{
va_list ap;
char xpath[XPATH_MAXLEN];
- const struct lyd_node_leaf_list *dleaf;
+ const struct lyd_node_term *dleaf;
assert(dnode);
@@ -807,8 +699,8 @@ bool yang_dnode_get_empty(const struct lyd_node *dnode, const char *xpath_fmt,
dnode = yang_dnode_get(dnode, xpath);
if (dnode) {
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- if (dleaf->value_type == LY_TYPE_EMPTY)
+ dleaf = (const struct lyd_node_term *)dnode;
+ if (dleaf->value.realtype->basetype == LY_TYPE_EMPTY)
return true;
}
@@ -836,29 +728,16 @@ struct yang_data *yang_data_new_prefix(const char *xpath,
void yang_dnode_get_prefix(struct prefix *prefix, const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
+ const char *canon;
/*
* Initialize prefix to avoid static analyzer complaints about
* uninitialized memory.
*/
memset(prefix, 0, sizeof(*prefix));
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)str2prefix(dleaf->value_str, prefix);
+ /* XXX ip_prefix is a native type now in ly2, leverage? */
+ canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)str2prefix(canon, prefix);
}
void yang_get_default_prefix(union prefixptr var, const char *xpath_fmt, ...)
@@ -895,23 +774,9 @@ struct yang_data *yang_data_new_ipv4(const char *xpath,
void yang_dnode_get_ipv4(struct in_addr *addr, const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)inet_pton(AF_INET, dleaf->value_str, addr);
+ /* XXX libyang2 IPv4 address is a native type now in ly2 */
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)inet_pton(AF_INET, canon, addr);
}
void yang_get_default_ipv4(struct in_addr *var, const char *xpath_fmt, ...)
@@ -951,24 +816,10 @@ struct yang_data *yang_data_new_ipv4p(const char *xpath,
void yang_dnode_get_ipv4p(union prefixptr prefix, const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
struct prefix_ipv4 *prefix4 = prefix.p4;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)str2prefix_ipv4(dleaf->value_str, prefix4);
+ /* XXX libyang2: ipv4/6 address is a native type now in ly2 */
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)str2prefix_ipv4(canon, prefix4);
}
void yang_get_default_ipv4p(union prefixptr var, const char *xpath_fmt, ...)
@@ -1005,23 +856,9 @@ struct yang_data *yang_data_new_ipv6(const char *xpath,
void yang_dnode_get_ipv6(struct in6_addr *addr, const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)inet_pton(AF_INET6, dleaf->value_str, addr);
+ /* XXX libyang2: IPv6 address is a native type now, leverage. */
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)inet_pton(AF_INET6, canon, addr);
}
void yang_get_default_ipv6(struct in6_addr *var, const char *xpath_fmt, ...)
@@ -1061,24 +898,11 @@ struct yang_data *yang_data_new_ipv6p(const char *xpath,
void yang_dnode_get_ipv6p(union prefixptr prefix, const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
struct prefix_ipv6 *prefix6 = prefix.p6;
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)str2prefix_ipv6(dleaf->value_str, prefix6);
+ /* XXX IPv6 address is a native type now in ly2 -- can we leverage? */
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)str2prefix_ipv6(canon, prefix6);
}
void yang_get_default_ipv6p(union prefixptr var, const char *xpath_fmt, ...)
@@ -1115,23 +939,9 @@ struct yang_data *yang_data_new_ip(const char *xpath, const struct ipaddr *addr)
void yang_dnode_get_ip(struct ipaddr *addr, const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- assert(dnode);
- if (xpath_fmt) {
- va_list ap;
- char xpath[XPATH_MAXLEN];
-
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
- dnode = yang_dnode_get(dnode, xpath);
- YANG_DNODE_GET_ASSERT(dnode, xpath);
- }
-
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)str2ipaddr(dleaf->value_str, addr);
+ /* XXX IPv4 address could be a plugin type now in ly2, leverage? */
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)str2ipaddr(canon, addr);
}
void yang_get_default_ip(struct ipaddr *var, const char *xpath_fmt, ...)