mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 17:18:56 +00:00
lib: make yang_dnode_get_entry() more flexible
Add the "abort_if_not_found" parameter to the yang_dnode_get_entry() function instead of always aborting when an user pointer is not found. This will make it possible, for example, to use this function during the validation phase of a configuration transaction. Callers will only need to check if the function returned NULL or not, since new configuration objects (if any) won't be created until the NB_EV_APPLY phase of the transaction. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
3f66207896
commit
25c780a32a
6
lib/if.c
6
lib/if.c
@ -1338,7 +1338,7 @@ static int lib_interface_delete(enum nb_event event,
|
|||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NB_EV_VALIDATE:
|
case NB_EV_VALIDATE:
|
||||||
@ -1372,7 +1372,7 @@ static int lib_interface_description_modify(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
if (ifp->desc)
|
if (ifp->desc)
|
||||||
XFREE(MTYPE_TMP, ifp->desc);
|
XFREE(MTYPE_TMP, ifp->desc);
|
||||||
description = yang_dnode_get_string(dnode, NULL);
|
description = yang_dnode_get_string(dnode, NULL);
|
||||||
@ -1389,7 +1389,7 @@ static int lib_interface_description_delete(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
if (ifp->desc)
|
if (ifp->desc)
|
||||||
XFREE(MTYPE_TMP, ifp->desc);
|
XFREE(MTYPE_TMP, ifp->desc);
|
||||||
|
|
||||||
|
@ -493,7 +493,8 @@ void yang_dnode_set_entry(const struct lyd_node *dnode, void *entry)
|
|||||||
lyd_set_private(dnode, entry);
|
lyd_set_private(dnode, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *yang_dnode_get_entry(const struct lyd_node *dnode)
|
void *yang_dnode_get_entry(const struct lyd_node *dnode,
|
||||||
|
bool abort_if_not_found)
|
||||||
{
|
{
|
||||||
const struct lyd_node *orig_dnode = dnode;
|
const struct lyd_node *orig_dnode = dnode;
|
||||||
char xpath[XPATH_MAXLEN];
|
char xpath[XPATH_MAXLEN];
|
||||||
@ -512,6 +513,9 @@ void *yang_dnode_get_entry(const struct lyd_node *dnode)
|
|||||||
dnode = dnode->parent;
|
dnode = dnode->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!abort_if_not_found)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
yang_dnode_get_path(orig_dnode, xpath, sizeof(xpath));
|
yang_dnode_get_path(orig_dnode, xpath, sizeof(xpath));
|
||||||
flog_err(EC_LIB_YANG_DNODE_NOT_FOUND,
|
flog_err(EC_LIB_YANG_DNODE_NOT_FOUND,
|
||||||
"%s: failed to find entry [xpath %s]", __func__, xpath);
|
"%s: failed to find entry [xpath %s]", __func__, xpath);
|
||||||
|
26
lib/yang.h
26
lib/yang.h
@ -385,15 +385,37 @@ extern void yang_dnode_change_leaf(struct lyd_node *dnode, const char *value);
|
|||||||
extern void yang_dnode_set_entry(const struct lyd_node *dnode, void *entry);
|
extern void yang_dnode_set_entry(const struct lyd_node *dnode, void *entry);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the closest data node that contains an user pointer and return it.
|
* Find the user pointer associated to the given libyang data node.
|
||||||
|
*
|
||||||
|
* The data node is traversed by following the parent pointers until an user
|
||||||
|
* pointer is found or until the root node is reached.
|
||||||
*
|
*
|
||||||
* dnode
|
* dnode
|
||||||
* libyang data node to operate on.
|
* libyang data node to operate on.
|
||||||
*
|
*
|
||||||
|
* abort_if_not_found
|
||||||
|
* When set to true, abort the program if no user pointer is found.
|
||||||
|
*
|
||||||
|
* As a rule of thumb, this parameter should be set to true in the following
|
||||||
|
* scenarios:
|
||||||
|
* - Calling this function from any northbound configuration callback during
|
||||||
|
* the NB_EV_APPLY phase.
|
||||||
|
* - Calling this function from a 'delete' northbound configuration callback
|
||||||
|
* during any phase.
|
||||||
|
*
|
||||||
|
* In both the above cases, the libyang data node should contain an user
|
||||||
|
* pointer except when there's a bug in the code, in which case it's better
|
||||||
|
* to abort the program right away and eliminate the need for unnecessary
|
||||||
|
* NULL checks.
|
||||||
|
*
|
||||||
|
* In all other cases, this parameter should be set to false and the caller
|
||||||
|
* should check if the function returned NULL or not.
|
||||||
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* User pointer if found, NULL otherwise.
|
* User pointer if found, NULL otherwise.
|
||||||
*/
|
*/
|
||||||
extern void *yang_dnode_get_entry(const struct lyd_node *dnode);
|
extern void *yang_dnode_get_entry(const struct lyd_node *dnode,
|
||||||
|
bool abort_if_not_found);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new libyang data node.
|
* Create a new libyang data node.
|
||||||
|
@ -188,7 +188,7 @@ static int ripd_instance_distance_source_delete(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
rn = yang_dnode_get_entry(dnode);
|
rn = yang_dnode_get_entry(dnode, true);
|
||||||
rdistance = rn->info;
|
rdistance = rn->info;
|
||||||
if (rdistance->access_list)
|
if (rdistance->access_list)
|
||||||
free(rdistance->access_list);
|
free(rdistance->access_list);
|
||||||
@ -216,7 +216,7 @@ ripd_instance_distance_source_distance_modify(enum nb_event event,
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
/* Set distance value. */
|
/* Set distance value. */
|
||||||
rn = yang_dnode_get_entry(dnode);
|
rn = yang_dnode_get_entry(dnode, true);
|
||||||
distance = yang_dnode_get_uint8(dnode, NULL);
|
distance = yang_dnode_get_uint8(dnode, NULL);
|
||||||
rdistance = rn->info;
|
rdistance = rn->info;
|
||||||
rdistance->distance = distance;
|
rdistance->distance = distance;
|
||||||
@ -242,7 +242,7 @@ ripd_instance_distance_source_access_list_modify(enum nb_event event,
|
|||||||
acl_name = yang_dnode_get_string(dnode, NULL);
|
acl_name = yang_dnode_get_string(dnode, NULL);
|
||||||
|
|
||||||
/* Set access-list */
|
/* Set access-list */
|
||||||
rn = yang_dnode_get_entry(dnode);
|
rn = yang_dnode_get_entry(dnode, true);
|
||||||
rdistance = rn->info;
|
rdistance = rn->info;
|
||||||
if (rdistance->access_list)
|
if (rdistance->access_list)
|
||||||
free(rdistance->access_list);
|
free(rdistance->access_list);
|
||||||
@ -262,7 +262,7 @@ ripd_instance_distance_source_access_list_delete(enum nb_event event,
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
/* Reset access-list configuration. */
|
/* Reset access-list configuration. */
|
||||||
rn = yang_dnode_get_entry(dnode);
|
rn = yang_dnode_get_entry(dnode, true);
|
||||||
rdistance = rn->info;
|
rdistance = rn->info;
|
||||||
free(rdistance->access_list);
|
free(rdistance->access_list);
|
||||||
rdistance->access_list = NULL;
|
rdistance->access_list = NULL;
|
||||||
@ -396,7 +396,7 @@ static int ripd_instance_offset_list_delete(enum nb_event event,
|
|||||||
|
|
||||||
direct = yang_dnode_get_enum(dnode, "./direction");
|
direct = yang_dnode_get_enum(dnode, "./direction");
|
||||||
|
|
||||||
offset = yang_dnode_get_entry(dnode);
|
offset = yang_dnode_get_entry(dnode, true);
|
||||||
if (offset->direct[direct].alist_name) {
|
if (offset->direct[direct].alist_name) {
|
||||||
free(offset->direct[direct].alist_name);
|
free(offset->direct[direct].alist_name);
|
||||||
offset->direct[direct].alist_name = NULL;
|
offset->direct[direct].alist_name = NULL;
|
||||||
@ -426,7 +426,7 @@ ripd_instance_offset_list_access_list_modify(enum nb_event event,
|
|||||||
direct = yang_dnode_get_enum(dnode, "../direction");
|
direct = yang_dnode_get_enum(dnode, "../direction");
|
||||||
alist_name = yang_dnode_get_string(dnode, NULL);
|
alist_name = yang_dnode_get_string(dnode, NULL);
|
||||||
|
|
||||||
offset = yang_dnode_get_entry(dnode);
|
offset = yang_dnode_get_entry(dnode, true);
|
||||||
if (offset->direct[direct].alist_name)
|
if (offset->direct[direct].alist_name)
|
||||||
free(offset->direct[direct].alist_name);
|
free(offset->direct[direct].alist_name);
|
||||||
offset->direct[direct].alist_name = strdup(alist_name);
|
offset->direct[direct].alist_name = strdup(alist_name);
|
||||||
@ -451,7 +451,7 @@ static int ripd_instance_offset_list_metric_modify(enum nb_event event,
|
|||||||
direct = yang_dnode_get_enum(dnode, "../direction");
|
direct = yang_dnode_get_enum(dnode, "../direction");
|
||||||
metric = yang_dnode_get_uint8(dnode, NULL);
|
metric = yang_dnode_get_uint8(dnode, NULL);
|
||||||
|
|
||||||
offset = yang_dnode_get_entry(dnode);
|
offset = yang_dnode_get_entry(dnode, true);
|
||||||
offset->direct[direct].metric = metric;
|
offset->direct[direct].metric = metric;
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
@ -791,7 +791,7 @@ static int lib_interface_rip_split_horizon_modify(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
ri->split_horizon = yang_dnode_get_enum(dnode, NULL);
|
ri->split_horizon = yang_dnode_get_enum(dnode, NULL);
|
||||||
|
|
||||||
@ -811,7 +811,7 @@ static int lib_interface_rip_v2_broadcast_modify(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
ri->v2_broadcast = yang_dnode_get_bool(dnode, NULL);
|
ri->v2_broadcast = yang_dnode_get_bool(dnode, NULL);
|
||||||
|
|
||||||
@ -832,7 +832,7 @@ lib_interface_rip_version_receive_modify(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
ri->ri_receive = yang_dnode_get_enum(dnode, NULL);
|
ri->ri_receive = yang_dnode_get_enum(dnode, NULL);
|
||||||
|
|
||||||
@ -852,7 +852,7 @@ static int lib_interface_rip_version_send_modify(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
ri->ri_send = yang_dnode_get_enum(dnode, NULL);
|
ri->ri_send = yang_dnode_get_enum(dnode, NULL);
|
||||||
|
|
||||||
@ -872,7 +872,7 @@ static int lib_interface_rip_authentication_scheme_mode_modify(
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
ri->auth_type = yang_dnode_get_enum(dnode, NULL);
|
ri->auth_type = yang_dnode_get_enum(dnode, NULL);
|
||||||
|
|
||||||
@ -893,7 +893,7 @@ static int lib_interface_rip_authentication_scheme_md5_auth_length_modify(
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
ri->md5_auth_len = yang_dnode_get_enum(dnode, NULL);
|
ri->md5_auth_len = yang_dnode_get_enum(dnode, NULL);
|
||||||
|
|
||||||
@ -909,7 +909,7 @@ static int lib_interface_rip_authentication_scheme_md5_auth_length_delete(
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
ri->md5_auth_len = yang_get_default_enum(
|
ri->md5_auth_len = yang_get_default_enum(
|
||||||
"%s/authentication-scheme/md5-auth-length", RIP_IFACE);
|
"%s/authentication-scheme/md5-auth-length", RIP_IFACE);
|
||||||
@ -931,7 +931,7 @@ lib_interface_rip_authentication_password_modify(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
if (ri->auth_str)
|
if (ri->auth_str)
|
||||||
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
|
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
|
||||||
@ -951,7 +951,7 @@ lib_interface_rip_authentication_password_delete(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
|
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
|
||||||
|
|
||||||
@ -972,7 +972,7 @@ lib_interface_rip_authentication_key_chain_modify(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
if (ri->key_chain)
|
if (ri->key_chain)
|
||||||
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
|
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
|
||||||
@ -992,7 +992,7 @@ lib_interface_rip_authentication_key_chain_delete(enum nb_event event,
|
|||||||
if (event != NB_EV_APPLY)
|
if (event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
ifp = yang_dnode_get_entry(dnode);
|
ifp = yang_dnode_get_entry(dnode, true);
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
|
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user