Skip to content

Commit

Permalink
mgmtd: add native session-req (create/delete) messages
Browse files Browse the repository at this point in the history
This addition allows for a limited native-message-only front-end
interaction.

Signed-off-by: Christian Hopps <[email protected]>
  • Loading branch information
choppsv1 committed Jun 11, 2024
1 parent 56ce198 commit 3dad09b
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 1 deletion.
27 changes: 27 additions & 0 deletions lib/mgmt_msg_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,33 @@ DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_EDIT, "native edit msg");
DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_EDIT_REPLY, "native edit reply msg");
DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_RPC, "native RPC msg");
DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_RPC_REPLY, "native RPC reply msg");
DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_SESSION_REQ, "native session-req msg");
DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_SESSION_REPLY, "native session-reply msg");


size_t mgmt_msg_min_sizes[] = {
[MGMT_MSG_CODE_ERROR] = sizeof(struct mgmt_msg_error),
[MGMT_MSG_CODE_GET_TREE] = sizeof(struct mgmt_msg_get_tree),
[MGMT_MSG_CODE_TREE_DATA] = sizeof(struct mgmt_msg_tree_data),
[MGMT_MSG_CODE_GET_DATA] = sizeof(struct mgmt_msg_get_data),
[MGMT_MSG_CODE_NOTIFY] = sizeof(struct mgmt_msg_notify_data),
[MGMT_MSG_CODE_EDIT] = sizeof(struct mgmt_msg_edit),
[MGMT_MSG_CODE_EDIT_REPLY] = sizeof(struct mgmt_msg_edit_reply),
[MGMT_MSG_CODE_RPC] = sizeof(struct mgmt_msg_rpc),
[MGMT_MSG_CODE_RPC_REPLY] = sizeof(struct mgmt_msg_rpc_reply),
[MGMT_MSG_CODE_NOTIFY_SELECT] = sizeof(struct mgmt_msg_notify_select),
[MGMT_MSG_CODE_SESSION_REQ] = sizeof(struct mgmt_msg_session_req),
[MGMT_MSG_CODE_SESSION_REPLY] = sizeof(struct mgmt_msg_session_reply),
};
size_t nmgmt_msg_min_sizes = sizeof(mgmt_msg_min_sizes) /
sizeof(*mgmt_msg_min_sizes);

size_t mgmt_msg_get_min_size(uint code)
{
if (code >= nmgmt_msg_min_sizes)
return 0;
return mgmt_msg_min_sizes[code];
}

int vmgmt_msg_native_send_error(struct msg_conn *conn, uint64_t sess_or_txn_id,
uint64_t req_id, bool short_circuit_ok,
Expand Down
45 changes: 44 additions & 1 deletion lib/mgmt_msg_native.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ DECLARE_MTYPE(MSG_NATIVE_EDIT);
DECLARE_MTYPE(MSG_NATIVE_EDIT_REPLY);
DECLARE_MTYPE(MSG_NATIVE_RPC);
DECLARE_MTYPE(MSG_NATIVE_RPC_REPLY);
DECLARE_MTYPE(MSG_NATIVE_SESSION_REQ);
DECLARE_MTYPE(MSG_NATIVE_SESSION_REPLY);

/*
* Native message codes
Expand All @@ -177,6 +179,8 @@ DECLARE_MTYPE(MSG_NATIVE_RPC_REPLY);
#define MGMT_MSG_CODE_RPC 7 /* Public API */
#define MGMT_MSG_CODE_RPC_REPLY 8 /* Public API */
#define MGMT_MSG_CODE_NOTIFY_SELECT 9 /* Public API */
#define MGMT_MSG_CODE_SESSION_REQ 10 /* Public API */
#define MGMT_MSG_CODE_SESSION_REPLY 11 /* Public API */

/*
* Datastores
Expand Down Expand Up @@ -434,7 +438,7 @@ _Static_assert(sizeof(struct mgmt_msg_rpc_reply) ==
* to the front-end client.
*
* @selectors: the xpath prefixes to selectors notifications through.
* @repalce: if true replace existing selectors with `selectors`.
* @replace: if true replace existing selectors with `selectors`.
*/
struct mgmt_msg_notify_select {
struct mgmt_msg_header;
Expand All @@ -448,12 +452,51 @@ _Static_assert(sizeof(struct mgmt_msg_notify_select) ==
offsetof(struct mgmt_msg_notify_select, selectors),
"Size mismatch");

/**
* struct mgmt_msg_session_req - Create or delete a front-end session.
*
* @refer_id: Zero for create, otherwise the session-id to delete.
* @req_id: For create will use as client-id.
* @client_name: For first session request the client name, otherwise empty.
*/
struct mgmt_msg_session_req {
struct mgmt_msg_header;
uint8_t resv2[8]; /* bug in compiler produces error w/o this */

alignas(8) char client_name[];
};

_Static_assert(sizeof(struct mgmt_msg_session_req) ==
offsetof(struct mgmt_msg_session_req, client_name),
"Size mismatch");

/**
* struct mgmt_msg_session_reply - Reply to session request message.
*
* @created: true if this is a reply to a create request, otherwise 0.
* @refer_id: The session-id for the action (create or delete) just taken.
*/
struct mgmt_msg_session_reply {
struct mgmt_msg_header;
uint8_t created;
uint8_t resv2[7];
};

/*
* Validate that the message ends in a NUL terminating byte
*/
#define MGMT_MSG_VALIDATE_NUL_TERM(msgp, len) \
((len) >= sizeof(*msgp) + 1 && ((char *)msgp)[(len)-1] == 0)

/**
* mgmt_msg_get_min_size() - Get minimum message size given the type
* @code: The type of the message (MGMT_MSG_CODE_*)
*
* Return:
* The minimum size of a message of the given type or 0 if the message
* code is unknown.
*/
size_t mgmt_msg_get_min_size(uint code);

/**
* Send a native message error to the other end of the connection.
Expand Down
124 changes: 124 additions & 0 deletions mgmtd/mgmt_fe_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, ...)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 3dad09b

Please sign in to comment.