forked from Mirror/frr
lib: mgmtd: add changed
and created
to edit-reply msg
- This is used for various return values in RESTCONF Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
parent
96db155acd
commit
b097a966cb
|
@ -383,11 +383,18 @@ _Static_assert(sizeof(struct mgmt_msg_edit) ==
|
||||||
/**
|
/**
|
||||||
* struct mgmt_msg_edit_reply - frontend edit reply.
|
* struct mgmt_msg_edit_reply - frontend edit reply.
|
||||||
*
|
*
|
||||||
* @data: the xpath of the data node that was created.
|
* @changed: If true then changes in datastore resulted.
|
||||||
|
* @created: If true then object was newly created (non-existing before)
|
||||||
|
* @data: @vsplit values, second value may be zero len.
|
||||||
|
* @data: [0] the xpath of the data node that was created.
|
||||||
|
* @data: [1] Possible structured data to pass back to client (e.g., non-"error"
|
||||||
|
* yang modeled error data).
|
||||||
*/
|
*/
|
||||||
struct mgmt_msg_edit_reply {
|
struct mgmt_msg_edit_reply {
|
||||||
struct mgmt_msg_header;
|
struct mgmt_msg_header;
|
||||||
uint8_t resv2[8];
|
uint8_t changed;
|
||||||
|
uint8_t created;
|
||||||
|
uint8_t resv2[6];
|
||||||
|
|
||||||
alignas(8) char data[];
|
alignas(8) char data[];
|
||||||
};
|
};
|
||||||
|
|
|
@ -816,8 +816,9 @@ int nb_candidate_edit(struct nb_config *candidate, const struct nb_node *nb_node
|
||||||
static int nb_candidate_edit_tree_add(struct nb_config *candidate,
|
static int nb_candidate_edit_tree_add(struct nb_config *candidate,
|
||||||
enum nb_operation operation,
|
enum nb_operation operation,
|
||||||
LYD_FORMAT format, const char *xpath,
|
LYD_FORMAT format, const char *xpath,
|
||||||
const char *data, char *xpath_created,
|
const char *data, bool *created,
|
||||||
char *errmsg, size_t errmsg_len)
|
char *xpath_created, char *errmsg,
|
||||||
|
size_t errmsg_len)
|
||||||
{
|
{
|
||||||
struct lyd_node *tree = NULL;
|
struct lyd_node *tree = NULL;
|
||||||
struct lyd_node *parent = NULL;
|
struct lyd_node *parent = NULL;
|
||||||
|
@ -897,10 +898,18 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the node already exists in candidate */
|
/* check if the node already exists in candidate */
|
||||||
if (operation == NB_OP_CREATE_EXCL || operation == NB_OP_REPLACE) {
|
if (operation == NB_OP_CREATE || operation == NB_OP_MODIFY)
|
||||||
|
existing = yang_dnode_get(candidate->dnode, xpath_created);
|
||||||
|
else if (operation == NB_OP_CREATE_EXCL || operation == NB_OP_REPLACE) {
|
||||||
existing = yang_dnode_get(candidate->dnode, xpath_created);
|
existing = yang_dnode_get(candidate->dnode, xpath_created);
|
||||||
|
|
||||||
/* if the existing node is implicit default, ignore */
|
/* if the existing node is implicit default, ignore */
|
||||||
|
/* Q: Is this correct for CREATE_EXCL which is supposed to error
|
||||||
|
* if the resouurce already exists? This is used by RESTCONF
|
||||||
|
* when processing the POST command, for example. RFC8040
|
||||||
|
* doesn't say POST fails if resource exists "unless it was a
|
||||||
|
* default".
|
||||||
|
*/
|
||||||
if (existing && (existing->flags & LYD_DEFAULT))
|
if (existing && (existing->flags & LYD_DEFAULT))
|
||||||
existing = NULL;
|
existing = NULL;
|
||||||
|
|
||||||
|
@ -930,7 +939,7 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate,
|
||||||
LYD_MERGE_DESTRUCT | LYD_MERGE_WITH_FLAGS);
|
LYD_MERGE_DESTRUCT | LYD_MERGE_WITH_FLAGS);
|
||||||
if (err) {
|
if (err) {
|
||||||
/* if replace failed, restore the original node */
|
/* if replace failed, restore the original node */
|
||||||
if (existing) {
|
if (existing && operation == NB_OP_REPLACE) {
|
||||||
if (root) {
|
if (root) {
|
||||||
/* Restoring the whole config. */
|
/* Restoring the whole config. */
|
||||||
candidate->dnode = existing;
|
candidate->dnode = existing;
|
||||||
|
@ -954,6 +963,8 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate,
|
||||||
ret = NB_ERR;
|
ret = NB_ERR;
|
||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
|
if (!existing)
|
||||||
|
*created = true;
|
||||||
/*
|
/*
|
||||||
* Free existing node after replace.
|
* Free existing node after replace.
|
||||||
* We're using `lyd_free_siblings` here to free the whole
|
* We're using `lyd_free_siblings` here to free the whole
|
||||||
|
@ -961,7 +972,7 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate,
|
||||||
* siblings if it wasn't root, because the existing node
|
* siblings if it wasn't root, because the existing node
|
||||||
* was unlinked from the tree.
|
* was unlinked from the tree.
|
||||||
*/
|
*/
|
||||||
if (existing)
|
if (existing && operation == NB_OP_REPLACE)
|
||||||
lyd_free_siblings(existing);
|
lyd_free_siblings(existing);
|
||||||
|
|
||||||
tree = NULL; /* LYD_MERGE_DESTRUCT deleted the tree */
|
tree = NULL; /* LYD_MERGE_DESTRUCT deleted the tree */
|
||||||
|
@ -1011,7 +1022,7 @@ static int nb_candidate_edit_tree_del(struct nb_config *candidate,
|
||||||
|
|
||||||
int nb_candidate_edit_tree(struct nb_config *candidate,
|
int nb_candidate_edit_tree(struct nb_config *candidate,
|
||||||
enum nb_operation operation, LYD_FORMAT format,
|
enum nb_operation operation, LYD_FORMAT format,
|
||||||
const char *xpath, const char *data,
|
const char *xpath, const char *data, bool *created,
|
||||||
char *xpath_created, char *errmsg, size_t errmsg_len)
|
char *xpath_created, char *errmsg, size_t errmsg_len)
|
||||||
{
|
{
|
||||||
int ret = NB_ERR;
|
int ret = NB_ERR;
|
||||||
|
@ -1022,8 +1033,9 @@ int nb_candidate_edit_tree(struct nb_config *candidate,
|
||||||
case NB_OP_MODIFY:
|
case NB_OP_MODIFY:
|
||||||
case NB_OP_REPLACE:
|
case NB_OP_REPLACE:
|
||||||
ret = nb_candidate_edit_tree_add(candidate, operation, format,
|
ret = nb_candidate_edit_tree_add(candidate, operation, format,
|
||||||
xpath, data, xpath_created,
|
xpath, data, created,
|
||||||
errmsg, errmsg_len);
|
xpath_created, errmsg,
|
||||||
|
errmsg_len);
|
||||||
break;
|
break;
|
||||||
case NB_OP_DESTROY:
|
case NB_OP_DESTROY:
|
||||||
case NB_OP_DELETE:
|
case NB_OP_DELETE:
|
||||||
|
|
|
@ -1016,6 +1016,9 @@ extern int nb_candidate_edit(struct nb_config *candidate,
|
||||||
* data
|
* data
|
||||||
* New data tree for the node.
|
* New data tree for the node.
|
||||||
*
|
*
|
||||||
|
* created
|
||||||
|
* OUT param set accordingly if a node was created or just updated
|
||||||
|
*
|
||||||
* xpath_created
|
* xpath_created
|
||||||
* XPath of the created node if operation is "create".
|
* XPath of the created node if operation is "create".
|
||||||
*
|
*
|
||||||
|
@ -1030,9 +1033,9 @@ extern int nb_candidate_edit(struct nb_config *candidate,
|
||||||
* - NB_ERR for other errors.
|
* - NB_ERR for other errors.
|
||||||
*/
|
*/
|
||||||
extern int nb_candidate_edit_tree(struct nb_config *candidate,
|
extern int nb_candidate_edit_tree(struct nb_config *candidate,
|
||||||
enum nb_operation operation,
|
enum nb_operation operation, LYD_FORMAT format,
|
||||||
LYD_FORMAT format, const char *xpath,
|
const char *xpath, const char *data,
|
||||||
const char *data, char *xpath_created,
|
bool *created, char *xpath_created,
|
||||||
char *errmsg, size_t errmsg_len);
|
char *errmsg, size_t errmsg_len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1164,7 +1164,9 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fe_adapter_send_edit_reply(struct mgmt_fe_session_ctx *session,
|
static int fe_adapter_send_edit_reply(struct mgmt_fe_session_ctx *session,
|
||||||
uint64_t req_id, const char *xpath)
|
uint64_t req_id, bool changed,
|
||||||
|
bool created, const char *xpath,
|
||||||
|
const char *data)
|
||||||
{
|
{
|
||||||
struct mgmt_msg_edit_reply *msg;
|
struct mgmt_msg_edit_reply *msg;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1173,14 +1175,19 @@ static int fe_adapter_send_edit_reply(struct mgmt_fe_session_ctx *session,
|
||||||
MTYPE_MSG_NATIVE_EDIT_REPLY);
|
MTYPE_MSG_NATIVE_EDIT_REPLY);
|
||||||
msg->refer_id = session->session_id;
|
msg->refer_id = session->session_id;
|
||||||
msg->req_id = req_id;
|
msg->req_id = req_id;
|
||||||
|
msg->changed = changed;
|
||||||
|
msg->created = created;
|
||||||
msg->code = MGMT_MSG_CODE_EDIT_REPLY;
|
msg->code = MGMT_MSG_CODE_EDIT_REPLY;
|
||||||
|
|
||||||
mgmt_msg_native_xpath_encode(msg, xpath);
|
mgmt_msg_native_xpath_encode(msg, xpath);
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
mgmt_msg_native_append(msg, data, strlen(data) + 1);
|
||||||
|
|
||||||
__dbg("Sending edit-reply from adapter %s to session-id %" PRIu64
|
__dbg("Sending edit-reply from adapter %s to session-id %" PRIu64
|
||||||
" req-id %" PRIu64 " len %u",
|
" req-id %" PRIu64 " changed %u created %u len %u",
|
||||||
session->adapter->name, session->session_id, req_id,
|
session->adapter->name, session->session_id, req_id, changed,
|
||||||
mgmt_msg_native_get_msg_len(msg));
|
created, mgmt_msg_native_get_msg_len(msg));
|
||||||
|
|
||||||
ret = fe_adapter_send_native_msg(session->adapter, msg,
|
ret = fe_adapter_send_native_msg(session->adapter, msg,
|
||||||
mgmt_msg_native_get_msg_len(msg),
|
mgmt_msg_native_get_msg_len(msg),
|
||||||
|
@ -1977,8 +1984,8 @@ int mgmt_fe_adapter_send_rpc_reply(uint64_t session_id, uint64_t txn_id,
|
||||||
|
|
||||||
int mgmt_fe_adapter_send_edit_reply(uint64_t session_id, uint64_t txn_id,
|
int mgmt_fe_adapter_send_edit_reply(uint64_t session_id, uint64_t txn_id,
|
||||||
uint64_t req_id, bool unlock, bool commit,
|
uint64_t req_id, bool unlock, bool commit,
|
||||||
const char *xpath, int16_t error,
|
bool created, const char *xpath,
|
||||||
const char *errstr)
|
int16_t error, const char *errstr)
|
||||||
{
|
{
|
||||||
struct mgmt_fe_session_ctx *session;
|
struct mgmt_fe_session_ctx *session;
|
||||||
Mgmtd__DatastoreId ds_id, rds_id;
|
Mgmtd__DatastoreId ds_id, rds_id;
|
||||||
|
@ -2009,11 +2016,12 @@ int mgmt_fe_adapter_send_edit_reply(uint64_t session_id, uint64_t txn_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error)
|
if (error != 0 && error != -EALREADY)
|
||||||
ret = fe_adapter_send_error(session, req_id, false, error, "%s",
|
ret = fe_adapter_send_error(session, req_id, false, error, "%s",
|
||||||
errstr);
|
errstr);
|
||||||
else
|
else
|
||||||
ret = fe_adapter_send_edit_reply(session, req_id, xpath);
|
ret = fe_adapter_send_edit_reply(session, req_id, created,
|
||||||
|
!error, xpath, errstr);
|
||||||
|
|
||||||
if (session->cfg_txn_id != MGMTD_TXN_ID_NONE && !commit)
|
if (session->cfg_txn_id != MGMTD_TXN_ID_NONE && !commit)
|
||||||
mgmt_destroy_txn(&session->cfg_txn_id);
|
mgmt_destroy_txn(&session->cfg_txn_id);
|
||||||
|
|
|
@ -193,14 +193,16 @@ extern int mgmt_fe_adapter_send_rpc_reply(uint64_t session_id, uint64_t txn_id,
|
||||||
* req_id: the req id for the edit message
|
* req_id: the req id for the edit message
|
||||||
* unlock: implicit-lock flag was set in the request
|
* unlock: implicit-lock flag was set in the request
|
||||||
* commit: implicit-commit flag was set in the request
|
* commit: implicit-commit flag was set in the request
|
||||||
* xpath: the xpath of the data node that was created
|
* created: true if the node was just created
|
||||||
|
* xpath: the xpath of the data node that was created/updated
|
||||||
* error: >0 LY_ERR, < 0 -errno
|
* error: >0 LY_ERR, < 0 -errno
|
||||||
* errstr: the error string, if error is non-zero
|
* errstr: the error string, if error is non-zero
|
||||||
*/
|
*/
|
||||||
extern int mgmt_fe_adapter_send_edit_reply(uint64_t session_id, uint64_t txn_id,
|
extern int mgmt_fe_adapter_send_edit_reply(uint64_t session_id, uint64_t txn_id,
|
||||||
uint64_t req_id, bool unlock,
|
uint64_t req_id, bool unlock,
|
||||||
bool commit, const char *xpath,
|
bool commit, bool created,
|
||||||
int16_t error, const char *errstr);
|
const char *xpath, int16_t error,
|
||||||
|
const char *errstr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an error back to the FE client using native messaging.
|
* Send an error back to the FE client using native messaging.
|
||||||
|
|
|
@ -94,6 +94,7 @@ DECLARE_LIST(mgmt_txn_batches, struct mgmt_txn_be_cfg_batch, list_linkage);
|
||||||
|
|
||||||
struct mgmt_edit_req {
|
struct mgmt_edit_req {
|
||||||
char xpath_created[XPATH_MAXLEN];
|
char xpath_created[XPATH_MAXLEN];
|
||||||
|
bool created;
|
||||||
bool unlock;
|
bool unlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -741,6 +742,8 @@ static int mgmt_txn_send_commit_cfg_reply(struct mgmt_txn_ctx *txn,
|
||||||
txn->commit_cfg_req->req.commit_cfg
|
txn->commit_cfg_req->req.commit_cfg
|
||||||
.edit->unlock,
|
.edit->unlock,
|
||||||
true,
|
true,
|
||||||
|
txn->commit_cfg_req->req.commit_cfg
|
||||||
|
.edit->created,
|
||||||
txn->commit_cfg_req->req.commit_cfg
|
txn->commit_cfg_req->req.commit_cfg
|
||||||
.edit->xpath_created,
|
.edit->xpath_created,
|
||||||
success ? 0 : -1,
|
success ? 0 : -1,
|
||||||
|
@ -2566,8 +2569,8 @@ int mgmt_txn_send_edit(uint64_t txn_id, uint64_t req_id,
|
||||||
assert(nb_config);
|
assert(nb_config);
|
||||||
|
|
||||||
ret = nb_candidate_edit_tree(nb_config, operation, request_type, xpath,
|
ret = nb_candidate_edit_tree(nb_config, operation, request_type, xpath,
|
||||||
data, edit->xpath_created, errstr,
|
data, &edit->created, edit->xpath_created,
|
||||||
sizeof(errstr));
|
errstr, sizeof(errstr));
|
||||||
if (ret)
|
if (ret)
|
||||||
goto reply;
|
goto reply;
|
||||||
|
|
||||||
|
@ -2581,7 +2584,8 @@ int mgmt_txn_send_edit(uint64_t txn_id, uint64_t req_id,
|
||||||
}
|
}
|
||||||
reply:
|
reply:
|
||||||
mgmt_fe_adapter_send_edit_reply(txn->session_id, txn->txn_id, req_id,
|
mgmt_fe_adapter_send_edit_reply(txn->session_id, txn->txn_id, req_id,
|
||||||
unlock, commit, edit->xpath_created,
|
unlock, commit, edit->created,
|
||||||
|
edit->xpath_created,
|
||||||
errno_from_nb_error(ret), errstr);
|
errno_from_nb_error(ret), errstr);
|
||||||
|
|
||||||
XFREE(MTYPE_MGMTD_TXN_REQ, edit);
|
XFREE(MTYPE_MGMTD_TXN_REQ, edit);
|
||||||
|
|
Loading…
Reference in a new issue