]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: add dedicated API functions for native msgs
authorChristian Hopps <chopps@labn.net>
Wed, 13 Dec 2023 22:32:43 +0000 (17:32 -0500)
committerChristian Hopps <chopps@labn.net>
Thu, 28 Dec 2023 17:53:40 +0000 (17:53 +0000)
- reorg native message header

Signed-off-by: Christian Hopps <chopps@labn.net>
lib/mgmt_be_client.c
lib/mgmt_fe_client.c
lib/mgmt_msg.c
lib/mgmt_msg_native.c
lib/mgmt_msg_native.h
mgmtd/mgmt_be_adapter.c
mgmtd/mgmt_be_adapter.h
mgmtd/mgmt_fe_adapter.c
mgmtd/mgmt_txn.c

index 020096666360b3c5c1d6bd6377492284d0278a12..2ffcd8f9fc2e4c6a72718905f18cc3f8985b612a 100644 (file)
@@ -787,8 +787,8 @@ static enum nb_error be_client_send_tree_data_batch(const struct lyd_node *tree,
        struct be_client_tree_data_batch_args *args = arg;
        struct mgmt_be_client *client = args->client;
        struct mgmt_msg_tree_data *tree_msg = NULL;
-       uint8_t *buf = NULL;
        bool more = false;
+       uint8_t **darrp;
        LY_ERR err;
 
        if (ret == NB_YIELD) {
@@ -798,26 +798,27 @@ static enum nb_error be_client_send_tree_data_batch(const struct lyd_node *tree,
        if (ret != NB_OK)
                goto done;
 
-       darr_append_nz(buf, offsetof(typeof(*tree_msg), result));
-       tree_msg = (typeof(tree_msg))buf;
-       tree_msg->txn_id = args->txn_id;
+       tree_msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_tree_data, 0,
+                                            MTYPE_MSG_NATIVE_TREE_DATA);
+       tree_msg->refer_id = args->txn_id;
        tree_msg->req_id = args->req_id;
        tree_msg->code = MGMT_MSG_CODE_TREE_DATA;
        tree_msg->result_type = args->result_type;
        tree_msg->more = more;
-       err = yang_print_tree_append(&buf, tree, args->result_type,
+
+       darrp = mgmt_msg_native_get_darrp(tree_msg);
+       err = yang_print_tree_append(darrp, tree, args->result_type,
                                     (LYD_PRINT_WD_EXPLICIT |
                                      LYD_PRINT_WITHSIBLINGS));
-       /* buf may have been reallocated and moved */
-       tree_msg = (typeof(tree_msg))buf;
-
        if (err) {
                ret = NB_ERR;
                goto done;
        }
-       (void)be_client_send_native_msg(client, buf, darr_len(buf), false);
+       (void)be_client_send_native_msg(client, tree_msg,
+                                       mgmt_msg_native_get_msg_len(tree_msg),
+                                       false);
 done:
-       darr_free(buf);
+       mgmt_msg_native_free_msg(tree_msg);
        if (ret)
                be_client_send_error(client, args->txn_id, args->req_id, false,
                                     -EINVAL,
@@ -849,7 +850,7 @@ static void be_client_handle_get_tree(struct mgmt_be_client *client,
 
        args = XMALLOC(MTYPE_MGMTD_BE_GT_CB_ARGS, sizeof(*args));
        args->client = client;
-       args->txn_id = get_tree_msg->txn_id;
+       args->txn_id = get_tree_msg->refer_id;
        args->req_id = get_tree_msg->req_id;
        args->result_type = get_tree_msg->result_type;
        nb_oper_walk(get_tree_msg->xpath, NULL, 0, true, NULL, NULL,
@@ -865,7 +866,7 @@ static void be_client_handle_native_msg(struct mgmt_be_client *client,
                                        struct mgmt_msg_header *msg,
                                        size_t msg_len)
 {
-       uint64_t txn_id = msg->txn_id;
+       uint64_t txn_id = msg->refer_id;
 
        switch (msg->code) {
        case MGMT_MSG_CODE_GET_TREE:
@@ -876,7 +877,7 @@ static void be_client_handle_native_msg(struct mgmt_be_client *client,
                                    " req-id %" PRIu64 " code %u to client %s",
                                    txn_id, msg->req_id, msg->code,
                                    client->name);
-               be_client_send_error(client, msg->txn_id, msg->req_id, false, -1,
+               be_client_send_error(client, msg->refer_id, msg->req_id, false, -1,
                                     "BE cilent %s recv msg unknown txn-id %" PRIu64,
                                     client->name, txn_id);
                break;
index f6ae485c5cbf47c9ae532881ef0853457cc20a7d..c30a0339ebf5883887eee502c2900f8ebb74c376 100644 (file)
@@ -35,7 +35,6 @@ DECLARE_LIST(mgmt_sessions, struct mgmt_fe_client_session, list_linkage);
 
 DEFINE_MTYPE_STATIC(LIB, MGMTD_FE_CLIENT, "frontend client");
 DEFINE_MTYPE_STATIC(LIB, MGMTD_FE_CLIENT_NAME, "frontend client name");
-DEFINE_MTYPE_STATIC(LIB, MGMTD_FE_GET_DATA_MSG, "FE get data msg");
 DEFINE_MTYPE_STATIC(LIB, MGMTD_FE_SESSION, "frontend session");
 
 struct mgmt_fe_client {
@@ -111,13 +110,6 @@ mgmt_fe_find_session_by_session_id(struct mgmt_fe_client *client,
        return NULL;
 }
 
-static int fe_client_send_native_msg(struct mgmt_fe_client *client, void *msg,
-                                    size_t len, bool short_circuit_ok)
-{
-       return msg_conn_send_msg(&client->client.conn, MGMT_MSG_VERSION_NATIVE,
-                                msg, len, NULL, short_circuit_ok);
-}
-
 static int mgmt_fe_client_send_msg(struct mgmt_fe_client *client,
                                   Mgmtd__FeMessage *fe_msg,
                                   bool short_circuit_ok)
@@ -322,11 +314,11 @@ int mgmt_fe_send_get_tree_req(struct mgmt_fe_client *client,
 {
        struct mgmt_msg_get_tree *msg;
        size_t xplen = strlen(xpath);
-       size_t mlen = sizeof(*msg) + xplen + 1;
        int ret;
 
-       msg = XCALLOC(MTYPE_MGMTD_FE_GET_DATA_MSG, mlen);
-       msg->session_id = session_id;
+       msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_get_tree, xplen + 1,
+                                       MTYPE_MSG_NATIVE_GET_TREE);
+       msg->refer_id = session_id;
        msg->req_id = req_id;
        msg->code = MGMT_MSG_CODE_GET_TREE;
        msg->result_type = result_type;
@@ -336,8 +328,8 @@ int mgmt_fe_send_get_tree_req(struct mgmt_fe_client *client,
                            " req-id %" PRIu64 " xpath: %s",
                            session_id, req_id, xpath);
 
-       ret = fe_client_send_native_msg(client, msg, mlen, false);
-       XFREE(MTYPE_MGMTD_FE_GET_DATA_MSG, msg);
+       ret = mgmt_msg_native_send_msg(&client->client.conn, msg, false);
+       mgmt_msg_native_free_msg(msg);
        return ret;
 }
 
@@ -519,13 +511,13 @@ static void fe_client_handle_native_msg(struct mgmt_fe_client *client,
        struct mgmt_msg_error *err_msg;
 
        MGMTD_FE_CLIENT_DBG("Got GET_TREE reply for session-id %" PRIu64,
-                           msg->session_id);
+                           msg->refer_id);
 
-       session = mgmt_fe_find_session_by_session_id(client, msg->session_id);
+       session = mgmt_fe_find_session_by_session_id(client, msg->refer_id);
 
        if (!session || !session->client) {
                MGMTD_FE_CLIENT_ERR("No session for received native msg session-id %" PRIu64,
-                                   msg->session_id);
+                                   msg->refer_id);
                return;
        }
 
@@ -541,7 +533,7 @@ static void fe_client_handle_native_msg(struct mgmt_fe_client *client,
                }
                session->client->cbs.error_notify(client, client->user_data,
                                                  session->client_id,
-                                                 msg->session_id,
+                                                 msg->refer_id,
                                                  session->user_ctx,
                                                  msg->req_id, err_msg->error,
                                                  err_msg->errstr);
@@ -557,7 +549,7 @@ static void fe_client_handle_native_msg(struct mgmt_fe_client *client,
                }
                session->client->cbs.get_tree_notify(client, client->user_data,
                                                     session->client_id,
-                                                    msg->session_id,
+                                                    msg->refer_id,
                                                     session->user_ctx,
                                                     msg->req_id,
                                                     MGMTD_DS_OPERATIONAL,
@@ -569,7 +561,7 @@ static void fe_client_handle_native_msg(struct mgmt_fe_client *client,
        default:
                MGMTD_FE_CLIENT_ERR("unknown native message session-id %" PRIu64
                                    " req-id %" PRIu64 " code %u",
-                                   msg->session_id, msg->req_id, msg->code);
+                                   msg->refer_id, msg->req_id, msg->code);
                break;
        }
 }
index d8a7fde435f9a7c540884e7fbd17d99d5cbd57e6..b03dbe8cc3e24d670ab04cb19aec17ac9de62b6c 100644 (file)
@@ -348,7 +348,7 @@ int mgmt_msg_send_msg(struct mgmt_msg_state *ms, uint8_t version, void *msg,
                MGMT_MSG_DBG(
                        dbgtag,
                        "Sending native msg sess/txn-id %"PRIu64" req-id %"PRIu64" code %u",
-                       native_msg->session_id, native_msg->req_id, native_msg->code);
+                       native_msg->refer_id, native_msg->req_id, native_msg->code);
 
        }
 
index a9e8a1711de4b14c01b7a4ff9bc64df5392b6d94..b6dc126d49c83329a4152f697867612fdafec58d 100644 (file)
 
 DEFINE_MGROUP(MSG_NATIVE, "Native message allocations");
 DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_MSG, "native mgmt msg");
-DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_ERROR, "native mgmt error msg");
+DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_ERROR, "native error msg");
+DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_GET_TREE, "native get tree msg");
+DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_TREE_DATA, "native tree data msg");
 
 int vmgmt_msg_native_send_error(struct msg_conn *conn, uint64_t sess_or_txn_id,
                                uint64_t req_id, bool short_circuit_ok,
                                int16_t error, const char *errfmt, va_list ap)
 {
        struct mgmt_msg_error *msg;
+       char *errstr;
        ssize_t slen;
-       size_t mlen;
        int ret;
 
-       msg = XCALLOC(MTYPE_MSG_NATIVE_ERROR, 1024);
-       msg->session_id = sess_or_txn_id;
+       errstr = darr_vsprintf(errfmt, ap);
+       slen = strlen(errstr);
+
+       msg = mgmt_msg_native_alloc_msg(typeof(*msg), slen + 1,
+                                       MTYPE_MSG_NATIVE_ERROR);
+       msg->refer_id = sess_or_txn_id;
        msg->req_id = req_id;
        msg->code = MGMT_MSG_CODE_ERROR;
        msg->error = error;
-
-       slen = vsnprintfrr(msg->errstr, 1024 - sizeof(*msg), errfmt, ap);
-       mlen = MIN(slen + sizeof(*msg) + 1, 1024);
+       strlcpy(msg->errstr, errstr, slen + 1);
+       darr_free(errstr);
 
        if (conn->debug)
                zlog_debug("Sending error %d session-id %" PRIu64
@@ -36,10 +41,7 @@ int vmgmt_msg_native_send_error(struct msg_conn *conn, uint64_t sess_or_txn_id,
                           error, sess_or_txn_id, req_id, short_circuit_ok,
                           msg->errstr);
 
-       ret = msg_conn_send_msg(conn, MGMT_MSG_VERSION_NATIVE, msg, mlen, NULL,
-                               short_circuit_ok);
-
-       XFREE(MTYPE_MSG_NATIVE_ERROR, msg);
-
+       ret = mgmt_msg_native_send_msg(conn, msg, short_circuit_ok);
+       mgmt_msg_native_free_msg(msg);
        return ret;
 }
index a3b456efaac1862ccdaeca966e12c43d47067e42..3f6283025c3e29c46745fff37f2c3df35675d037 100644 (file)
@@ -17,14 +17,131 @@ extern "C" {
 
 #include <zebra.h>
 #include "compiler.h"
+#include "darr.h"
 #include "memory.h"
 #include "mgmt_msg.h"
 #include "mgmt_defines.h"
 
 #include <stdalign.h>
 
+/*
+ * ==================
+ * Native Message API
+ * ==================
+ *
+ * -----------------------
+ * Defining A New Message:
+ * -----------------------
+ *
+ *  1) Start with `struct mgmt_msg_header` as the first (unnamed) field.
+ *
+ *  2) Add fixed-width fields. Add on natural aligned boundaries (*)
+ *
+ *  3) [Optional] Add a zero-length variable field. Add aligned on a 64-bit
+ *     boundary, this is done so that: `value = (HDR + 1)` works.
+ *
+ *  4) Define a new MTYPE for the new message type (see DECLARE_MTYPE below
+ *     as well as the paired DEFINE_MTYPE in mgmt_msg_native.c)
+ *
+ * These rules are so the messages may be read from and written directly to
+ * "the wire", easily, using common programming languages (e.g., C, rust, go,
+ * python, ...)
+ *
+ * (*) Natrual aligned boundaries, i.e., uint16_t on 2-byte boundary, uint64_t
+ * on 8-byte boundaries, ...)
+ *
+ * ------------------------------
+ * Allocating New Native Messages
+ * ------------------------------
+ *
+ * For fixed-length and variable length messages one should allocate new
+ * messages with the mgmt_msg_native_alloc_msg() passing in the newly defined
+ * MTYPE. Likewise, to free the message one should use
+ * mgmt_msg_native_free_msg().
+ *
+ * Unknown Variable Length Messages:
+ * ---------------------------------
+ *
+ * If using a zero-length variable length field and the length is not known at
+ * message creation time, you can use the `native` API function
+ * mgmt_msg_native_append() to add data to the end of the message, or if a more
+ * full set of operations are required, the darr_xxxx() API is also available as
+ * in the Advanced section below.
+ *
+ * Notable API Functions:
+ * ---------------------------------
+ *
+ * mgmt_msg_native_alloc_msg() - Allocate a native msg.
+ * mgmt_msg_native_free_msg() - Free a native msg.
+ * mgmt_msg_native_append() - Append data to the end of the msg.
+ * mgmt_msg_native_get_msg_len() - Get the total length of the msg.
+ * mgmt_msg_native_send_msg() - Send the message.
+ *
+ *
+ * -------------------------------------
+ * [Advanced Use] Dynamic Array Messages
+ * -------------------------------------
+ *
+ * NOTE: Most users can simply use mgmt_msg_native_append() and skip this
+ * section.
+ *
+ * This section is only important to understand if you wish to utilize the fact
+ * that native messages allocated with mgmt_msg_native_alloc_msg are
+ * actually allocated as uint8_t dynamic arrays (`darr`).
+ *
+ * You can utilize all the darr_xxxx() API to manipulate the variable length
+ * message data in a native message. To do so you simply need to understand that
+ * the native message is actually a `uint8_t *` darr. So, for example, to append
+ * data to the end of a message one could do the following:
+ *
+ *     void append_metric_path(struct mgmt_msg_my_msg *msg)
+ *     {
+ *          msg = (struct mggm_msg_my_msg *)
+ *              darr_strcat((uint8_t *)msg, "/metric");
+ *
+ *         // ...
+ *     }
+ *
+ * NOTE: If reallocs happen the original passed in pointer will be updated;
+ * however, any other pointers into the message will become invalid, and so they
+ * should always be discarded or reinitialized after using any reallocating
+ * darr_xxx() API functions.
+ *
+ *     void append_metric_path(struct mgmt_msg_my_msg *msg)
+ *     {
+ *          char *xpath = msg->xpath;  // pointer into message
+ *
+ *          darr_in_strcat((uint8_t *)msg, "/metric");
+ *          // msg may have been updated to point at new memory
+ *
+ *          xpath = NULL;              // now invalid
+ *          xpath = msg->xpath;         // reinitialize
+ *         // ...
+ *     }
+ *
+ * Rather than worry about this, it's typical when using dynamic arrays to always
+ * work from the main pointer to the dynamic array, rather than caching multiple
+ * pointers into the data. Modern compilers will optimize the code so that it
+ * adds no extra execution cost.
+ *
+ *     void append_metric_path(struct mgmt_msg_my_msg *msg)
+ *     {
+ *          darr_in_strcat((uint8_t *)msg, "/metric");
+ *
+ *          // Use `msg->xpath` directly rather creating and using an
+ *          // `xpath = msg->xpath` local variable.
+ *
+ *          if (strcmp(msg->xpath, "foobar/metric")) {
+ *             // ...
+ *          }
+ *     }
+ *
+ */
+
 DECLARE_MTYPE(MSG_NATIVE_MSG);
 DECLARE_MTYPE(MSG_NATIVE_ERROR);
+DECLARE_MTYPE(MSG_NATIVE_GET_TREE);
+DECLARE_MTYPE(MSG_NATIVE_TREE_DATA);
 
 /*
  * Native message codes
@@ -33,29 +150,41 @@ DECLARE_MTYPE(MSG_NATIVE_ERROR);
 #define MGMT_MSG_CODE_GET_TREE 1
 #define MGMT_MSG_CODE_TREE_DATA 2
 
-/*
- * A note on alignments: The zero length arrays fields are aligned such that
- * this is so:
- *
- *    sizeof(struct mgmt_msg_foo) == offsetof(struct mgmt_msg_foo, field)
+/**
+ * struct mgmt_msg_header - Header common to all native messages.
  *
- * This allows things like `ptr = darr_append_n(A, sizeof(*ptr))`
- * to work
+ * @code: the actual type of the message.
+ * @resv: Set to zero, ignore on receive.
+ * @vsplit: If a variable section is split in 2, the length of first part.
+ * @refer_id: the session, txn, conn, etc, this message is associated with.
+ * @req_id: the request this message is for.
  */
-
-
 struct mgmt_msg_header {
-       union {
-               uint64_t session_id;
-               uint64_t txn_id;
-       };
-       uint64_t req_id;
        uint16_t code;
+       uint16_t resv;
+       uint32_t vsplit;
+       uint64_t refer_id;
+       uint64_t req_id;
 };
+_Static_assert(sizeof(struct mgmt_msg_header) == 3 * 8, "Bad padding");
+_Static_assert(sizeof(struct mgmt_msg_header) ==
+                      offsetof(struct mgmt_msg_header, req_id) +
+                              sizeof(((struct mgmt_msg_header *)0)->req_id),
+              "Size mismatch");
 
+/**
+ * struct mgmt_msg_error - Common error message.
+ *
+ * @error: An error value.
+ * @errst: Description of error can be 0 length.
+ *
+ * This common error message can be used for replies for many msg requests
+ * (req_id).
+ */
 struct mgmt_msg_error {
        struct mgmt_msg_header;
        int16_t error;
+       uint8_t resv2[6];
 
        alignas(8) char errstr[];
 };
@@ -63,9 +192,16 @@ _Static_assert(sizeof(struct mgmt_msg_error) ==
                       offsetof(struct mgmt_msg_error, errstr),
               "Size mismatch");
 
+/**
+ * struct mgmt_msg_get_tree - Message carrying xpath query request.
+ *
+ * @result_type: ``LYD_FORMAT`` for the returned result.
+ * @xpath: the query for the data to return.
+ */
 struct mgmt_msg_get_tree {
        struct mgmt_msg_header;
        uint8_t result_type;
+       uint8_t resv2[7];
 
        alignas(8) char xpath[];
 };
@@ -73,11 +209,21 @@ _Static_assert(sizeof(struct mgmt_msg_get_tree) ==
                       offsetof(struct mgmt_msg_get_tree, xpath),
               "Size mismatch");
 
+/**
+ * struct mgmt_msg_tree_data - Message carrying tree data.
+ *
+ * @partial_error: If the full result could not be returned do to this error.
+ * @result_type: ``LYD_FORMAT`` for format of the @result value.
+ * @more: if this is a partial return and there will be more coming.
+ * @result: The tree data in @result_type format.
+ *
+ */
 struct mgmt_msg_tree_data {
        struct mgmt_msg_header;
        int8_t partial_error;
        uint8_t result_type;
        uint8_t more;
+       uint8_t resv2[5];
 
        alignas(8) uint8_t result[];
 };
@@ -115,6 +261,118 @@ extern int vmgmt_msg_native_send_error(struct msg_conn *conn,
                                       const char *errfmt, va_list ap)
        PRINTFRR(6, 0);
 
+/**
+ * mgmt_msg_native_alloc_msg() - Create a native appendable msg.
+ * @msg_type: The message structure type.
+ * @var_len: The initial additional length to add to the message.
+ * @mem_type: The initial additional length to add to the message.
+ *
+ * This function takes a C type (e.g., `struct mgmt_msg_get_tree`) as an
+ * argument and returns a new native message. The newly allocated message
+ * can be used with the other `native` functions.
+ *
+ * Importantly the mgmt_msg_native_append() function can be used to add data
+ * to the end of the message, and mgmt_msg_get_native_msg_len() can be used
+ * to obtain the total length of the message (i.e., the fixed sized header plus
+ * the variable length data that has been appended).
+ *
+ * Additionally, a dynamic array (darr) pointer can be obtained using
+ * mgmt_msg_get_native_darr() which allows adding and manipulating the
+ * variable data that follows the fixed sized header.
+ *
+ * Return: A `msg_type` object created using a dynamic_array.
+ */
+#define mgmt_msg_native_alloc_msg(msg_type, var_len, mem_type)                 \
+       ({                                                                     \
+               uint8_t *buf = NULL;                                           \
+               (msg_type *)darr_append_nz_mt(buf,                             \
+                                             sizeof(msg_type) + (var_len),    \
+                                             mem_type);                       \
+       })
+
+/**
+ * mgmt_msg_free_native_msg() - Free a native msg.
+ * @msg - pointer to message allocated by mgmt_msg_create_native_msg().
+ */
+#define mgmt_msg_native_free_msg(msg) darr_free(msg)
+
+/**
+ * mgmt_msg_native_get_msg_len() - Get the total length of the msg.
+ * @msg: the native message.
+ *
+ * Return: the total length of the message, fixed + variable length.
+ */
+#define mgmt_msg_native_get_msg_len(msg) (darr_len((uint8_t *)(msg)))
+
+/**
+ * mgmt_msg_native_append() - Append data to the end of the msg.
+ * @msg: (IN/OUT) Pointer to the native message, variable may be updated.
+ * @data: data to append.
+ * @len: length of data to append.
+ *
+ * Append @data of length @len to the native message @msg.
+ *
+ * NOTE: Be aware @msg pointer may change as a result of reallocating the
+ * message to fit the new data. Any other pointers into the old message should
+ * be discarded.
+ *
+ * Return: a pointer to the newly appended data.
+ */
+#define mgmt_msg_native_append(msg, data, len)                                 \
+       memcpy(darr_append(*mgmt_msg_native_get_darrp(msg), len), data, len)
+
+/**
+ * mgmt_msg_native_send_msg(msg, short_circuit_ok) - Send a native msg.
+ * @conn: the mgmt_msg connection.
+ * @msg: the native message.
+ * @short_circuit_ok: True if short-circuit sending is required.
+ *
+ * Return: The error return value of msg_conn_send_msg().
+ */
+#define mgmt_msg_native_send_msg(conn, msg, short_circuit_ok)                  \
+       msg_conn_send_msg(conn, MGMT_MSG_VERSION_NATIVE, msg,                  \
+                         mgmt_msg_native_get_msg_len(msg), NULL,              \
+                         short_circuit_ok)
+
+/**
+ * mgmt_msg_native_get_darrp() - Return a ptr to the dynamic array ptr.
+ * @msg: Pointer to the native message.
+ *
+ * NOTE: Most users can simply use mgmt_msg_native_append() instead of this.
+ *
+ * This function obtains a pointer to the dynamic byte array for this message,
+ * this array actually includes the message header if one is going to look at
+ * the length value. With that in mind any of the `darr_*()` functions/API may
+ * be used to manipulate the variable data at the end of the message.
+ *
+ * NOTE: The pointer returned is actually a pointer to the message pointer
+ * passed in to this function. This pointer to pointer is required so that
+ * realloc can be done inside the darr API.
+ *
+ * NOTE: If reallocs happen the original passed in pointer will be updated;
+ * however, any other pointers into the message will become invalid and so they
+ * should always be discarded after using the returned value.
+ *
+ * Example:
+ *
+ *     void append_metric_path(struct mgmt_msg_my_msg *msg)
+ *     {
+ *          char *xpath = msg->xpath;  // pointer into message
+ *          uint8_t **darp;
+ *
+ *          darrp = mgmt_msg_native_get_darrp(msg);
+ *          darr_in_strcat(*darrp, "/metric");
+ *
+ *          xpath = NULL;              // now invalid
+ *          xpath = msg->xpath;
+ *     }
+ *
+ *
+ * Return: A pointer to the first argument -- which is a pointer to a pointer to
+ * a dynamic array.
+ */
+#define mgmt_msg_native_get_darrp(msg) ((uint8_t **)&(msg))
+
 #ifdef __cplusplus
 }
 #endif
index 8444502bdee55387353322f18b55de67f3a25712..72dff4b062d9d900d3acacc515eabd97ef26c49a 100644 (file)
@@ -287,14 +287,6 @@ mgmt_be_adapter_cleanup_old_conn(struct mgmt_be_client_adapter *adapter)
        }
 }
 
-static int be_adapter_send_native_msg(struct mgmt_be_client_adapter *adapter,
-                                     void *msg, size_t len,
-                                     bool short_circuit_ok)
-{
-       return msg_conn_send_msg(adapter->conn, MGMT_MSG_VERSION_NATIVE, msg,
-                                len, NULL, short_circuit_ok);
-}
-
 static int mgmt_be_adapter_send_msg(struct mgmt_be_client_adapter *adapter,
                                    Mgmtd__BeMessage *be_msg)
 {
@@ -504,14 +496,14 @@ int mgmt_be_send_cfgapply_req(struct mgmt_be_client_adapter *adapter,
        return mgmt_be_adapter_send_msg(adapter, &be_msg);
 }
 
-int mgmt_be_send_native(enum mgmt_be_client_id id, void *msg, size_t len)
+int mgmt_be_send_native(enum mgmt_be_client_id id, void *msg)
 {
        struct mgmt_be_client_adapter *adapter = mgmt_be_get_adapter_by_id(id);
 
        if (!adapter)
                return -1;
 
-       return be_adapter_send_native_msg(adapter, msg, len, false);
+       return mgmt_msg_native_send_msg(adapter->conn, msg, false);
 }
 
 /*
@@ -530,10 +522,10 @@ static void be_adapter_handle_native_msg(struct mgmt_be_client_adapter *adapter,
        case MGMT_MSG_CODE_ERROR:
                error_msg = (typeof(error_msg))msg;
                MGMTD_BE_ADAPTER_DBG("Got ERROR from '%s' txn-id %" PRIx64,
-                                    adapter->name, msg->txn_id);
+                                    adapter->name, msg->refer_id);
 
                /* Forward the reply to the txn module */
-               mgmt_txn_notify_error(adapter, msg->txn_id, msg->req_id,
+               mgmt_txn_notify_error(adapter, msg->refer_id, msg->req_id,
                                      error_msg->error, error_msg->errstr);
 
                break;
@@ -541,7 +533,7 @@ static void be_adapter_handle_native_msg(struct mgmt_be_client_adapter *adapter,
                /* tree data from a backend client */
                tree_msg = (typeof(tree_msg))msg;
                MGMTD_BE_ADAPTER_DBG("Got TREE_DATA from '%s' txn-id %" PRIx64,
-                                    adapter->name, msg->txn_id);
+                                    adapter->name, msg->refer_id);
 
                /* Forward the reply to the txn module */
                mgmt_txn_notify_tree_data_reply(adapter, tree_msg, msg_len);
@@ -550,7 +542,7 @@ static void be_adapter_handle_native_msg(struct mgmt_be_client_adapter *adapter,
                MGMTD_BE_ADAPTER_ERR("unknown native message txn-id %" PRIu64
                                     " req-id %" PRIu64
                                     " code %u from BE client for adapter %s",
-                                    msg->txn_id, msg->req_id, msg->code,
+                                    msg->refer_id, msg->req_id, msg->code,
                                     adapter->name);
                break;
        }
index b8abd016e6a28cf53d81932780a7820a386d7054..2afac949f5a884ed93132dd365c0a608c1b782b5 100644 (file)
@@ -220,12 +220,12 @@ extern void mgmt_be_xpath_register_write(struct vty *vty);
  *
  * Args:
  *     adapter: the client to send the message to.
- *     msg: the message data.
- *     len: the length of the message data.
+ *     msg: a native message from mgmt_msg_native_alloc_msg()
+ *
  * Return:
- *     Any return value from msg_conn_send_msg.
+ *     Any return value from msg_conn_send_msg().
  */
-extern int mgmt_be_send_native(enum mgmt_be_client_id id, void *data, size_t len);
+extern int mgmt_be_send_native(enum mgmt_be_client_id id, void *msg);
 
 /**
  * Lookup the clients which are subscribed to a given `xpath`
index dc965498779729c26e3e290a62a8e5e9ed27c36f..87c67491b6f413939c61e561f2af58ed59135e80 100644 (file)
@@ -1089,7 +1089,7 @@ static int fe_adapter_send_tree_data(struct mgmt_fe_session_ctx *session,
 
        darr_append_n(buf, offsetof(typeof(*msg), result));
        msg = (typeof(msg))buf;
-       msg->session_id = session->session_id;
+       msg->refer_id = session->session_id;
        msg->req_id = req_id;
        msg->code = MGMT_MSG_CODE_TREE_DATA;
        msg->partial_error = partial_error;
@@ -1200,10 +1200,10 @@ static void fe_adapter_handle_native_msg(struct mgmt_fe_client_adapter *adapter,
 {
        struct mgmt_fe_session_ctx *session;
 
-       session = mgmt_session_id2ctx(msg->session_id);
+       session = mgmt_session_id2ctx(msg->refer_id);
        if (!session) {
                MGMTD_FE_ADAPTER_ERR("adapter %s: recv msg unknown session-id %" PRIu64,
-                                    adapter->name, msg->session_id);
+                                    adapter->name, msg->refer_id);
                return;
        }
        assert(session->adapter == adapter);
@@ -1216,7 +1216,7 @@ static void fe_adapter_handle_native_msg(struct mgmt_fe_client_adapter *adapter,
                MGMTD_FE_ADAPTER_ERR("unknown native message session-id %" PRIu64
                                     " req-id %" PRIu64
                                     " code %u to FE adapter %s",
-                                    msg->session_id, msg->req_id, msg->code,
+                                    msg->refer_id, msg->req_id, msg->code,
                                     adapter->name);
                break;
        }
index b94fd3bad47b29b93c62570673e1a8c0013132b9..7e625c73ec0e127e0c7157cde7df94fe1df71405 100644 (file)
@@ -2367,7 +2367,7 @@ int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id,
        struct mgmt_txn_req *txn_req;
        struct txn_req_get_tree *get_tree;
        enum mgmt_be_client_id id;
-       size_t mlen = sizeof(*msg) + strlen(xpath) + 1;
+       ssize_t slen = strlen(xpath);
        int ret;
 
        txn = mgmt_txn_id2ctx(txn_id);
@@ -2380,17 +2380,18 @@ int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id,
        get_tree->result_type = result_type;
        get_tree->xpath = XSTRDUP(MTYPE_MGMTD_XPATH, xpath);
 
-       msg = XCALLOC(MTYPE_MSG_NATIVE_MSG, mlen);
-       msg->txn_id = txn_id;
+       msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_get_tree, slen + 1,
+                                       MTYPE_MSG_NATIVE_GET_TREE);
+       msg->refer_id = txn_id;
        msg->req_id = req_id;
        msg->code = MGMT_MSG_CODE_GET_TREE;
        /* Always operate with the binary format in the backend */
        msg->result_type = LYD_LYB;
-       strlcpy(msg->xpath, xpath, mlen - sizeof(*msg));
+       strlcpy(msg->xpath, xpath, slen + 1);
 
        assert(clients);
        FOREACH_BE_CLIENT_BITS (id, clients) {
-               ret = mgmt_be_send_native(id, msg, mlen);
+               ret = mgmt_be_send_native(id, msg);
                if (ret) {
                        MGMTD_TXN_ERR("Could not send get-tree message to backend client %s",
                                      mgmt_be_client_id2name(id));
@@ -2404,7 +2405,7 @@ int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id,
                get_tree->sent_clients |= (1u << id);
        }
 
-       XFREE(MTYPE_MSG_NATIVE_MSG, msg);
+       mgmt_msg_native_free_msg(msg);
 
        /* Start timeout timer - pulled out of register event code so we can
         * pass a different arg
@@ -2479,7 +2480,7 @@ int mgmt_txn_notify_tree_data_reply(struct mgmt_be_client_adapter *adapter,
                                    struct mgmt_msg_tree_data *data_msg,
                                    size_t msg_len)
 {
-       uint64_t txn_id = data_msg->txn_id;
+       uint64_t txn_id = data_msg->refer_id;
        uint64_t req_id = data_msg->req_id;
 
        enum mgmt_be_client_id id = adapter->id;