Skip to content

Commit

Permalink
mgmtd: add support for native 'edit' operation
Browse files Browse the repository at this point in the history
This operation basically implements support for RESTCONF operations. It
receives an xpath and a data tree in JSON/XML format, instead of a list
of (xpath, value) tuples as required by the current protobuf interface.

Signed-off-by: Igor Ryzhov <[email protected]>
  • Loading branch information
idryzhov committed Mar 26, 2024
1 parent 73e0b7a commit 1196d94
Show file tree
Hide file tree
Showing 16 changed files with 922 additions and 51 deletions.
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

0 comments on commit 1196d94

Please sign in to comment.