]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/northbound.c
Merge pull request #5104 from opensourcerouting/route-map-nbv2
[mirror_frr.git] / lib / northbound.c
index 1b332fb1e8bd692c59ebb7255afc96999a5ea99b..206a88d9800650d4de56b753f73fe90c4d93771e 100644 (file)
@@ -350,7 +350,22 @@ static inline int nb_config_cb_compare(const struct nb_config_cb *a,
        /*
         * Preserve the order of the configuration changes as told by libyang.
         */
-       return a->seq - b->seq;
+       if (a->seq < b->seq)
+               return -1;
+       if (a->seq > b->seq)
+               return 1;
+
+       /*
+        * All 'apply_finish' callbacks have their sequence number set to zero.
+        * In this case, compare them using their dnode pointers (the order
+        * doesn't matter for callbacks that have the same priority).
+        */
+       if (a->dnode < b->dnode)
+               return -1;
+       if (a->dnode > b->dnode)
+               return 1;
+
+       return 0;
 }
 RB_GENERATE(nb_config_cbs, nb_config_cb, entry, nb_config_cb_compare);
 
@@ -366,7 +381,6 @@ static void nb_config_diff_add_change(struct nb_config_cbs *changes,
        change->cb.seq = *seq;
        *seq = *seq + 1;
        change->cb.nb_node = dnode->schema->priv;
-       yang_dnode_get_path(dnode, change->cb.xpath, sizeof(change->cb.xpath));
        change->cb.dnode = dnode;
 
        RB_INSERT(nb_config_cbs, changes, &change->cb);
@@ -516,17 +530,6 @@ int nb_candidate_edit(struct nb_config *candidate,
                                  __func__);
                        return NB_ERR;
                }
-
-               /*
-                * If a new node was created, call lyd_validate() only to create
-                * default child nodes.
-                */
-               if (dnode) {
-                       lyd_schema_sort(dnode, 0);
-                       lyd_validate(&dnode,
-                                    LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL,
-                                    ly_native_ctx);
-               }
                break;
        case NB_OP_DESTROY:
                dnode = yang_dnode_get(candidate->dnode, xpath_edit);
@@ -806,7 +809,7 @@ static int nb_callback_configuration(const enum nb_event event,
                                     struct nb_config_change *change)
 {
        enum nb_operation operation = change->cb.operation;
-       const char *xpath = change->cb.xpath;
+       char xpath[XPATH_MAXLEN];
        const struct nb_node *nb_node = change->cb.nb_node;
        const struct lyd_node *dnode = change->cb.dnode;
        union nb_resource *resource;
@@ -818,6 +821,7 @@ static int nb_callback_configuration(const enum nb_event event,
                if (dnode && !yang_snode_is_typeless_data(dnode->schema))
                        value = yang_dnode_get_string(dnode, NULL);
 
+               yang_dnode_get_path(dnode, xpath, sizeof(xpath));
                nb_log_callback(event, operation, xpath, value);
        }
 
@@ -840,6 +844,7 @@ static int nb_callback_configuration(const enum nb_event event,
                ret = (*nb_node->cbs.move)(event, dnode);
                break;
        default:
+               yang_dnode_get_path(dnode, xpath, sizeof(xpath));
                flog_err(EC_LIB_DEVELOPMENT,
                         "%s: unknown operation (%u) [xpath %s]", __func__,
                         operation, xpath);
@@ -850,6 +855,8 @@ static int nb_callback_configuration(const enum nb_event event,
                int priority;
                enum lib_log_refs ref;
 
+               yang_dnode_get_path(dnode, xpath, sizeof(xpath));
+
                switch (event) {
                case NB_EV_VALIDATE:
                        priority = LOG_WARNING;
@@ -1020,14 +1027,12 @@ static int nb_transaction_process(enum nb_event event,
 }
 
 static struct nb_config_cb *
-nb_apply_finish_cb_new(struct nb_config_cbs *cbs, const char *xpath,
-                      const struct nb_node *nb_node,
+nb_apply_finish_cb_new(struct nb_config_cbs *cbs, const struct nb_node *nb_node,
                       const struct lyd_node *dnode)
 {
        struct nb_config_cb *cb;
 
        cb = XCALLOC(MTYPE_TMP, sizeof(*cb));
-       strlcpy(cb->xpath, xpath, sizeof(cb->xpath));
        cb->nb_node = nb_node;
        cb->dnode = dnode;
        RB_INSERT(nb_config_cbs, cbs, cb);
@@ -1036,13 +1041,15 @@ nb_apply_finish_cb_new(struct nb_config_cbs *cbs, const char *xpath,
 }
 
 static struct nb_config_cb *
-nb_apply_finish_cb_find(struct nb_config_cbs *cbs, const char *xpath,
-                       const struct nb_node *nb_node)
+nb_apply_finish_cb_find(struct nb_config_cbs *cbs,
+                       const struct nb_node *nb_node,
+                       const struct lyd_node *dnode)
 {
        struct nb_config_cb s;
 
-       strlcpy(s.xpath, xpath, sizeof(s.xpath));
+       s.seq = 0;
        s.nb_node = nb_node;
+       s.dnode = dnode;
        return RB_FIND(nb_config_cbs, cbs, &s);
 }
 
@@ -1051,6 +1058,7 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
 {
        struct nb_config_cbs cbs;
        struct nb_config_cb *cb;
+       char xpath[XPATH_MAXLEN];
 
        /* Initialize tree of 'apply_finish' callbacks. */
        RB_INIT(nb_config_cbs, &cbs);
@@ -1067,8 +1075,6 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
                 * be called though).
                 */
                if (change->cb.operation == NB_OP_DESTROY) {
-                       char xpath[XPATH_MAXLEN];
-
                        dnode = dnode->parent;
                        if (!dnode)
                                break;
@@ -1084,7 +1090,6 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
                                               xpath);
                }
                while (dnode) {
-                       char xpath[XPATH_MAXLEN];
                        struct nb_node *nb_node;
 
                        nb_node = dnode->schema->priv;
@@ -1095,11 +1100,10 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
                         * Don't call the callback more than once for the same
                         * data node.
                         */
-                       yang_dnode_get_path(dnode, xpath, sizeof(xpath));
-                       if (nb_apply_finish_cb_find(&cbs, xpath, nb_node))
+                       if (nb_apply_finish_cb_find(&cbs, nb_node, dnode))
                                goto next;
 
-                       nb_apply_finish_cb_new(&cbs, xpath, nb_node, dnode);
+                       nb_apply_finish_cb_new(&cbs, nb_node, dnode);
 
                next:
                        dnode = dnode->parent;
@@ -1108,9 +1112,11 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
 
        /* Call the 'apply_finish' callbacks, sorted by their priorities. */
        RB_FOREACH (cb, nb_config_cbs, &cbs) {
-               if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL))
-                       nb_log_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH,
-                                       cb->xpath, NULL);
+               if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) {
+                       yang_dnode_get_path(cb->dnode, xpath, sizeof(xpath));
+                       nb_log_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH, xpath,
+                                       NULL);
+               }
 
                (*cb->nb_node->cbs.apply_finish)(cb->dnode);
        }
@@ -1876,7 +1882,8 @@ static void nb_load_callbacks(const struct frr_yang_module_info *module)
 }
 
 void nb_init(struct thread_master *tm,
-            const struct frr_yang_module_info *modules[], size_t nmodules)
+            const struct frr_yang_module_info *const modules[],
+            size_t nmodules)
 {
        unsigned int errors = 0;