lib: mgmt_be_client handles datastore notification using CBs

Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
Christian Hopps 2025-01-16 04:13:08 +00:00
parent 2375a11b08
commit 94f70c2100
3 changed files with 39 additions and 11 deletions

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
/*