summaryrefslogtreecommitdiffstats
path: root/lib/northbound_confd.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2019-04-12 23:00:26 +0200
committerRenato Westphal <renato@opensourcerouting.org>2019-04-15 20:59:38 +0200
commit9eb2c0a1dc80c2693f3290df85e04dbe58f7575d (patch)
treef7b16bcf38283f6fe8afa6f632077396262f8e35 /lib/northbound_confd.c
parentlib: fix inverted logic in the "debug all" command (diff)
downloadfrr-9eb2c0a1dc80c2693f3290df85e04dbe58f7575d.tar.xz
frr-9eb2c0a1dc80c2693f3290df85e04dbe58f7575d.zip
lib: add fine-grained debugging in the northbound
Split the "debug northbound" command into the following commands: * debug northbound callbacks configuration * debug northbound callbacks state * debug northbound callbacks rpc * debug northbound notifications * debug northbound events * debug northbound client confd * debug northbound client sysrepo If "debug northbound" is entered alone, all of its suboptions are enabled. This commit also adds code to debug state/rpc callbacks and notifications (only configuration callbacks were logged before). Use the debugging infrastructure from "lib/debug.h" in order to benefit from its facilities (e.g. MT-safe debugging) and avoid code duplication. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'lib/northbound_confd.c')
-rw-r--r--lib/northbound_confd.c92
1 files changed, 73 insertions, 19 deletions
diff --git a/lib/northbound_confd.c b/lib/northbound_confd.c
index a499d48c1..0df286511 100644
--- a/lib/northbound_confd.c
+++ b/lib/northbound_confd.c
@@ -22,6 +22,7 @@
#include "log.h"
#include "lib_errors.h"
#include "command.h"
+#include "debug.h"
#include "libfrr.h"
#include "version.h"
#include "northbound.h"
@@ -33,6 +34,8 @@
DEFINE_MTYPE_STATIC(LIB, CONFD, "ConfD module")
+static struct debug nb_dbg_client_confd = {0, "Northbound client: ConfD"};
+
static struct thread_master *master;
static struct sockaddr confd_addr;
static int cdb_sub_sock, dp_ctl_sock, dp_worker_sock;
@@ -139,8 +142,8 @@ static int frr_confd_hkeypath_get_list_entry(const confd_hkeypath_t *kp,
/* Obtain list entry. */
if (!CHECK_FLAG(nb_node_list->flags, F_NB_NODE_KEYLESS_LIST)) {
- *list_entry = nb_node_list->cbs.lookup_entry(
- *list_entry, &keys);
+ *list_entry = nb_callback_lookup_entry(
+ nb_node, *list_entry, &keys);
if (*list_entry == NULL)
return -1;
} else {
@@ -545,9 +548,8 @@ static int frr_confd_init_cdb(void)
continue;
nb_node = snode->priv;
- if (debug_northbound)
- zlog_debug("%s: subscribing to '%s'", __func__,
- nb_node->xpath);
+ DEBUGD(&nb_dbg_client_confd, "%s: subscribing to '%s'",
+ __func__, nb_node->xpath);
spoint = XMALLOC(MTYPE_CONFD, sizeof(*spoint));
ret = cdb_subscribe2(
@@ -630,7 +632,7 @@ static int frr_confd_data_get_elem(struct confd_trans_ctx *tctx,
return CONFD_OK;
}
- data = nb_node->cbs.get_elem(xpath, list_entry);
+ data = nb_callback_get_elem(nb_node, xpath, list_entry);
if (data) {
if (data->value) {
CONFD_SET_STR(&v, data->value);
@@ -670,8 +672,8 @@ static int frr_confd_data_get_next(struct confd_trans_ctx *tctx,
return CONFD_OK;
}
- nb_next = nb_node->cbs.get_next(parent_list_entry,
- (next == -1) ? NULL : (void *)next);
+ nb_next = nb_callback_get_next(nb_node, parent_list_entry,
+ (next == -1) ? NULL : (void *)next);
if (!nb_next) {
/* End of the list or leaf-list. */
confd_data_reply_next_key(tctx, NULL, -1, -1);
@@ -684,7 +686,8 @@ static int frr_confd_data_get_next(struct confd_trans_ctx *tctx,
struct yang_list_keys keys;
memset(&keys, 0, sizeof(keys));
- if (nb_node->cbs.get_keys(nb_next, &keys) != NB_OK) {
+ if (nb_callback_get_keys(nb_node, nb_next, &keys)
+ != NB_OK) {
flog_warn(EC_LIB_NB_CB_STATE,
"%s: failed to get list keys",
__func__);
@@ -729,7 +732,7 @@ static int frr_confd_data_get_next(struct confd_trans_ctx *tctx,
}
break;
case LYS_LEAFLIST:
- data = nb_node->cbs.get_elem(xpath, nb_next);
+ data = nb_callback_get_elem(nb_node, xpath, nb_next);
if (data) {
if (data->value) {
CONFD_SET_STR(&v[0], data->value);
@@ -798,7 +801,8 @@ static int frr_confd_data_get_object(struct confd_trans_ctx *tctx,
snprintf(xpath_child, sizeof(xpath_child), "%s/%s", xpath,
child->name);
- data = nb_node_child->cbs.get_elem(xpath_child, list_entry);
+ data = nb_callback_get_elem(nb_node_child, xpath_child,
+ list_entry);
if (data) {
if (data->value)
CONFD_SET_STR(v, data->value);
@@ -866,7 +870,8 @@ static int frr_confd_data_get_next_object(struct confd_trans_ctx *tctx,
object = &objects[j];
- nb_next = nb_node->cbs.get_next(parent_list_entry, nb_next);
+ nb_next = nb_callback_get_next(nb_node, parent_list_entry,
+ nb_next);
if (!nb_next)
/* End of the list. */
break;
@@ -876,7 +881,7 @@ static int frr_confd_data_get_next_object(struct confd_trans_ctx *tctx,
/* Leaf-lists require special handling. */
if (nb_node->snode->nodetype == LYS_LEAFLIST) {
object->v = XMALLOC(MTYPE_CONFD, sizeof(confd_value_t));
- data = nb_node->cbs.get_elem(xpath, nb_next);
+ data = nb_callback_get_elem(nb_node, xpath, nb_next);
assert(data && data->value);
CONFD_SET_STR(object->v, data->value);
nvalues++;
@@ -927,8 +932,8 @@ static int frr_confd_data_get_next_object(struct confd_trans_ctx *tctx,
snprintf(xpath_child, sizeof(xpath_child), "%s/%s",
xpath, child->name);
- data = nb_node_child->cbs.get_elem(xpath_child,
- nb_next);
+ data = nb_callback_get_elem(nb_node_child, xpath_child,
+ nb_next);
if (data) {
if (data->value)
CONFD_SET_STR(v, data->value);
@@ -1108,7 +1113,7 @@ static int frr_confd_action_execute(struct confd_user_info *uinfo,
}
/* Execute callback registered for this XPath. */
- if (nb_node->cbs.rpc(xpath, input, output) != NB_OK) {
+ if (nb_callback_rpc(nb_node, xpath, input, output) != NB_OK) {
flog_warn(EC_LIB_NB_CB_RPC, "%s: rpc callback failed: %s",
__func__, xpath);
ret = CONFD_ERR;
@@ -1185,9 +1190,9 @@ static int frr_confd_subscribe_state(const struct lys_node *snode, void *arg)
if (snode->parent && CHECK_FLAG(snode->parent->flags, LYS_CONFIG_R))
return YANG_ITER_CONTINUE;
- if (debug_northbound)
- zlog_debug("%s: providing data to '%s' (callpoint %s)",
- __func__, nb_node->xpath, snode->name);
+ DEBUGD(&nb_dbg_client_confd,
+ "%s: providing data to '%s' (callpoint %s)", __func__,
+ nb_node->xpath, snode->name);
strlcpy(data_cbs->callpoint, snode->name, sizeof(data_cbs->callpoint));
if (confd_register_data_cb(dctx, data_cbs) != CONFD_OK)
@@ -1328,6 +1333,54 @@ static void frr_confd_finish_dp(void)
confd_release_daemon(dctx);
}
+/* ------------ CLI ------------ */
+
+DEFUN (debug_nb_confd,
+ debug_nb_confd_cmd,
+ "[no] debug northbound client confd",
+ NO_STR
+ DEBUG_STR
+ "Northbound debugging\n"
+ "Client\n"
+ "ConfD\n")
+{
+ uint32_t mode = DEBUG_NODE2MODE(vty->node);
+ bool no = strmatch(argv[0]->text, "no");
+
+ DEBUG_MODE_SET(&nb_dbg_client_confd, mode, !no);
+
+ return CMD_SUCCESS;
+}
+
+static int frr_confd_debug_config_write(struct vty *vty)
+{
+ if (DEBUG_MODE_CHECK(&nb_dbg_client_confd, DEBUG_MODE_CONF))
+ vty_out(vty, "debug northbound client confd\n");
+
+ return 0;
+}
+
+static int frr_confd_debug_set_all(uint32_t flags, bool set)
+{
+ DEBUG_FLAGS_SET(&nb_dbg_client_confd, flags, set);
+
+ /* If all modes have been turned off, don't preserve options. */
+ if (!DEBUG_MODE_CHECK(&nb_dbg_client_confd, DEBUG_MODE_ALL))
+ DEBUG_CLEAR(&nb_dbg_client_confd);
+
+ return 0;
+}
+
+static void frr_confd_cli_init(void)
+{
+ hook_register(nb_client_debug_config_write,
+ frr_confd_debug_config_write);
+ hook_register(nb_client_debug_set_all, frr_confd_debug_set_all);
+
+ install_element(ENABLE_NODE, &debug_nb_confd_cmd);
+ install_element(CONFIG_NODE, &debug_nb_confd_cmd);
+}
+
/* ------------ Main ------------ */
static int frr_confd_calculate_snode_hash(const struct lys_node *snode,
@@ -1407,6 +1460,7 @@ static int frr_confd_module_late_init(struct thread_master *tm)
}
hook_register(frr_fini, frr_confd_finish);
+ frr_confd_cli_init();
return 0;
}