summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/mgmt_be_client.c44
-rw-r--r--lib/northbound.c3
-rw-r--r--lib/northbound.h3
3 files changed, 39 insertions, 11 deletions
diff --git a/lib/mgmt_be_client.c b/lib/mgmt_be_client.c
index 3a07a1d2d9..806242ed53 100644
--- a/lib/mgmt_be_client.c
+++ b/lib/mgmt_be_client.c
@@ -1114,19 +1114,24 @@ static void be_client_handle_notify(struct mgmt_be_client *client, void *msgbuf,
size_t msg_len)
{
struct mgmt_msg_notify_data *notif_msg = msgbuf;
- struct nb_node *nb_node;
- struct lyd_node *dnode;
+ struct nb_node *nb_node, *nb_parent;
+ struct lyd_node *dnode = NULL;
const char *data = NULL;
const char *notif;
- LY_ERR err;
+ bool is_yang_notify;
+ LY_ERR err = LY_SUCCESS;
debug_be_client("Received notification for client %s", client->name);
notif = mgmt_msg_native_xpath_data_decode(notif_msg, msg_len, data);
- if (!notif || !data) {
+ if (!notif) {
log_err_be_client("Corrupt notify msg");
return;
}
+ if (!data && (notif_msg->op == NOTIFY_OP_DS_REPLACE || notif_msg->op == NOTIFY_OP_DS_PATCH)) {
+ log_err_be_client("Corrupt replace/patch notify msg: missing data");
+ return;
+ }
nb_node = nb_node_find(notif);
if (!nb_node) {
@@ -1134,20 +1139,41 @@ static void be_client_handle_notify(struct mgmt_be_client *client, void *msgbuf,
return;
}
- if (!nb_node->cbs.notify) {
+ is_yang_notify = !!CHECK_FLAG(nb_node->snode->nodetype, LYS_NOTIF);
+
+ if (is_yang_notify && !nb_node->cbs.notify) {
debug_be_client("No notification callback for: %s", notif);
return;
}
- err = yang_parse_notification(notif, notif_msg->result_type, data,
+ if (!nb_node->cbs.notify) {
+ /*
+ * See if a parent has a callback, this is so backend's can
+ * listen for changes on an entire datastore sub-tree.
+ */
+ for (nb_parent = nb_node->parent; nb_parent; nb_parent = nb_node->parent)
+ if (nb_parent->cbs.notify)
+ break;
+ if (!nb_parent) {
+ debug_be_client("Including parents, no DS notification callback for: %s",
+ notif);
+ return;
+ }
+ nb_node = nb_parent;
+ }
+
+ if (data && is_yang_notify) {
+ err = yang_parse_notification(notif, notif_msg->result_type, data, &dnode);
+ } else if (data) {
+ err = yang_parse_data(notif, notif_msg->result_type, false, true, false, data,
&dnode);
+ }
if (err) {
- log_err_be_client("Can't parse notification data for: %s",
- notif);
+ log_err_be_client("Can't parse notification data for: %s", notif);
return;
}
- nb_callback_notify(nb_node, notif, dnode);
+ nb_callback_notify(nb_node, notif_msg->op, notif, dnode);
lyd_free_all(dnode);
}
diff --git a/lib/northbound.c b/lib/northbound.c
index 418cb246f6..400309a750 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -1857,7 +1857,7 @@ int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
return nb_node->cbs.rpc(&args);
}
-void nb_callback_notify(const struct nb_node *nb_node, const char *xpath,
+void nb_callback_notify(const struct nb_node *nb_node, uint8_t op, const char *xpath,
struct lyd_node *dnode)
{
struct nb_cb_notify_args args = {};
@@ -1865,6 +1865,7 @@ void nb_callback_notify(const struct nb_node *nb_node, const char *xpath,
DEBUGD(&nb_dbg_cbs_notify, "northbound notify: %s", xpath);
args.xpath = xpath;
+ args.op = op;
args.dnode = dnode;
nb_node->cbs.notify(&args);
}
diff --git a/lib/northbound.h b/lib/northbound.h
index ce59bfd01a..c31f007e70 100644
--- a/lib/northbound.h
+++ b/lib/northbound.h
@@ -305,6 +305,7 @@ struct nb_cb_rpc_args {
struct nb_cb_notify_args {
/* XPath of the notification. */
const char *xpath;
+ uint8_t op;
/*
* libyang data node representing the notification. If the notification
@@ -861,7 +862,7 @@ extern const void *nb_callback_lookup_next(const struct nb_node *nb_node,
extern int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
const struct lyd_node *input, struct lyd_node *output,
char *errmsg, size_t errmsg_len);
-extern void nb_callback_notify(const struct nb_node *nb_node, const char *xpath,
+extern void nb_callback_notify(const struct nb_node *nb_node, uint8_t op, const char *xpath,
struct lyd_node *dnode);
/*