forked from Mirror/frr
lib : Yang wrappers
1. To get the parent node 2. To auto delete the parent when last node in list gets deleted Signed-off-by: VishalDhingra <vdhingra@vmware.com>
This commit is contained in:
parent
565f463e30
commit
27802d3fee
144
lib/yang.c
144
lib/yang.c
|
@ -749,3 +749,147 @@ void yang_terminate(void)
|
|||
|
||||
ly_ctx_destroy(ly_native_ctx, NULL);
|
||||
}
|
||||
|
||||
const struct lyd_node *yang_dnode_get_parent(const struct lyd_node *dnode,
|
||||
const char *name)
|
||||
{
|
||||
const struct lyd_node *orig_dnode = dnode;
|
||||
|
||||
while (orig_dnode) {
|
||||
switch (orig_dnode->schema->nodetype) {
|
||||
case LYS_LIST:
|
||||
case LYS_CONTAINER:
|
||||
if (!strcmp(orig_dnode->schema->name, name))
|
||||
return orig_dnode;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
orig_dnode = orig_dnode->parent;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* API to check if the given node is last node in the list */
|
||||
static bool yang_is_last_list_dnode(const struct lyd_node *dnode)
|
||||
{
|
||||
return (((dnode->next == NULL)
|
||||
|| (dnode->next
|
||||
&& (strcmp(dnode->next->schema->name, dnode->schema->name)
|
||||
!= 0)))
|
||||
&& dnode->prev
|
||||
&& ((dnode->prev == dnode)
|
||||
|| (strcmp(dnode->prev->schema->name, dnode->schema->name)
|
||||
!= 0)));
|
||||
}
|
||||
|
||||
/* API to check if the given node is last node in the data tree level */
|
||||
static 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;
|
||||
key_leaf = dnode->prev;
|
||||
for (keys_size = 1; keys_size < snode->keys_size; keys_size++)
|
||||
key_leaf = key_leaf->prev;
|
||||
if (key_leaf->prev == dnode)
|
||||
return true;
|
||||
break;
|
||||
case LYS_CONTAINER:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
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)
|
||||
return node;
|
||||
|
||||
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 (node->parent
|
||||
&& (node->parent->schema->module
|
||||
== dnode->schema->module))
|
||||
node = node->parent;
|
||||
else
|
||||
parent = false;
|
||||
} else
|
||||
parent = false;
|
||||
break;
|
||||
case LYS_LIST:
|
||||
if (yang_is_last_list_dnode(node)
|
||||
&& yang_is_last_level_dnode(node)) {
|
||||
if (node->parent
|
||||
&& (node->parent->schema->module
|
||||
== dnode->schema->module))
|
||||
node = node->parent;
|
||||
else
|
||||
parent = false;
|
||||
} else
|
||||
parent = false;
|
||||
break;
|
||||
default:
|
||||
parent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
uint32_t yang_get_list_pos(const struct lyd_node *node)
|
||||
{
|
||||
return lyd_list_pos(node);
|
||||
}
|
||||
|
||||
uint32_t yang_get_list_elements_count(const struct lyd_node *node)
|
||||
{
|
||||
unsigned int count;
|
||||
struct lys_node *schema;
|
||||
|
||||
if (!node
|
||||
|| ((node->schema->nodetype != LYS_LIST)
|
||||
&& (node->schema->nodetype != LYS_LEAFLIST))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
schema = node->schema;
|
||||
count = 0;
|
||||
do {
|
||||
if (node->schema == schema)
|
||||
++count;
|
||||
node = node->next;
|
||||
} while (node);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode)
|
||||
{
|
||||
if (dnode)
|
||||
return dnode->child;
|
||||
return NULL;
|
||||
}
|
||||
|
|
53
lib/yang.h
53
lib/yang.h
|
@ -34,7 +34,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/* Maximum XPath length. */
|
||||
#define XPATH_MAXLEN 512
|
||||
#define XPATH_MAXLEN 1024
|
||||
|
||||
/* Maximum list key length. */
|
||||
#define LIST_MAXKEYS 8
|
||||
|
@ -551,6 +551,57 @@ extern void yang_init(bool embedded_modules);
|
|||
*/
|
||||
extern void yang_terminate(void);
|
||||
|
||||
/*
|
||||
* API to return the parent dnode having a given schema-node name
|
||||
* Use case: One has to access the parent dnode's private pointer
|
||||
* for a given child node.
|
||||
* For that there is a need to find parent dnode first.
|
||||
*
|
||||
* dnode The starting node to work on
|
||||
*
|
||||
* name The name of container/list schema-node
|
||||
*
|
||||
* Returns The dnode matched with the given name
|
||||
*/
|
||||
extern const struct lyd_node *
|
||||
yang_dnode_get_parent(const struct lyd_node *dnode, const char *name);
|
||||
|
||||
|
||||
/*
|
||||
* In some cases there is a need to auto delete the parent nodes
|
||||
* if the given node is last in the list.
|
||||
* It tries to delete all the parents in a given tree in a given module.
|
||||
* The use case is with static routes and route maps
|
||||
* example : ip route 1.1.1.1/32 ens33
|
||||
* ip route 1.1.1.1/32 ens34
|
||||
* After this no ip route 1.1.1.1/32 ens34 came, now staticd
|
||||
* has to find out upto which level it has to delete the dnodes.
|
||||
* For this case it has to send delete nexthop
|
||||
* After this no ip route 1.1.1.1/32 ens33 came, now staticd has to
|
||||
* clear nexthop, path and route nodes.
|
||||
* The same scheme is required for routemaps also
|
||||
* dnode The starting node to work on
|
||||
*
|
||||
* Returns The final parent node selected for deletion
|
||||
*/
|
||||
extern const struct lyd_node *
|
||||
yang_get_subtree_with_no_sibling(const struct lyd_node *dnode);
|
||||
|
||||
/* To get the relative position of a node in list */
|
||||
extern uint32_t yang_get_list_pos(const struct lyd_node *node);
|
||||
|
||||
/* To get the number of elements in a list
|
||||
*
|
||||
* dnode : The head of list
|
||||
* Returns : The number of dnodes present in the list
|
||||
*/
|
||||
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);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue