summaryrefslogtreecommitdiffstats
path: root/mgmtd/mgmt_fe_adapter.c
diff options
context:
space:
mode:
authorChristian Hopps <chopps@labn.net>2024-06-11 11:08:49 +0200
committerChristian Hopps <chopps@labn.net>2024-06-11 16:37:31 +0200
commit3dad09b228e3c4a4ffa6da260fadda6762a77c58 (patch)
tree75c36cc0a1b7f8b5c5e65e005758543454ad37ee /mgmtd/mgmt_fe_adapter.c
parenttests: switch test to new fe_client notify selector syntax (diff)
downloadfrr-3dad09b228e3c4a4ffa6da260fadda6762a77c58.tar.xz
frr-3dad09b228e3c4a4ffa6da260fadda6762a77c58.zip
mgmtd: add native session-req (create/delete) messages
This addition allows for a limited native-message-only front-end interaction. Signed-off-by: Christian Hopps <chopps@labn.net>
Diffstat (limited to 'mgmtd/mgmt_fe_adapter.c')
-rw-r--r--mgmtd/mgmt_fe_adapter.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c
index a076dc72f..5f53c928a 100644
--- a/mgmtd/mgmt_fe_adapter.c
+++ b/mgmtd/mgmt_fe_adapter.c
@@ -490,6 +490,26 @@ static int fe_adapter_send_get_reply(struct mgmt_fe_session_ctx *session,
return fe_adapter_send_msg(session->adapter, &fe_msg, false);
}
+static int fe_adapter_conn_send_error(struct msg_conn *conn,
+ uint64_t session_id, uint64_t req_id,
+ bool short_circuit_ok, int16_t error,
+ const char *errfmt, ...) PRINTFRR(6, 7);
+static int fe_adapter_conn_send_error(struct msg_conn *conn, uint64_t session_id,
+ uint64_t req_id, bool short_circuit_ok,
+ int16_t error, const char *errfmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, errfmt);
+
+ ret = vmgmt_msg_native_send_error(conn, session_id, req_id,
+ short_circuit_ok, error, errfmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
static int fe_adapter_send_error(struct mgmt_fe_session_ctx *session,
uint64_t req_id, bool short_circuit_ok,
int16_t error, const char *errfmt, ...)
@@ -1170,6 +1190,88 @@ static int fe_adapter_send_edit_reply(struct mgmt_fe_session_ctx *session,
return ret;
}
+static int
+fe_adapter_native_send_session_reply(struct mgmt_fe_client_adapter *adapter,
+ uint64_t req_id, uint64_t session_id,
+ bool created)
+{
+ struct mgmt_msg_session_reply *msg;
+ int ret;
+
+ msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_session_reply, 0,
+ MTYPE_MSG_NATIVE_SESSION_REPLY);
+ msg->refer_id = session_id;
+ msg->req_id = req_id;
+ msg->code = MGMT_MSG_CODE_SESSION_REPLY;
+ msg->created = created;
+
+ __dbg("Sending session-reply from adapter %s to session-id %" PRIu64
+ " req-id %" PRIu64 " len %u",
+ adapter->name, session_id, req_id,
+ mgmt_msg_native_get_msg_len(msg));
+
+ ret = fe_adapter_send_native_msg(adapter, msg,
+ mgmt_msg_native_get_msg_len(msg),
+ false);
+ mgmt_msg_native_free_msg(msg);
+
+ return ret;
+}
+
+/**
+ * fe_adapter_handle_session_req() - Handle a session-req message from a FE client.
+ * @msg_raw: the message data.
+ * @msg_len: the length of the message data.
+ */
+static void fe_adapter_handle_session_req(struct mgmt_fe_client_adapter *adapter,
+ void *__msg, size_t msg_len)
+{
+ struct mgmt_msg_session_req *msg = __msg;
+ struct mgmt_fe_session_ctx *session;
+ uint64_t client_id;
+
+ __dbg("Got session-req creating: %u for refer-id %" PRIu64 " from '%s'",
+ msg->refer_id == 0, msg->refer_id, adapter->name);
+
+ if (msg->refer_id) {
+ uint64_t session_id = msg->refer_id;
+
+ session = mgmt_session_id2ctx(session_id);
+ if (!session) {
+ fe_adapter_conn_send_error(
+ adapter->conn, session_id, msg->req_id, false,
+ -EINVAL,
+ "No session to delete for session-id: %" PRIu64,
+ session_id);
+ return;
+ }
+ fe_adapter_native_send_session_reply(adapter, msg->req_id,
+ session_id, false);
+ mgmt_fe_cleanup_session(&session);
+ return;
+ }
+
+ client_id = msg->req_id;
+
+ /* See if we have a client name to register */
+ if (msg_len > sizeof(*msg)) {
+ if (!MGMT_MSG_VALIDATE_NUL_TERM(msg, msg_len)) {
+ fe_adapter_conn_send_error(
+ adapter->conn, client_id, msg->req_id, false,
+ -EINVAL,
+ "Corrupt session-req message rcvd from client-id: %" PRIu64,
+ client_id);
+ return;
+ }
+ __dbg("Set client-name to '%s'", msg->client_name);
+ strlcpy(adapter->name, msg->client_name, sizeof(adapter->name));
+ }
+
+ session = mgmt_fe_create_session(adapter, client_id);
+ fe_adapter_native_send_session_reply(adapter, client_id,
+ session->session_id, true);
+}
+
/**
* fe_adapter_handle_get_data() - Handle a get-tree message from a FE client.
* @session: the client session.
@@ -1529,6 +1631,28 @@ static void fe_adapter_handle_native_msg(struct mgmt_fe_client_adapter *adapter,
size_t msg_len)
{
struct mgmt_fe_session_ctx *session;
+ size_t min_size = mgmt_msg_get_min_size(msg->code);
+
+ if (msg_len < min_size) {
+ if (!min_size)
+ __log_err("adapter %s: recv msg refer-id %" PRIu64
+ " unknown message type %u",
+ adapter->name, msg->refer_id, msg->code);
+ else
+ __log_err("adapter %s: recv msg refer-id %" PRIu64
+ " short (%zu<%zu) msg for type %u",
+ adapter->name, msg->refer_id, msg_len,
+ min_size, msg->code);
+ return;
+ }
+
+ if (msg->code == MGMT_MSG_CODE_SESSION_REQ) {
+ __dbg("adapter %s: session-id %" PRIu64
+ " received SESSION_REQ message",
+ adapter->name, msg->refer_id);
+ fe_adapter_handle_session_req(adapter, msg, msg_len);
+ return;
+ }
session = mgmt_session_id2ctx(msg->refer_id);
if (!session) {