forked from Mirror/frr
lib: mgmt_be_client handles datastore notification using CBs
Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
parent
2375a11b08
commit
94f70c2100
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue