forked from Mirror/frr
lib: always call new notification hooks too
- call the new notification hooks when backends call the old notification posting API. Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
parent
fa67c0b91c
commit
1d4ea437e4
|
@ -163,6 +163,8 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg,
|
||||||
_hook_unregister(&_hook_##hookname, \
|
_hook_unregister(&_hook_##hookname, \
|
||||||
_hook_typecheck_arg_##hookname(func), arg, true)
|
_hook_typecheck_arg_##hookname(func), arg, true)
|
||||||
|
|
||||||
|
#define hook_have_hooks(hookname) (_hook_##hookname.entries != NULL)
|
||||||
|
|
||||||
/* invoke hooks
|
/* invoke hooks
|
||||||
* this is private (static) to the file that has the DEFINE_HOOK statement
|
* this is private (static) to the file that has the DEFINE_HOOK statement
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -311,13 +311,15 @@ static int be_client_send_error(struct mgmt_be_client *client, uint64_t txn_id,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mgmt_be_send_notification(struct lyd_node *tree)
|
static int mgmt_be_send_notification(void *__be_client, const char *xpath,
|
||||||
|
const struct lyd_node *tree)
|
||||||
{
|
{
|
||||||
struct mgmt_be_client *client = __be_client;
|
struct mgmt_be_client *client = __be_client;
|
||||||
struct mgmt_msg_notify_data *msg = NULL;
|
struct mgmt_msg_notify_data *msg = NULL;
|
||||||
LYD_FORMAT format = LYD_JSON;
|
LYD_FORMAT format = LYD_JSON;
|
||||||
uint8_t **darrp;
|
uint8_t **darrp;
|
||||||
LY_ERR err;
|
LY_ERR err;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
assert(tree);
|
assert(tree);
|
||||||
|
|
||||||
|
@ -339,6 +341,7 @@ void mgmt_be_send_notification(struct lyd_node *tree)
|
||||||
flog_err(EC_LIB_LIBYANG,
|
flog_err(EC_LIB_LIBYANG,
|
||||||
"%s: error creating notification data: %s", __func__,
|
"%s: error creating notification data: %s", __func__,
|
||||||
ly_strerrcode(err));
|
ly_strerrcode(err));
|
||||||
|
ret = 1;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,53 +349,7 @@ void mgmt_be_send_notification(struct lyd_node *tree)
|
||||||
mgmt_msg_native_get_msg_len(msg), false);
|
mgmt_msg_native_get_msg_len(msg), false);
|
||||||
done:
|
done:
|
||||||
mgmt_msg_native_free_msg(msg);
|
mgmt_msg_native_free_msg(msg);
|
||||||
lyd_free_all(tree);
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert old style NB notification data into new MGMTD YANG tree and send.
|
|
||||||
*/
|
|
||||||
static int mgmt_be_notification_send(void *arg, const char *xpath,
|
|
||||||
struct list *args)
|
|
||||||
{
|
|
||||||
struct lyd_node *root = NULL;
|
|
||||||
struct lyd_node *dnode;
|
|
||||||
struct yang_data *data;
|
|
||||||
struct listnode *ln;
|
|
||||||
LY_ERR err;
|
|
||||||
|
|
||||||
debug_be_client("%s: sending notification: %s", __func__, xpath);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert yang data args list to a libyang data tree
|
|
||||||
*/
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(args, ln, data)) {
|
|
||||||
err = lyd_new_path(root, ly_native_ctx, data->xpath,
|
|
||||||
data->value, LYD_NEW_PATH_UPDATE, &dnode);
|
|
||||||
if (err != LY_SUCCESS) {
|
|
||||||
lyerr:
|
|
||||||
flog_err(EC_LIB_LIBYANG,
|
|
||||||
"%s: error creating notification data: %s",
|
|
||||||
__func__, ly_strerrcode(err));
|
|
||||||
if (root)
|
|
||||||
lyd_free_all(root);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (!root) {
|
|
||||||
root = dnode;
|
|
||||||
while (root->parent)
|
|
||||||
root = lyd_parent(root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!root) {
|
|
||||||
err = lyd_new_path(NULL, ly_native_ctx, xpath, "", 0, &root);
|
|
||||||
if (err)
|
|
||||||
goto lyerr;
|
|
||||||
}
|
|
||||||
|
|
||||||
mgmt_be_send_notification(root);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mgmt_be_send_txn_reply(struct mgmt_be_client *client_ctx,
|
static int mgmt_be_send_txn_reply(struct mgmt_be_client *client_ctx,
|
||||||
|
@ -1202,7 +1159,7 @@ struct mgmt_be_client *mgmt_be_client_create(const char *client_name,
|
||||||
"BE-client", debug_check_be_client());
|
"BE-client", debug_check_be_client());
|
||||||
|
|
||||||
/* Hook to receive notifications */
|
/* Hook to receive notifications */
|
||||||
hook_register_arg(nb_notification_send, mgmt_be_notification_send,
|
hook_register_arg(nb_notification_tree_send, mgmt_be_send_notification,
|
||||||
client);
|
client);
|
||||||
|
|
||||||
debug_be_client("Initialized client '%s'", client_name);
|
debug_be_client("Initialized client '%s'", client_name);
|
||||||
|
|
|
@ -143,15 +143,6 @@ extern int mgmt_be_send_subscr_req(struct mgmt_be_client *client_ctx,
|
||||||
int n_config_xpaths, char **config_xpaths,
|
int n_config_xpaths, char **config_xpaths,
|
||||||
int n_oper_xpaths, char **oper_xpaths);
|
int n_oper_xpaths, char **oper_xpaths);
|
||||||
|
|
||||||
/**
|
|
||||||
* mgmt_be_notification_send() - send a YANG notification to FE clients.
|
|
||||||
* @tree: libyang tree for the notification. The tree will be freed by
|
|
||||||
* this function.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
extern void mgmt_be_send_notification(struct lyd_node *tree);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Destroy backend client and cleanup everything.
|
* Destroy backend client and cleanup everything.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2076,20 +2076,68 @@ DEFINE_HOOK(nb_notification_send, (const char *xpath, struct list *arguments),
|
||||||
|
|
||||||
int nb_notification_send(const char *xpath, struct list *arguments)
|
int nb_notification_send(const char *xpath, struct list *arguments)
|
||||||
{
|
{
|
||||||
|
struct lyd_node *root = NULL;
|
||||||
|
struct lyd_node *dnode;
|
||||||
|
struct yang_data *data;
|
||||||
|
struct listnode *ln;
|
||||||
|
LY_ERR err;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DEBUGD(&nb_dbg_notif, "northbound notification: %s", xpath);
|
DEBUGD(&nb_dbg_notif, "northbound notification: %s", xpath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call old hook functions
|
||||||
|
*/
|
||||||
ret = hook_call(nb_notification_send, xpath, arguments);
|
ret = hook_call(nb_notification_send, xpath, arguments);
|
||||||
|
|
||||||
|
if (!hook_have_hooks(nb_notification_tree_send))
|
||||||
|
goto done;
|
||||||
|
/*
|
||||||
|
* Convert yang data arguments list to a libyang data tree for new hook
|
||||||
|
* functions.
|
||||||
|
*/
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(arguments, ln, data)) {
|
||||||
|
err = lyd_new_path(root, ly_native_ctx, data->xpath,
|
||||||
|
data->value, LYD_NEW_PATH_UPDATE, &dnode);
|
||||||
|
if (err != LY_SUCCESS)
|
||||||
|
goto lyerr;
|
||||||
|
if (!root) {
|
||||||
|
root = dnode;
|
||||||
|
while (root->parent)
|
||||||
|
root = lyd_parent(root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!root) {
|
||||||
|
err = lyd_new_path(NULL, ly_native_ctx, xpath, "", 0, &root);
|
||||||
|
if (err) {
|
||||||
|
lyerr:
|
||||||
|
flog_err(EC_LIB_LIBYANG,
|
||||||
|
"%s: error creating notification data: %s",
|
||||||
|
__func__, ly_strerrcode(err));
|
||||||
|
ret += 1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call new hook functions
|
||||||
|
*/
|
||||||
|
ret += nb_notification_tree_send(xpath, root);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (root)
|
||||||
|
lyd_free_all(root);
|
||||||
if (arguments)
|
if (arguments)
|
||||||
list_delete(&arguments);
|
list_delete(&arguments);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_HOOK(nb_notification_tree_send, (struct lyd_node *tree), (tree));
|
DEFINE_HOOK(nb_notification_tree_send,
|
||||||
|
(const char *xpath, const struct lyd_node *tree), (xpath, tree));
|
||||||
|
|
||||||
int nb_notification_tree_send(struct lyd_node *tree)
|
int nb_notification_tree_send(const char *xpath, const struct lyd_node *tree)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -2098,8 +2146,7 @@ int nb_notification_tree_send(struct lyd_node *tree)
|
||||||
DEBUGD(&nb_dbg_notif, "northbound tree notification: %s",
|
DEBUGD(&nb_dbg_notif, "northbound tree notification: %s",
|
||||||
tree->schema->name);
|
tree->schema->name);
|
||||||
|
|
||||||
ret = hook_call(nb_notification_tree_send, tree);
|
ret = hook_call(nb_notification_tree_send, xpath, tree);
|
||||||
lyd_free_all(tree);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -803,6 +803,8 @@ typedef enum nb_error (*nb_oper_data_finish_cb)(const struct lyd_node *tree,
|
||||||
/* Hooks. */
|
/* Hooks. */
|
||||||
DECLARE_HOOK(nb_notification_send, (const char *xpath, struct list *arguments),
|
DECLARE_HOOK(nb_notification_send, (const char *xpath, struct list *arguments),
|
||||||
(xpath, arguments));
|
(xpath, arguments));
|
||||||
|
DECLARE_HOOK(nb_notification_tree_send,
|
||||||
|
(const char *xpath, const struct lyd_node *tree), (xpath, tree));
|
||||||
DECLARE_HOOK(nb_client_debug_config_write, (struct vty *vty), (vty));
|
DECLARE_HOOK(nb_client_debug_config_write, (struct vty *vty), (vty));
|
||||||
DECLARE_HOOK(nb_client_debug_set_all, (uint32_t flags, bool set), (flags, set));
|
DECLARE_HOOK(nb_client_debug_set_all, (uint32_t flags, bool set), (flags, set));
|
||||||
|
|
||||||
|
@ -1491,14 +1493,17 @@ extern int nb_notification_send(const char *xpath, struct list *arguments);
|
||||||
* Send a YANG notification from a backend . This is a no-op unless th
|
* Send a YANG notification from a backend . This is a no-op unless th
|
||||||
* 'nb_notification_tree_send' hook was registered by a northbound plugin.
|
* 'nb_notification_tree_send' hook was registered by a northbound plugin.
|
||||||
*
|
*
|
||||||
|
* xpath
|
||||||
|
* XPath of the YANG notification.
|
||||||
|
*
|
||||||
* tree
|
* tree
|
||||||
* The libyang tree for the notification. The tree will be freed by
|
* The libyang tree for the notification.
|
||||||
* this call.
|
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* NB_OK on success, NB_ERR otherwise.
|
* NB_OK on success, NB_ERR otherwise.
|
||||||
*/
|
*/
|
||||||
extern int nb_notification_tree_send(struct lyd_node *tree);
|
extern int nb_notification_tree_send(const char *xpath,
|
||||||
|
const struct lyd_node *tree);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Associate a user pointer to a configuration node.
|
* Associate a user pointer to a configuration node.
|
||||||
|
|
Loading…
Reference in a new issue