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)
|
size_t msg_len)
|
||||||
{
|
{
|
||||||
struct mgmt_msg_notify_data *notif_msg = msgbuf;
|
struct mgmt_msg_notify_data *notif_msg = msgbuf;
|
||||||
struct nb_node *nb_node;
|
struct nb_node *nb_node, *nb_parent;
|
||||||
struct lyd_node *dnode;
|
struct lyd_node *dnode = NULL;
|
||||||
const char *data = NULL;
|
const char *data = NULL;
|
||||||
const char *notif;
|
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);
|
debug_be_client("Received notification for client %s", client->name);
|
||||||
|
|
||||||
notif = mgmt_msg_native_xpath_data_decode(notif_msg, msg_len, data);
|
notif = mgmt_msg_native_xpath_data_decode(notif_msg, msg_len, data);
|
||||||
if (!notif || !data) {
|
if (!notif) {
|
||||||
log_err_be_client("Corrupt notify msg");
|
log_err_be_client("Corrupt notify msg");
|
||||||
return;
|
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);
|
nb_node = nb_node_find(notif);
|
||||||
if (!nb_node) {
|
if (!nb_node) {
|
||||||
|
@ -1134,20 +1139,41 @@ static void be_client_handle_notify(struct mgmt_be_client *client, void *msgbuf,
|
||||||
return;
|
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);
|
debug_be_client("No notification callback for: %s", notif);
|
||||||
return;
|
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);
|
&dnode);
|
||||||
|
}
|
||||||
if (err) {
|
if (err) {
|
||||||
log_err_be_client("Can't parse notification data for: %s",
|
log_err_be_client("Can't parse notification data for: %s", notif);
|
||||||
notif);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nb_callback_notify(nb_node, notif, dnode);
|
nb_callback_notify(nb_node, notif_msg->op, notif, dnode);
|
||||||
|
|
||||||
lyd_free_all(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);
|
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 lyd_node *dnode)
|
||||||
{
|
{
|
||||||
struct nb_cb_notify_args args = {};
|
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);
|
DEBUGD(&nb_dbg_cbs_notify, "northbound notify: %s", xpath);
|
||||||
|
|
||||||
args.xpath = xpath;
|
args.xpath = xpath;
|
||||||
|
args.op = op;
|
||||||
args.dnode = dnode;
|
args.dnode = dnode;
|
||||||
nb_node->cbs.notify(&args);
|
nb_node->cbs.notify(&args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,6 +305,7 @@ struct nb_cb_rpc_args {
|
||||||
struct nb_cb_notify_args {
|
struct nb_cb_notify_args {
|
||||||
/* XPath of the notification. */
|
/* XPath of the notification. */
|
||||||
const char *xpath;
|
const char *xpath;
|
||||||
|
uint8_t op;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* libyang data node representing the notification. If the notification
|
* 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,
|
extern int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
|
||||||
const struct lyd_node *input, struct lyd_node *output,
|
const struct lyd_node *input, struct lyd_node *output,
|
||||||
char *errmsg, size_t errmsg_len);
|
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);
|
struct lyd_node *dnode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue