diff options
Diffstat (limited to 'lib/northbound.c')
| -rw-r--r-- | lib/northbound.c | 87 |
1 files changed, 67 insertions, 20 deletions
diff --git a/lib/northbound.c b/lib/northbound.c index 8503f87d60..a7f9c8620e 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -95,6 +95,13 @@ static int nb_node_new_cb(const struct lys_node *snode, void *arg) if (config_only) SET_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY); } + if (CHECK_FLAG(snode->nodetype, LYS_LIST)) { + struct lys_node_list *slist; + + slist = (struct lys_node_list *)snode; + if (slist->keys_size == 0) + SET_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST); + } /* * Link the northbound node and the libyang schema node with one @@ -712,6 +719,7 @@ static int nb_configuration_callback(const enum nb_event event, const struct lyd_node *dnode = change->cb.dnode; union nb_resource *resource; int ret = NB_ERR; + enum lib_log_refs ref; if (debug_northbound) { const char *value = "(none)"; @@ -744,12 +752,36 @@ static int nb_configuration_callback(const enum nb_event event, break; } - if (ret != NB_OK) - flog_warn( - EC_LIB_NB_CB_CONFIG, - "%s: error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]", - __func__, nb_err_name(ret), nb_event_name(event), - nb_operation_name(operation), xpath); + if (ret != NB_OK) { + switch (event) { + case NB_EV_VALIDATE: + ref = EC_LIB_NB_CB_CONFIG_VALIDATE; + break; + case NB_EV_PREPARE: + ref = EC_LIB_NB_CB_CONFIG_PREPARE; + break; + case NB_EV_ABORT: + ref = EC_LIB_NB_CB_CONFIG_ABORT; + break; + case NB_EV_APPLY: + ref = EC_LIB_NB_CB_CONFIG_APPLY; + break; + } + if (event == NB_EV_VALIDATE || event == NB_EV_PREPARE) + flog_warn( + ref, + "%s: error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]", + __func__, nb_err_name(ret), + nb_event_name(event), + nb_operation_name(operation), xpath); + else + flog_err( + ref, + "%s: error processing configuration change: error [%s] event [%s] operation [%s] xpath [%s]", + __func__, nb_err_name(ret), + nb_event_name(event), + nb_operation_name(operation), xpath); + } return ret; } @@ -1056,6 +1088,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node, { struct lys_node_list *slist = (struct lys_node_list *)nb_node->snode; const void *list_entry = NULL; + uint32_t position = 1; if (CHECK_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY)) return NB_OK; @@ -1063,7 +1096,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node, /* Iterate over all list entries. */ do { struct yang_list_keys list_keys; - char xpath[XPATH_MAXLEN]; + char xpath[XPATH_MAXLEN * 2]; int ret; /* Obtain list entry. */ @@ -1073,19 +1106,31 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node, /* End of the list. */ break; - /* Obtain the list entry keys. */ - if (nb_node->cbs.get_keys(list_entry, &list_keys) != NB_OK) { - flog_warn(EC_LIB_NB_CB_STATE, - "%s: failed to get list keys", __func__); - return NB_ERR; - } - - /* Build XPath of the list entry. */ - strlcpy(xpath, xpath_list, sizeof(xpath)); - for (unsigned int i = 0; i < list_keys.num; i++) { - snprintf(xpath + strlen(xpath), - sizeof(xpath) - strlen(xpath), "[%s='%s']", - slist->keys[i]->name, list_keys.key[i]); + if (!CHECK_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST)) { + /* Obtain the list entry keys. */ + if (nb_node->cbs.get_keys(list_entry, &list_keys) + != NB_OK) { + flog_warn(EC_LIB_NB_CB_STATE, + "%s: failed to get list keys", + __func__); + return NB_ERR; + } + + /* Build XPath of the list entry. */ + strlcpy(xpath, xpath_list, sizeof(xpath)); + for (unsigned int i = 0; i < list_keys.num; i++) { + snprintf(xpath + strlen(xpath), + sizeof(xpath) - strlen(xpath), + "[%s='%s']", slist->keys[i]->name, + list_keys.key[i]); + } + } else { + /* + * Keyless list - build XPath using a positional index. + */ + snprintf(xpath, sizeof(xpath), "%s[%u]", xpath_list, + position); + position++; } /* Iterate over the child nodes. */ @@ -1400,6 +1445,8 @@ bool nb_operation_is_valid(enum nb_operation operation, case LYS_LIST: if (CHECK_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY)) return false; + if (CHECK_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST)) + return false; break; default: return false; |
