diff options
Diffstat (limited to 'lib/northbound.c')
| -rw-r--r-- | lib/northbound.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/lib/northbound.c b/lib/northbound.c index 0bc79d0277..a385cc9ece 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -178,7 +178,7 @@ struct nb_node *nb_node_find(const char *path) struct nb_node **nb_nodes_find(const char *xpath) { - struct lysc_node **snodes = NULL; + const struct lysc_node **snodes = NULL; struct nb_node **nb_nodes = NULL; bool simple; LY_ERR err; @@ -816,8 +816,9 @@ int nb_candidate_edit(struct nb_config *candidate, const struct nb_node *nb_node static int nb_candidate_edit_tree_add(struct nb_config *candidate, enum nb_operation operation, LYD_FORMAT format, const char *xpath, - const char *data, char *xpath_created, - char *errmsg, size_t errmsg_len) + const char *data, bool *created, + char *xpath_created, char *errmsg, + size_t errmsg_len) { struct lyd_node *tree = NULL; struct lyd_node *parent = NULL; @@ -897,10 +898,18 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate, } /* check if the node already exists in candidate */ - if (operation == NB_OP_CREATE_EXCL || operation == NB_OP_REPLACE) { + if (operation == NB_OP_CREATE || operation == NB_OP_MODIFY) + existing = yang_dnode_get(candidate->dnode, xpath_created); + else if (operation == NB_OP_CREATE_EXCL || operation == NB_OP_REPLACE) { existing = yang_dnode_get(candidate->dnode, xpath_created); /* if the existing node is implicit default, ignore */ + /* Q: Is this correct for CREATE_EXCL which is supposed to error + * if the resouurce already exists? This is used by RESTCONF + * when processing the POST command, for example. RFC8040 + * doesn't say POST fails if resource exists "unless it was a + * default". + */ if (existing && (existing->flags & LYD_DEFAULT)) existing = NULL; @@ -908,7 +917,7 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate, if (operation == NB_OP_CREATE_EXCL) { snprintf(errmsg, errmsg_len, "Data already exists"); - ret = NB_ERR; + ret = NB_ERR_EXISTS; goto done; } @@ -930,7 +939,7 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate, LYD_MERGE_DESTRUCT | LYD_MERGE_WITH_FLAGS); if (err) { /* if replace failed, restore the original node */ - if (existing) { + if (existing && operation == NB_OP_REPLACE) { if (root) { /* Restoring the whole config. */ candidate->dnode = existing; @@ -954,6 +963,8 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate, ret = NB_ERR; goto done; } else { + if (!existing) + *created = true; /* * Free existing node after replace. * We're using `lyd_free_siblings` here to free the whole @@ -961,7 +972,7 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate, * siblings if it wasn't root, because the existing node * was unlinked from the tree. */ - if (existing) + if (existing && operation == NB_OP_REPLACE) lyd_free_siblings(existing); tree = NULL; /* LYD_MERGE_DESTRUCT deleted the tree */ @@ -995,7 +1006,7 @@ static int nb_candidate_edit_tree_del(struct nb_config *candidate, if (!dnode || (dnode->flags & LYD_DEFAULT)) { if (operation == NB_OP_DELETE) { snprintf(errmsg, errmsg_len, "Data missing"); - return NB_ERR; + return NB_ERR_NOT_FOUND; } else return NB_OK; } @@ -1011,7 +1022,7 @@ static int nb_candidate_edit_tree_del(struct nb_config *candidate, int nb_candidate_edit_tree(struct nb_config *candidate, enum nb_operation operation, LYD_FORMAT format, - const char *xpath, const char *data, + const char *xpath, const char *data, bool *created, char *xpath_created, char *errmsg, size_t errmsg_len) { int ret = NB_ERR; @@ -1022,8 +1033,9 @@ int nb_candidate_edit_tree(struct nb_config *candidate, case NB_OP_MODIFY: case NB_OP_REPLACE: ret = nb_candidate_edit_tree_add(candidate, operation, format, - xpath, data, xpath_created, - errmsg, errmsg_len); + xpath, data, created, + xpath_created, errmsg, + errmsg_len); break; case NB_OP_DESTROY: case NB_OP_DELETE: @@ -2605,6 +2617,8 @@ const char *nb_err_name(enum nb_error error) return "no changes"; case NB_ERR_NOT_FOUND: return "element not found"; + case NB_ERR_EXISTS: + return "element already exists"; case NB_ERR_LOCKED: return "resource is locked"; case NB_ERR_VALIDATION: @@ -2687,7 +2701,7 @@ void nb_validate_callbacks(void) void nb_init(struct event_loop *tm, const struct frr_yang_module_info *const modules[], - size_t nmodules, bool db_enabled) + size_t nmodules, bool db_enabled, bool load_library) { struct yang_module *loaded[nmodules], **loadedp = loaded; @@ -2703,7 +2717,7 @@ void nb_init(struct event_loop *tm, nb_db_enabled = db_enabled; - yang_init(true, explicit_compile); + yang_init(true, explicit_compile, load_library); /* Load YANG modules and their corresponding northbound callbacks. */ for (size_t i = 0; i < nmodules; i++) { |
