mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 06:03:10 +00:00
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>
This commit is contained in:
parent
e0ccfad220
commit
544ca69a5c
@ -51,6 +51,18 @@ static int nb_transaction_process(enum nb_event event,
|
|||||||
struct nb_transaction *transaction);
|
struct nb_transaction *transaction);
|
||||||
static void nb_transaction_apply_finish(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)
|
static int nb_node_new_cb(const struct lys_node *snode, void *arg)
|
||||||
{
|
{
|
||||||
struct nb_node *nb_node;
|
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)
|
if (sparent_list)
|
||||||
nb_node->parent_list = sparent_list->priv;
|
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
|
* Link the northbound node and the libyang schema node with one
|
||||||
* another.
|
* another.
|
||||||
@ -88,6 +111,16 @@ static int nb_node_del_cb(const struct lys_node *snode, void *arg)
|
|||||||
return YANG_ITER_CONTINUE;
|
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)
|
struct nb_node *nb_node_find(const char *xpath)
|
||||||
{
|
{
|
||||||
const struct lys_node *snode;
|
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,
|
bool nb_operation_is_valid(enum nb_operation operation,
|
||||||
const struct lys_node *snode)
|
const struct lys_node *snode)
|
||||||
{
|
{
|
||||||
|
struct nb_node *nb_node = snode->priv;
|
||||||
struct lys_node_container *scontainer;
|
struct lys_node_container *scontainer;
|
||||||
struct lys_node_leaf *sleaf;
|
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_NEXT:
|
||||||
case NB_OP_GET_KEYS:
|
case NB_OP_GET_KEYS:
|
||||||
case NB_OP_LOOKUP_ENTRY:
|
case NB_OP_LOOKUP_ENTRY:
|
||||||
if (!CHECK_FLAG(snode->flags, LYS_CONFIG_R))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (snode->nodetype) {
|
switch (snode->nodetype) {
|
||||||
case LYS_LIST:
|
case LYS_LIST:
|
||||||
|
if (CHECK_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
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);
|
yang_module_load(modules[i]->name);
|
||||||
|
|
||||||
/* Create a nb_node for all YANG schema nodes. */
|
/* 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. */
|
/* Load northbound callbacks. */
|
||||||
for (size_t i = 0; i < nmodules; i++)
|
for (size_t i = 0; i < nmodules; i++)
|
||||||
@ -1205,7 +1238,7 @@ void nb_terminate(void)
|
|||||||
nb_cli_terminate();
|
nb_cli_terminate();
|
||||||
|
|
||||||
/* Delete all nb_node's from all YANG modules. */
|
/* 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. */
|
/* Delete the running configuration. */
|
||||||
nb_config_free(running_config);
|
nb_config_free(running_config);
|
||||||
|
@ -349,11 +349,16 @@ struct nb_node {
|
|||||||
/* Pointer to the nearest parent list, if any. */
|
/* Pointer to the nearest parent list, if any. */
|
||||||
struct nb_node *parent_list;
|
struct nb_node *parent_list;
|
||||||
|
|
||||||
|
/* Flags. */
|
||||||
|
uint8_t flags;
|
||||||
|
|
||||||
#ifdef HAVE_CONFD
|
#ifdef HAVE_CONFD
|
||||||
/* ConfD hash value corresponding to this YANG path. */
|
/* ConfD hash value corresponding to this YANG path. */
|
||||||
int confd_hash;
|
int confd_hash;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
/* The YANG container or list contains only config data. */
|
||||||
|
#define F_NB_NODE_CONFIG_ONLY 0x01
|
||||||
|
|
||||||
struct frr_yang_module_info {
|
struct frr_yang_module_info {
|
||||||
/* YANG module name. */
|
/* YANG module name. */
|
||||||
@ -435,6 +440,16 @@ DECLARE_HOOK(nb_notification_send, (const char *xpath, struct list *arguments),
|
|||||||
extern int debug_northbound;
|
extern int debug_northbound;
|
||||||
extern struct nb_config *running_config;
|
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.
|
* Find the northbound node corresponding to a YANG data path.
|
||||||
*
|
*
|
||||||
|
@ -195,7 +195,8 @@ next:
|
|||||||
return YANG_ITER_CONTINUE;
|
return YANG_ITER_CONTINUE;
|
||||||
|
|
||||||
LY_TREE_FOR (snode->child, child) {
|
LY_TREE_FOR (snode->child, child) {
|
||||||
if (child->parent != snode)
|
if (!CHECK_FLAG(flags, YANG_ITER_ALLOW_AUGMENTATIONS)
|
||||||
|
&& child->parent != snode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = yang_snodes_iterate_subtree(child, cb, flags, arg);
|
ret = yang_snodes_iterate_subtree(child, cb, flags, arg);
|
||||||
|
@ -98,6 +98,9 @@ enum yang_iter_flags {
|
|||||||
|
|
||||||
/* Filter implicitely created nodes. */
|
/* Filter implicitely created nodes. */
|
||||||
YANG_ITER_FILTER_IMPLICIT = (1<<3),
|
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. */
|
/* Callback used by the yang_snodes_iterate_*() family of functions. */
|
||||||
|
@ -272,8 +272,15 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
yang_init();
|
yang_init();
|
||||||
|
|
||||||
/* Load YANG module. */
|
/* Load all FRR native models to ensure all augmentations are loaded. */
|
||||||
module = yang_module_load(argv[0]);
|
yang_module_load_all();
|
||||||
|
module = yang_module_find(argv[0]);
|
||||||
|
if (!module)
|
||||||
|
/* Non-native FRR module (e.g. modules from unit tests). */
|
||||||
|
module = yang_module_load(argv[0]);
|
||||||
|
|
||||||
|
/* Create a nb_node for all YANG schema nodes. */
|
||||||
|
nb_nodes_create();
|
||||||
|
|
||||||
/* Generate callback functions. */
|
/* Generate callback functions. */
|
||||||
yang_snodes_iterate_module(module->info, generate_callbacks, 0, NULL);
|
yang_snodes_iterate_module(module->info, generate_callbacks, 0, NULL);
|
||||||
@ -296,6 +303,7 @@ int main(int argc, char *argv[])
|
|||||||
"};\n");
|
"};\n");
|
||||||
|
|
||||||
/* Cleanup and exit. */
|
/* Cleanup and exit. */
|
||||||
|
nb_nodes_delete();
|
||||||
yang_terminate();
|
yang_terminate();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user