]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: always call new notification hooks too
authorChristian Hopps <chopps@labn.net>
Mon, 12 Feb 2024 18:03:32 +0000 (13:03 -0500)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Tue, 20 Feb 2024 17:14:54 +0000 (17:14 +0000)
- call the new notification hooks when backends call the old notification
posting API.

Signed-off-by: Christian Hopps <chopps@labn.net>
(cherry picked from commit 1d4ea437e4a4fced3fce6e441952fdea8d94af80)

lib/hook.h
lib/mgmt_be_client.c
lib/mgmt_be_client.h
lib/northbound.c
lib/northbound.h

index 19e0f1fbfce784b7162f814556da268af6aafd82..58aa2009b961578b353f8ffe5c2576a70f5ac05c 100644 (file)
@@ -163,6 +163,8 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg,
        _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
  */
index 286555c56484798b7bb0dc592fb7201ed20e8ea0..589bf82c95c6193ef05a8c97ce69071bf7c392d1 100644 (file)
@@ -311,13 +311,15 @@ static int be_client_send_error(struct mgmt_be_client *client, uint64_t txn_id,
        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);
 
@@ -339,6 +341,7 @@ void mgmt_be_send_notification(struct lyd_node *tree)
                flog_err(EC_LIB_LIBYANG,
                         "%s: error creating notification data: %s", __func__,
                         ly_strerrcode(err));
+               ret = 1;
                goto done;
        }
 
@@ -346,53 +349,7 @@ void mgmt_be_send_notification(struct lyd_node *tree)
                                        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,
@@ -1202,7 +1159,7 @@ struct mgmt_be_client *mgmt_be_client_create(const char *client_name,
                        "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);
index 361899fc1da01184aa77ec5d28bdc6a17267f41a..cd8b23752671e4b4dda6fe8d6d8cfd9673fc5e78 100644 (file)
@@ -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_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.
  */
index d74773194c717f18c9a5ab9235f00d1deadb4a96..a3d91e56afb348cdb86c7d178686db85d96d3d6f 100644 (file)
@@ -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)
 {
+       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;
 
@@ -2098,8 +2146,7 @@ int nb_notification_tree_send(struct lyd_node *tree)
        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;
 }
index e9f2db9b6ef368db0d17a17fae0e89ebf771c72a..5be111cf0a1225ffb8edfb3a52514bf32f5fb104 100644 (file)
@@ -803,6 +803,8 @@ typedef enum nb_error (*nb_oper_data_finish_cb)(const struct lyd_node *tree,
 /* 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));
 
@@ -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
  * '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.