diff options
Diffstat (limited to 'lib/northbound.c')
| -rw-r--r-- | lib/northbound.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/lib/northbound.c b/lib/northbound.c index a3d91e56af..25ea658bc4 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -157,7 +157,7 @@ void nb_nodes_delete(void) struct nb_node *nb_node_find(const char *path) { const struct lysc_node *snode; - uint32_t llopts; + uint32_t llopts = 0; /* * Use libyang to find the schema node associated to the path and get @@ -165,8 +165,6 @@ struct nb_node *nb_node_find(const char *path) * disable logging temporarily to avoid libyang from logging an error * message when the node is not found. */ - llopts = ly_log_options(LY_LOSTORE); - llopts &= ~LY_LOLOG; ly_temp_log_options(&llopts); snode = yang_find_snode(ly_native_ctx, path, 0); @@ -391,13 +389,29 @@ void nb_config_replace(struct nb_config *config_dst, static inline int nb_config_cb_compare(const struct nb_config_cb *a, const struct nb_config_cb *b) { - /* Sort by priority first. */ - if (a->nb_node->priority < b->nb_node->priority) + bool a_destroy = a->operation == NB_CB_DESTROY; + bool b_destroy = b->operation == NB_CB_DESTROY; + + /* + * Sort by operation first. All "destroys" must come first, to correctly + * process the change of a "case" inside a "choice". The old "case" must + * be deleted before the new "case" is created. + */ + if (a_destroy && !b_destroy) return -1; - if (a->nb_node->priority > b->nb_node->priority) + if (!a_destroy && b_destroy) return 1; /* + * Then sort by priority. If the operation is "destroy", reverse the + * order, so that the dependants are deleted before the dependencies. + */ + if (a->nb_node->priority < b->nb_node->priority) + return !a_destroy ? -1 : 1; + if (a->nb_node->priority > b->nb_node->priority) + return !a_destroy ? 1 : -1; + + /* * Preserve the order of the configuration changes as told by libyang. */ if (a->seq < b->seq) @@ -1811,6 +1825,7 @@ nb_apply_finish_cb_new(struct nb_config_cbs *cbs, const struct nb_node *nb_node, struct nb_config_cb *cb; cb = XCALLOC(MTYPE_TMP, sizeof(*cb)); + cb->operation = NB_CB_APPLY_FINISH; cb->nb_node = nb_node; cb->dnode = dnode; RB_INSERT(nb_config_cbs, cbs, cb); @@ -1825,6 +1840,7 @@ nb_apply_finish_cb_find(struct nb_config_cbs *cbs, { struct nb_config_cb s; + s.operation = NB_CB_APPLY_FINISH; s.seq = 0; s.nb_node = nb_node; s.dnode = dnode; @@ -1922,6 +1938,8 @@ bool nb_cb_operation_is_valid(enum nb_cb_operation operation, return false; break; case LYS_CONTAINER: + if (snode->parent && snode->parent->nodetype == LYS_CASE) + return true; scontainer = (struct lysc_node_container *)snode; if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE)) return false; @@ -1976,6 +1994,8 @@ bool nb_cb_operation_is_valid(enum nb_cb_operation operation, return false; break; case LYS_CONTAINER: + if (snode->parent && snode->parent->nodetype == LYS_CASE) + return true; scontainer = (struct lysc_node_container *)snode; if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE)) return false; |
