Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mgmtd: add support for native 'edit' operation #15468

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions lib/mgmt_fe_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,36 @@ int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client,
return ret;
}

int mgmt_fe_send_edit_req(struct mgmt_fe_client *client, uint64_t session_id,
uint64_t req_id, uint8_t datastore,
LYD_FORMAT request_type, uint8_t flags,
uint8_t operation, const char *xpath, const char *data)
{
struct mgmt_msg_edit *msg;
int ret;

msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_edit, 0,
MTYPE_MSG_NATIVE_EDIT);
msg->refer_id = session_id;
msg->req_id = req_id;
msg->code = MGMT_MSG_CODE_EDIT;
msg->request_type = request_type;
msg->flags = flags;
msg->datastore = datastore;
msg->operation = operation;

mgmt_msg_native_xpath_encode(msg, xpath);
if (data)
mgmt_msg_native_append(msg, data, strlen(data) + 1);

debug_fe_client("Sending EDIT_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)
Expand Down Expand Up @@ -503,7 +533,9 @@ static void fe_client_handle_native_msg(struct mgmt_fe_client *client,
struct mgmt_fe_client_session *session = NULL;
struct mgmt_msg_notify_data *notify_msg;
struct mgmt_msg_tree_data *tree_msg;
struct mgmt_msg_edit_reply *edit_msg;
struct mgmt_msg_error *err_msg;
const char *xpath = NULL;
const char *data = NULL;
size_t dlen;

Expand Down Expand Up @@ -554,6 +586,28 @@ static void fe_client_handle_native_msg(struct mgmt_fe_client *client,
msg_len - sizeof(*tree_msg),
tree_msg->partial_error);
break;
case MGMT_MSG_CODE_EDIT_REPLY:
if (!session->client->cbs.edit_notify)
return;

edit_msg = (typeof(edit_msg))msg;
if (msg_len < sizeof(*edit_msg)) {
log_err_fe_client("Corrupt edit-reply msg recv");
return;
}

xpath = mgmt_msg_native_xpath_decode(edit_msg, msg_len);
if (!xpath) {
log_err_fe_client("Corrupt edit-reply msg recv");
return;
}

session->client->cbs.edit_notify(client, client->user_data,
session->client_id,
msg->refer_id,
session->user_ctx, msg->req_id,
xpath);
break;
case MGMT_MSG_CODE_NOTIFY:
if (!session->client->cbs.async_notification)
return;
Expand Down
45 changes: 45 additions & 0 deletions lib/mgmt_fe_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ struct mgmt_fe_client_cbs {
LYD_FORMAT result_type, void *result, size_t len,
int partial_error);

/* Called when edit result is returned */
int (*edit_notify)(struct mgmt_fe_client *client, uintptr_t user_data,
uint64_t client_id, uint64_t session_id,
uintptr_t session_ctx, uint64_t req_id,
const char *xpath);

/* Called with asynchronous notifications from backends */
int (*async_notification)(struct mgmt_fe_client *client,
uintptr_t user_data, uint64_t client_id,
Expand Down Expand Up @@ -409,6 +415,45 @@ extern int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client,
uint8_t flags, uint8_t defaults,
const char *xpath);

/*
* Send EDIT to MGMTD daemon.
*
* client
* Client object.
*
* session_id
* Client session ID.
*
* req_id
* Client request ID.
*
* datastore
* Datastore for editing.
*
* request_type
* The LYD_FORMAT of the request.
*
* flags
* Flags to control the behavior of the request.
*
* operation
* NB_OP_* operation to perform.
*
* xpath
* the xpath to edit.
*
* data
* the data tree.
*
* Returns:
* 0 on success, otherwise msg_conn_send_msg() return values.
*/
extern int mgmt_fe_send_edit_req(struct mgmt_fe_client *client,
uint64_t session_id, uint64_t req_id,
uint8_t datastore, LYD_FORMAT request_type,
uint8_t flags, uint8_t operation,
const char *xpath, const char *data);

/*
* Destroy library and cleanup everything.
*/
Expand Down
2 changes: 2 additions & 0 deletions lib/mgmt_msg_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_GET_TREE, "native get tree msg");
DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_TREE_DATA, "native tree data msg");
DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_GET_DATA, "native get data msg");
DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_NOTIFY, "native get data msg");
DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_EDIT, "native edit msg");
DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_EDIT_REPLY, "native edit reply 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,
Expand Down
63 changes: 61 additions & 2 deletions lib/mgmt_msg_native.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extern "C" {
#include "memory.h"
#include "mgmt_msg.h"
#include "mgmt_defines.h"
#include "northbound.h"

#include <stdalign.h>

Expand Down Expand Up @@ -149,6 +150,8 @@ DECLARE_MTYPE(MSG_NATIVE_GET_TREE);
DECLARE_MTYPE(MSG_NATIVE_TREE_DATA);
DECLARE_MTYPE(MSG_NATIVE_GET_DATA);
DECLARE_MTYPE(MSG_NATIVE_NOTIFY);
DECLARE_MTYPE(MSG_NATIVE_EDIT);
DECLARE_MTYPE(MSG_NATIVE_EDIT_REPLY);

/*
* Native message codes
Expand All @@ -158,6 +161,8 @@ DECLARE_MTYPE(MSG_NATIVE_NOTIFY);
#define MGMT_MSG_CODE_TREE_DATA 2
#define MGMT_MSG_CODE_GET_DATA 3
#define MGMT_MSG_CODE_NOTIFY 4
#define MGMT_MSG_CODE_EDIT 5
#define MGMT_MSG_CODE_EDIT_REPLY 6

/*
* Datastores
Expand Down Expand Up @@ -318,6 +323,60 @@ _Static_assert(sizeof(struct mgmt_msg_notify_data) ==
offsetof(struct mgmt_msg_notify_data, data),
"Size mismatch");

#define EDIT_FLAG_IMPLICIT_LOCK 0x01
#define EDIT_FLAG_IMPLICIT_COMMIT 0x02

#define EDIT_OP_CREATE 0
#define EDIT_OP_DELETE 4
#define EDIT_OP_MERGE 2
#define EDIT_OP_REPLACE 5
#define EDIT_OP_REMOVE 3

_Static_assert(EDIT_OP_CREATE == NB_OP_CREATE_EXCL, "Operation mismatch");
_Static_assert(EDIT_OP_DELETE == NB_OP_DELETE, "Operation mismatch");
_Static_assert(EDIT_OP_MERGE == NB_OP_MODIFY, "Operation mismatch");
_Static_assert(EDIT_OP_REPLACE == NB_OP_REPLACE, "Operation mismatch");
_Static_assert(EDIT_OP_REMOVE == NB_OP_DESTROY, "Operation mismatch");

/**
* struct mgmt_msg_edit - frontend edit request.
*
* @request_type: ``LYD_FORMAT`` for the @data.
* @flags: combination of ``EDIT_FLAG_*`` flags.
* @datastore: the datastore to edit.
* @operation: one of ``EDIT_OP_*`` operations.
* @data: the xpath followed by the tree data for the operation.
* for CREATE, xpath points to the parent node.
*/
struct mgmt_msg_edit {
struct mgmt_msg_header;
uint8_t request_type;
uint8_t flags;
uint8_t datastore;
uint8_t operation;
uint8_t resv2[4];

alignas(8) char data[];
};
_Static_assert(sizeof(struct mgmt_msg_edit) ==
offsetof(struct mgmt_msg_edit, data),
"Size mismatch");

/**
* struct mgmt_msg_edit_reply - frontend edit reply.
*
* @data: the xpath of the data node that was created.
*/
struct mgmt_msg_edit_reply {
struct mgmt_msg_header;
uint8_t resv2[8];

alignas(8) char data[];
};
_Static_assert(sizeof(struct mgmt_msg_edit_reply) ==
offsetof(struct mgmt_msg_edit_reply, data),
"Size mismatch");

/*
* Validate that the message ends in a NUL terminating byte
*/
Expand Down Expand Up @@ -504,13 +563,13 @@ extern int vmgmt_msg_native_send_error(struct msg_conn *conn,
* The xpath string or NULL if there was an error decoding (i.e., the
* message is corrupt).
*/
#define mgmt_msg_native_xpath_data_decode(msg, msglen, data) \
#define mgmt_msg_native_xpath_data_decode(msg, msglen, __data) \
({ \
size_t __len = (msglen) - sizeof(*msg); \
const char *__s = NULL; \
if (msg->vsplit && msg->vsplit <= __len && \
msg->data[msg->vsplit - 1] == 0) { \
(data) = msg->data + msg->vsplit; \
(__data) = msg->data + msg->vsplit; \
__s = msg->data; \
} \
__s; \
Expand Down
Loading
Loading