diff --git a/lib/northbound.c b/lib/northbound.c index 487f225913..545227df25 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -4,6 +4,9 @@ * Renato Westphal */ +#include +#include +#include #include #include "darr.h" @@ -683,6 +686,10 @@ void nb_config_diff(const struct nb_config *config1, lyd_free_all(diff); } +#define __dbg(fmt, ...) \ + zlog_err("%s: ERROR: " fmt, __func__, ##__VA_ARGS__) + +struct lyd_node *rm_set_src_node; static int dnode_create(struct nb_config *candidate, const char *xpath, const char *value, uint32_t options, struct lyd_node **new_dnode) @@ -692,6 +699,17 @@ static int dnode_create(struct nb_config *candidate, const char *xpath, err = lyd_new_path(candidate->dnode, ly_native_ctx, xpath, value, options, &dnode); + if (dnode) { + __dbg("frr_debug_sonic_create: dnode %p, xpath %s, value %s", dnode, xpath, value); + char *xpath = lyd_path(dnode, LYD_PATH_STD, NULL, 0); + if (xpath && + !strcmp("/frr-route-map:lib/route-map[name='RM_SET_SRC']/entry[sequence='10']/set-action[action='frr-zebra-route-map:src-address']/rmap-set-action/frr-zebra-route-map:ipv4-src-address", xpath)) { + mprotect(dnode->schema, sizeof(dnode->schema), PROT_READ); + rm_set_src_node = dnode; + free(xpath); + } + } + if (err) { flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path(%s) failed: %d", __func__, xpath, err); @@ -858,6 +876,7 @@ void nb_candidate_edit_config_changes(struct nb_config *candidate_config, if (xpath_base == NULL) xpath_base = ""; + __dbg("frr_debug_sonic: num_cfg_changes: '%u'", num_cfg_changes); /* Edit candidate configuration. */ for (size_t i = 0; i < num_cfg_changes; i++) { struct nb_cfg_change *change = &cfg_changes[i]; @@ -875,6 +894,7 @@ void nb_candidate_edit_config_changes(struct nb_config *candidate_config, change_xpath++; /* skip '.' */ } strlcat(xpath, change_xpath, sizeof(xpath)); + __dbg("frr_debug_sonic: XPath: '%s'", xpath); /* Find the northbound node associated to the data path. */ nb_node = nb_node_find(xpath); @@ -890,6 +910,7 @@ void nb_candidate_edit_config_changes(struct nb_config *candidate_config, if (error) *error = true; } + __dbg("frr_debug_sonic: XPath: '%s', nb_node NULL", xpath); continue; } /* Find if the node to be edited is not a key node */ @@ -897,6 +918,7 @@ void nb_candidate_edit_config_changes(struct nb_config *candidate_config, zlog_err(" Xpath %s points to key node", xpath); if (error) *error = true; + __dbg("frr_debug_sonic: XPath: '%s', nb_is_operation_allowed NULL", xpath); break; } @@ -910,6 +932,8 @@ void nb_candidate_edit_config_changes(struct nb_config *candidate_config, * Ignore "not found" errors when editing the candidate * configuration. */ + __dbg("frr_debug_sonic: XPath: '%s', value '%s', operation %u", xpath, + value, change->operation); ret = nb_candidate_edit(candidate_config, nb_node, change->operation, xpath, NULL, data); yang_data_free(data); @@ -921,6 +945,7 @@ void nb_candidate_edit_config_changes(struct nb_config *candidate_config, xpath); if (error) *error = true; + __dbg("frr_debug_sonic: XPath: '%s', nb_candidate_edit NULL", xpath); continue; } } diff --git a/lib/vty.c b/lib/vty.c index 1c9cff478d..52ecad9871 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -2845,6 +2845,8 @@ bool vty_read_config(struct nb_config *config, const char *config_file, { FILE *confp; + zlog_err("vty_read_config: frr_debug_sonic: config file: %s, config_default_dir %s ", + config_file, config_default_dir); confp = vty_open_config(config_file, config_default_dir); if (!confp) return false; diff --git a/lib/yang.c b/lib/yang.c index 03044fc29e..81b5a917e8 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -14,6 +14,7 @@ #include "northbound.h" #include "lib/config_paths.h" +#include "zlog.h" DEFINE_MTYPE_STATIC(LIB, YANG_MODULE, "YANG module"); DEFINE_MTYPE_STATIC(LIB, YANG_DATA, "YANG data structure"); @@ -1343,3 +1344,24 @@ const char *yang_ly_strvecode(LY_VECODE vecode) } #endif } + +void debug_lyd_free_tree(struct lyd_node *dnode) +{ + + zlog_err("%s: ERROR: frr_debug_sonic_free: dnode %p", __func__, dnode); +#undef lyd_free_tree + lyd_free_tree(dnode); +} + +static pthread_mutex_t candidate_edit_lock = PTHREAD_MUTEX_INITIALIZER; +LY_ERR debug_lyd_new_path(struct lyd_node *parent, const struct ly_ctx + *ctx, const char *path, const char *value, + uint32_t options, struct lyd_node **node) +{ + LY_ERR err; + pthread_mutex_lock(&candidate_edit_lock); +#undef lyd_new_path + err = lyd_new_path(parent, ctx, path, value, options, node); + pthread_mutex_unlock(&candidate_edit_lock); + return err; +} diff --git a/lib/yang.h b/lib/yang.h index 65f6a73e0b..f96f7dfd06 100644 --- a/lib/yang.h +++ b/lib/yang.h @@ -801,6 +801,16 @@ extern LY_ERR yang_lyd_new_list(struct lyd_node_inner *parent, struct lyd_node **nodes); extern LY_ERR yang_lyd_trim_xpath(struct lyd_node **rootp, const char *xpath); +#define lyd_free_tree debug_lyd_free_tree + +extern void debug_lyd_free_tree(struct lyd_node *dnode); + +#define lyd_new_path debug_lyd_new_path + +extern LY_ERR debug_lyd_new_path(struct lyd_node *parent, const struct ly_ctx + *ctx, const char *path, const char *value, + uint32_t options, struct lyd_node **node); + #ifdef __cplusplus } #endif diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index c1cb33f6f3..24db358ad2 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -16,6 +16,7 @@ #include "mgmtd/mgmt.h" #include "mgmtd/mgmt_memory.h" #include "mgmtd/mgmt_txn.h" +#include "libyang/libyang.h" #define __dbg(fmt, ...) \ DEBUGD(&mgmt_debug_txn, "TXN: %s: " fmt, __func__, ##__VA_ARGS__) @@ -945,10 +946,112 @@ static int mgmt_txn_create_config_batches(struct mgmt_txn_req *txn_req, return 0; } + +static void mgmt_print_nb_config_cbs(const char *prefix, struct nb_config_cbs *cfg_chgs) +{ + struct nb_config_cb *cb, *nxt; + struct nb_config_change *chg; + char *xpath; + + if (!cfg_chgs) { + __dbg("%s: nb_config_cbs is NULL", prefix); + return; + } + + __dbg("%s: nb_config_cbs structure: %p", prefix, cfg_chgs); + + if (RB_EMPTY(nb_config_cbs, cfg_chgs)) { + __dbg("%s: nb_config_cbs is empty", prefix); + return; + } + + RB_FOREACH_SAFE (cb, nb_config_cbs, cfg_chgs, nxt) { + chg = (struct nb_config_change *)cb; + + __dbg("%s: Change operation: %d", prefix, chg->cb.operation); + __dbg("%s: Change nb_node: %p", prefix, chg->cb.nb_node); + if (chg->cb.nb_node) { + __dbg("%s: Change nb_node schema: %s", prefix, chg->cb.nb_node->snode->name); + __dbg("%s: Change nb_node module: %s", prefix, chg->cb.nb_node->snode->module->name); + } + + __dbg("%s: Change dnode: %p", prefix, chg->cb.dnode); + if (chg->cb.dnode) { + __dbg("%s: Change dnode schema: %s", prefix, chg->cb.dnode->schema->name); + __dbg("%s: Change dnode module: %s", prefix, chg->cb.dnode->schema->module->name); + __dbg("%s: Change dnode type: %d", prefix, chg->cb.dnode->schema->nodetype); + + xpath = lyd_path(chg->cb.dnode, LYD_PATH_STD, NULL, 0); + if (xpath) { + __dbg("%s: Change dnode xpath: %s", prefix, xpath); + if (chg->cb.dnode->schema->nodetype & LYD_NODE_TERM) { + const char *value = lyd_get_value(chg->cb.dnode); + __dbg("%s: Change dnode value: %s", prefix, value ? value : "NULL"); + } + free(xpath); + } + } + } +} + +static void mgmt_print_nb_config(const char *prefix, struct nb_config *nb_config) +{ + struct lyd_node *dnode; + struct lyd_node *root, *child; + const char *value; + char *xpath; + + if (!nb_config) { + __dbg("%s: nb_config is NULL", prefix); + return; + } + + __dbg("%s: nb_config structure: %p", prefix, nb_config); + __dbg("%s: nb_config dnode: %p", prefix, nb_config->dnode); + + if (!nb_config->dnode) { + __dbg("%s: nb_config dnode is NULL", prefix); + return; + } + + __dbg("%s: nb_config dnode schema: %s", prefix, nb_config->dnode->schema->name); + __dbg("%s: nb_config dnode module: %s", prefix, nb_config->dnode->schema->module->name); + __dbg("%s: nb_config dnode type: %d", prefix, nb_config->dnode->schema->nodetype); + + /* Print the root node */ + xpath = lyd_path(nb_config->dnode, LYD_PATH_STD, NULL, 0); + if (xpath) { + __dbg("%s: Root node xpath: %s", prefix, xpath); + free(xpath); + } + + /* Print all child nodes */ + LY_LIST_FOR (nb_config->dnode, root) { + LYD_TREE_DFS_BEGIN (root, child) { + xpath = lyd_path(child, LYD_PATH_STD, NULL, 0); + if (xpath) { + __dbg("%s: Child node %p xpath: %s", prefix, child, xpath); + //__dbg("%s: Child node schema: %s", prefix, child->schema->name); + //__dbg("%s: Child node module: %s", prefix, child->schema->module->name); + //__dbg("%s: Child node type: %d", prefix, child->schema->nodetype); + + if (child->schema->nodetype & LYD_NODE_TERM) { + value = lyd_get_value(child); + __dbg("%s: Child node value: %s", prefix, value ? value : "NULL"); + } + + free(xpath); + } + LYD_TREE_DFS_END(root, child); + } + } +} + +extern struct lyd_node *rm_set_src_node; static int mgmt_txn_prepare_config(struct mgmt_txn_ctx *txn) { struct nb_context nb_ctx; - struct nb_config *nb_config; + struct nb_config *nb_config, *dst_nb_config; struct nb_config_cbs changes; struct nb_config_cbs *cfg_chgs = NULL; int ret; @@ -1013,6 +1116,17 @@ static int mgmt_txn_prepare_config(struct mgmt_txn_ctx *txn) goto mgmt_txn_prepare_config_done; } + if (rm_set_src_node) { + char *xpath = lyd_path(rm_set_src_node, LYD_PATH_STD, NULL, 0); + __dbg("frr_debug_sonic: dnode %p, xpath %s", rm_set_src_node, xpath); + __dbg("frr_debug_sonic: node schema: %s", rm_set_src_node->schema->name); + __dbg("frr_debug_sonic: node module: %s", rm_set_src_node->schema->module->name); + free(xpath); + } + else { + __dbg("frr_debug_sonic: rm_set_src_node is NULL"); + } + mgmt_print_nb_config("frr_debug_sonic: SET_CFG src", nb_config); /* * Validate YANG contents of the source DS and get the diff * between source and destination DS contents. @@ -1029,6 +1143,9 @@ static int mgmt_txn_prepare_config(struct mgmt_txn_ctx *txn) ret = -1; goto mgmt_txn_prepare_config_done; } + dst_nb_config = mgmt_ds_get_nb_config( + txn->commit_cfg_req->req.commit_cfg.dst_ds_ctx); + mgmt_print_nb_config("frr_debug_sonic: SET_CFG dst", dst_nb_config); nb_config_diff(mgmt_ds_get_nb_config(txn->commit_cfg_req->req.commit_cfg .dst_ds_ctx), @@ -1036,6 +1153,7 @@ static int mgmt_txn_prepare_config(struct mgmt_txn_ctx *txn) cfg_chgs = &changes; del_cfg_chgs = true; + mgmt_print_nb_config_cbs("frr_debug_sonic: CONFIG_CHANGES", cfg_chgs); if (RB_EMPTY(nb_config_cbs, cfg_chgs)) { /* * This means there's no changes to commit whatsoever