]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: make yang_dnode_get_entry() more flexible
authorRenato Westphal <renato@opensourcerouting.org>
Sun, 25 Nov 2018 16:41:38 +0000 (14:41 -0200)
committerRenato Westphal <renato@opensourcerouting.org>
Mon, 26 Nov 2018 17:53:15 +0000 (15:53 -0200)
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>
lib/if.c
lib/yang.c
lib/yang.h
ripd/rip_northbound.c

index e02c89b9acea3e0b4daa114c739bc89057c5374e..03a83f4a3886cd190d31e8730817f3577419ee45 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -1338,7 +1338,7 @@ static int lib_interface_delete(enum nb_event event,
 {
        struct interface *ifp;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
 
        switch (event) {
        case NB_EV_VALIDATE:
@@ -1372,7 +1372,7 @@ static int lib_interface_description_modify(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        if (ifp->desc)
                XFREE(MTYPE_TMP, ifp->desc);
        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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        if (ifp->desc)
                XFREE(MTYPE_TMP, ifp->desc);
 
index f41c645758a6287a27825727836d95b09bbb8994..757982d36793d09dc4423b9c5394aa3294506561 100644 (file)
@@ -493,7 +493,8 @@ void yang_dnode_set_entry(const struct lyd_node *dnode, void *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;
        char xpath[XPATH_MAXLEN];
@@ -512,6 +513,9 @@ void *yang_dnode_get_entry(const struct lyd_node *dnode)
                dnode = dnode->parent;
        }
 
+       if (!abort_if_not_found)
+               return NULL;
+
        yang_dnode_get_path(orig_dnode, xpath, sizeof(xpath));
        flog_err(EC_LIB_YANG_DNODE_NOT_FOUND,
                 "%s: failed to find entry [xpath %s]", __func__, xpath);
index eac9796df95a12e4f85c86196808a85fc9307d10..c920060071fd186a32c74c3a08ae9542d8267607 100644 (file)
@@ -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);
 
 /*
- * 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
  *    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:
  *    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.
index bb32409a2488d420747b57b9a993f1f3afdbce6e..d1e298c25cd568b28f7737fbb5841946f9ae2334 100644 (file)
@@ -188,7 +188,7 @@ static int ripd_instance_distance_source_delete(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       rn = yang_dnode_get_entry(dnode);
+       rn = yang_dnode_get_entry(dnode, true);
        rdistance = rn->info;
        if (rdistance->access_list)
                free(rdistance->access_list);
@@ -216,7 +216,7 @@ ripd_instance_distance_source_distance_modify(enum nb_event event,
                return NB_OK;
 
        /* Set distance value. */
-       rn = yang_dnode_get_entry(dnode);
+       rn = yang_dnode_get_entry(dnode, true);
        distance = yang_dnode_get_uint8(dnode, NULL);
        rdistance = rn->info;
        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);
 
        /* Set access-list */
-       rn = yang_dnode_get_entry(dnode);
+       rn = yang_dnode_get_entry(dnode, true);
        rdistance = rn->info;
        if (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;
 
        /* Reset access-list configuration. */
-       rn = yang_dnode_get_entry(dnode);
+       rn = yang_dnode_get_entry(dnode, true);
        rdistance = rn->info;
        free(rdistance->access_list);
        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");
 
-       offset = yang_dnode_get_entry(dnode);
+       offset = yang_dnode_get_entry(dnode, true);
        if (offset->direct[direct].alist_name) {
                free(offset->direct[direct].alist_name);
                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");
        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)
                free(offset->direct[direct].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");
        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;
 
        return NB_OK;
@@ -791,7 +791,7 @@ static int lib_interface_rip_split_horizon_modify(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        ri->md5_auth_len = yang_get_default_enum(
                "%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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        if (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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        if (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)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode);
+       ifp = yang_dnode_get_entry(dnode, true);
        ri = ifp->info;
        XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);