summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2018-11-13 20:36:48 -0200
committerRenato Westphal <renato@opensourcerouting.org>2018-11-26 17:38:08 -0200
commit544ca69a5cc7da81ad2f9f72110b34ee03b7cc44 (patch)
tree84daae9c8863af8bffae0ef910fbcc5f6f5f65f6 /lib
parente0ccfad220d80c1d02b327fd0ee24faf6a8d2bd4 (diff)
lib: add support for YANG lists with mixed config and state data
A YANG list that contains both configuration and state data must have the following callbacks: create(), delete(), get_next(), get_keys() and lookup_entry(). Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/northbound.c43
-rw-r--r--lib/northbound.h15
-rw-r--r--lib/yang.c3
-rw-r--r--lib/yang.h3
4 files changed, 58 insertions, 6 deletions
diff --git a/lib/northbound.c b/lib/northbound.c
index c6991680e0..f8045b89aa 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -51,6 +51,18 @@ static int nb_transaction_process(enum nb_event event,
struct nb_transaction *transaction);
static void nb_transaction_apply_finish(struct nb_transaction *transaction);
+static int nb_node_check_config_only(const struct lys_node *snode, void *arg)
+{
+ bool *config_only = arg;
+
+ if (CHECK_FLAG(snode->flags, LYS_CONFIG_R)) {
+ *config_only = false;
+ return YANG_ITER_STOP;
+ }
+
+ return YANG_ITER_CONTINUE;
+}
+
static int nb_node_new_cb(const struct lys_node *snode, void *arg)
{
struct nb_node *nb_node;
@@ -67,6 +79,17 @@ static int nb_node_new_cb(const struct lys_node *snode, void *arg)
if (sparent_list)
nb_node->parent_list = sparent_list->priv;
+ /* Set flags. */
+ if (CHECK_FLAG(snode->nodetype, LYS_CONTAINER | LYS_LIST)) {
+ bool config_only = true;
+
+ yang_snodes_iterate_subtree(snode, nb_node_check_config_only,
+ YANG_ITER_ALLOW_AUGMENTATIONS,
+ &config_only);
+ if (config_only)
+ SET_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY);
+ }
+
/*
* Link the northbound node and the libyang schema node with one
* another.
@@ -88,6 +111,16 @@ static int nb_node_del_cb(const struct lys_node *snode, void *arg)
return YANG_ITER_CONTINUE;
}
+void nb_nodes_create(void)
+{
+ yang_snodes_iterate_all(nb_node_new_cb, 0, NULL);
+}
+
+void nb_nodes_delete(void)
+{
+ yang_snodes_iterate_all(nb_node_del_cb, 0, NULL);
+}
+
struct nb_node *nb_node_find(const char *xpath)
{
const struct lys_node *snode;
@@ -900,6 +933,7 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
bool nb_operation_is_valid(enum nb_operation operation,
const struct lys_node *snode)
{
+ struct nb_node *nb_node = snode->priv;
struct lys_node_container *scontainer;
struct lys_node_leaf *sleaf;
@@ -1017,11 +1051,10 @@ bool nb_operation_is_valid(enum nb_operation operation,
case NB_OP_GET_NEXT:
case NB_OP_GET_KEYS:
case NB_OP_LOOKUP_ENTRY:
- if (!CHECK_FLAG(snode->flags, LYS_CONFIG_R))
- return false;
-
switch (snode->nodetype) {
case LYS_LIST:
+ if (CHECK_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY))
+ return false;
break;
default:
return false;
@@ -1170,7 +1203,7 @@ void nb_init(const struct frr_yang_module_info *modules[], size_t nmodules)
yang_module_load(modules[i]->name);
/* Create a nb_node for all YANG schema nodes. */
- yang_snodes_iterate_all(nb_node_new_cb, 0, NULL);
+ nb_nodes_create();
/* Load northbound callbacks. */
for (size_t i = 0; i < nmodules; i++)
@@ -1205,7 +1238,7 @@ void nb_terminate(void)
nb_cli_terminate();
/* Delete all nb_node's from all YANG modules. */
- yang_snodes_iterate_all(nb_node_del_cb, 0, NULL);
+ nb_nodes_delete();
/* Delete the running configuration. */
nb_config_free(running_config);
diff --git a/lib/northbound.h b/lib/northbound.h
index 8ab6662ecc..68bce5b398 100644
--- a/lib/northbound.h
+++ b/lib/northbound.h
@@ -349,11 +349,16 @@ struct nb_node {
/* Pointer to the nearest parent list, if any. */
struct nb_node *parent_list;
+ /* Flags. */
+ uint8_t flags;
+
#ifdef HAVE_CONFD
/* ConfD hash value corresponding to this YANG path. */
int confd_hash;
#endif
};
+/* The YANG container or list contains only config data. */
+#define F_NB_NODE_CONFIG_ONLY 0x01
struct frr_yang_module_info {
/* YANG module name. */
@@ -436,6 +441,16 @@ extern int debug_northbound;
extern struct nb_config *running_config;
/*
+ * Create a northbound node for all YANG schema nodes.
+ */
+void nb_nodes_create(void);
+
+/*
+ * Delete all northbound nodes from all YANG schema nodes.
+ */
+void nb_nodes_delete(void);
+
+/*
* Find the northbound node corresponding to a YANG data path.
*
* xpath
diff --git a/lib/yang.c b/lib/yang.c
index 6b797ffde3..e426b3af3e 100644
--- a/lib/yang.c
+++ b/lib/yang.c
@@ -195,7 +195,8 @@ next:
return YANG_ITER_CONTINUE;
LY_TREE_FOR (snode->child, child) {
- if (child->parent != snode)
+ if (!CHECK_FLAG(flags, YANG_ITER_ALLOW_AUGMENTATIONS)
+ && child->parent != snode)
continue;
ret = yang_snodes_iterate_subtree(child, cb, flags, arg);
diff --git a/lib/yang.h b/lib/yang.h
index 940f5d38e8..2c18017af2 100644
--- a/lib/yang.h
+++ b/lib/yang.h
@@ -98,6 +98,9 @@ enum yang_iter_flags {
/* Filter implicitely created nodes. */
YANG_ITER_FILTER_IMPLICIT = (1<<3),
+
+ /* Allow iteration over augmentations. */
+ YANG_ITER_ALLOW_AUGMENTATIONS = (1<<4),
};
/* Callback used by the yang_snodes_iterate_*() family of functions. */