_hook_unregister(&_hook_##hookname, \
_hook_typecheck_arg_##hookname(func), arg, true)
+#define hook_have_hooks(hookname) (_hook_##hookname.entries != NULL)
+
/* invoke hooks
* this is private (static) to the file that has the DEFINE_HOOK statement
*/
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_msg_notify_data *msg = NULL;
LYD_FORMAT format = LYD_JSON;
uint8_t **darrp;
LY_ERR err;
+ int ret = 0;
assert(tree);
flog_err(EC_LIB_LIBYANG,
"%s: error creating notification data: %s", __func__,
ly_strerrcode(err));
+ ret = 1;
goto done;
}
mgmt_msg_native_get_msg_len(msg), false);
done:
mgmt_msg_native_free_msg(msg);
- lyd_free_all(tree);
-}
-
-/*
- * 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;
+ return ret;
}
static int mgmt_be_send_txn_reply(struct mgmt_be_client *client_ctx,
"BE-client", debug_check_be_client());
/* 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);
debug_be_client("Initialized client '%s'", client_name);
int n_config_xpaths, char **config_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.
*/
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;
DEBUGD(&nb_dbg_notif, "northbound notification: %s", xpath);
+ /*
+ * Call old hook functions
+ */
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)
list_delete(&arguments);
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;
DEBUGD(&nb_dbg_notif, "northbound tree notification: %s",
tree->schema->name);
- ret = hook_call(nb_notification_tree_send, tree);
- lyd_free_all(tree);
+ ret = hook_call(nb_notification_tree_send, xpath, tree);
return ret;
}
/* Hooks. */
DECLARE_HOOK(nb_notification_send, (const char *xpath, struct list *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_set_all, (uint32_t flags, bool set), (flags, set));
* 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.
*
+ * xpath
+ * XPath of the YANG notification.
+ *
* tree
- * The libyang tree for the notification. The tree will be freed by
- * this call.
+ * The libyang tree for the notification.
*
* Returns:
* 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.