summaryrefslogtreecommitdiff
path: root/lib/northbound.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/northbound.c')
-rw-r--r--lib/northbound.c32
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;