summaryrefslogtreecommitdiff
path: root/lib/mgmt_fe_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mgmt_fe_client.c')
-rw-r--r--lib/mgmt_fe_client.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/lib/mgmt_fe_client.c b/lib/mgmt_fe_client.c
index 4c6f86b194..c30a0339eb 100644
--- a/lib/mgmt_fe_client.c
+++ b/lib/mgmt_fe_client.c
@@ -12,6 +12,7 @@
#include "libfrr.h"
#include "mgmt_fe_client.h"
#include "mgmt_msg.h"
+#include "mgmt_msg_native.h"
#include "mgmt_pb.h"
#include "network.h"
#include "stream.h"
@@ -304,6 +305,35 @@ int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client,
return mgmt_fe_client_send_msg(client, &fe_msg, false);
}
+/*
+ * Send get-tree request.
+ */
+int mgmt_fe_send_get_tree_req(struct mgmt_fe_client *client,
+ uint64_t session_id, uint64_t req_id,
+ LYD_FORMAT result_type, const char *xpath)
+{
+ struct mgmt_msg_get_tree *msg;
+ size_t xplen = strlen(xpath);
+ int ret;
+
+ 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;
+ strlcpy(msg->xpath, xpath, xplen + 1);
+
+ MGMTD_FE_CLIENT_DBG("Sending GET_TREE_REQ session-id %" PRIu64
+ " req-id %" PRIu64 " xpath: %s",
+ session_id, req_id, xpath);
+
+ ret = mgmt_msg_native_send_msg(&client->client.conn, msg, false);
+ mgmt_msg_native_free_msg(msg);
+ return ret;
+}
+
+
static int mgmt_fe_client_handle_msg(struct mgmt_fe_client *client,
Mgmtd__FeMessage *fe_msg)
{
@@ -469,6 +499,73 @@ static int mgmt_fe_client_handle_msg(struct mgmt_fe_client *client,
return 0;
}
+/*
+ * Handle a native encoded message
+ */
+static void fe_client_handle_native_msg(struct mgmt_fe_client *client,
+ struct mgmt_msg_header *msg,
+ size_t msg_len)
+{
+ struct mgmt_fe_client_session *session;
+ struct mgmt_msg_tree_data *tree_msg;
+ struct mgmt_msg_error *err_msg;
+
+ MGMTD_FE_CLIENT_DBG("Got GET_TREE reply for session-id %" PRIu64,
+ msg->refer_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->refer_id);
+ return;
+ }
+
+ switch (msg->code) {
+ case MGMT_MSG_CODE_ERROR:
+ if (!session->client->cbs.error_notify)
+ return;
+
+ err_msg = (typeof(err_msg))msg;
+ if (!MGMT_MSG_VALIDATE_NUL_TERM(err_msg, msg_len)) {
+ MGMTD_FE_CLIENT_ERR("Corrupt error msg recv");
+ return;
+ }
+ session->client->cbs.error_notify(client, client->user_data,
+ session->client_id,
+ msg->refer_id,
+ session->user_ctx,
+ msg->req_id, err_msg->error,
+ err_msg->errstr);
+ break;
+ case MGMT_MSG_CODE_TREE_DATA:
+ if (!session->client->cbs.get_tree_notify)
+ return;
+
+ tree_msg = (typeof(tree_msg))msg;
+ if (msg_len < sizeof(*tree_msg)) {
+ MGMTD_FE_CLIENT_ERR("Corrupt tree-data msg recv");
+ return;
+ }
+ session->client->cbs.get_tree_notify(client, client->user_data,
+ session->client_id,
+ msg->refer_id,
+ session->user_ctx,
+ msg->req_id,
+ MGMTD_DS_OPERATIONAL,
+ tree_msg->result_type,
+ tree_msg->result,
+ msg_len - sizeof(*tree_msg),
+ tree_msg->partial_error);
+ break;
+ default:
+ MGMTD_FE_CLIENT_ERR("unknown native message session-id %" PRIu64
+ " req-id %" PRIu64 " code %u",
+ msg->refer_id, msg->req_id, msg->code);
+ break;
+ }
+}
+
static void mgmt_fe_client_process_msg(uint8_t version, uint8_t *data,
size_t len, struct msg_conn *conn)
{
@@ -479,6 +576,17 @@ static void mgmt_fe_client_process_msg(uint8_t version, uint8_t *data,
msg_client = container_of(conn, struct msg_client, conn);
client = container_of(msg_client, struct mgmt_fe_client, client);
+ if (version == MGMT_MSG_VERSION_NATIVE) {
+ struct mgmt_msg_header *msg = (typeof(msg))data;
+
+ if (len >= sizeof(*msg))
+ fe_client_handle_native_msg(client, msg, len);
+ else
+ MGMTD_FE_CLIENT_ERR("native message to FE client %s too short %zu",
+ client->name, len);
+ return;
+ }
+
fe_msg = mgmtd__fe_message__unpack(NULL, len, data);
if (!fe_msg) {
MGMTD_FE_CLIENT_DBG("Failed to decode %zu bytes from server.",
@@ -647,6 +755,11 @@ bool mgmt_fe_client_current_msg_short_circuit(struct mgmt_fe_client *client)
return client->client.conn.is_short_circuit;
}
+const char *mgmt_fe_client_name(struct mgmt_fe_client *client)
+{
+ return client->name;
+}
+
/*
* Create a new Session for a Frontend Client connection.
*/