diff options
| author | Christian Hopps <chopps@labn.net> | 2025-01-16 04:13:08 +0000 | 
|---|---|---|
| committer | Christian Hopps <chopps@labn.net> | 2025-01-18 16:13:54 +0000 | 
| commit | 94f70c2100ef6709e03f28c541a8bfb175eff2c8 (patch) | |
| tree | ccecb85a36b4a96cd4b7634051f3cce70d43cfea /lib | |
| parent | 2375a11b088a6c8bc6f9133d7873d7096f7daa00 (diff) | |
lib: mgmt_be_client handles datastore notification using CBs
Signed-off-by: Christian Hopps <chopps@labn.net>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/mgmt_be_client.c | 44 | ||||
| -rw-r--r-- | lib/northbound.c | 3 | ||||
| -rw-r--r-- | lib/northbound.h | 3 | 
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);  /*  | 
