diff options
| -rw-r--r-- | lib/mgmt_msg_native.h | 11 | ||||
| -rw-r--r-- | lib/northbound.c | 28 | ||||
| -rw-r--r-- | lib/northbound.h | 9 | ||||
| -rw-r--r-- | mgmtd/mgmt_fe_adapter.c | 24 | ||||
| -rw-r--r-- | mgmtd/mgmt_fe_adapter.h | 8 | ||||
| -rw-r--r-- | mgmtd/mgmt_txn.c | 10 | 
6 files changed, 63 insertions, 27 deletions
diff --git a/lib/mgmt_msg_native.h b/lib/mgmt_msg_native.h index 76a52658cd..ef03b66edc 100644 --- a/lib/mgmt_msg_native.h +++ b/lib/mgmt_msg_native.h @@ -383,11 +383,18 @@ _Static_assert(sizeof(struct mgmt_msg_edit) ==  /**   * 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_header; -	uint8_t resv2[8]; +	uint8_t changed; +	uint8_t created; +	uint8_t resv2[6];  	alignas(8) char data[];  }; diff --git a/lib/northbound.c b/lib/northbound.c index 35d0596ed4..2dae21341e 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -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,  				      enum nb_operation operation,  				      LYD_FORMAT format, const char *xpath, -				      const char *data, char *xpath_created, -				      char *errmsg, size_t errmsg_len) +				      const char *data, bool *created, +				      char *xpath_created, char *errmsg, +				      size_t errmsg_len)  {  	struct lyd_node *tree = 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 */ -	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);  		/* 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))  			existing = NULL; @@ -930,7 +939,7 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate,  				 LYD_MERGE_DESTRUCT | LYD_MERGE_WITH_FLAGS);  	if (err) {  		/* if replace failed, restore the original node */ -		if (existing) { +		if (existing && operation == NB_OP_REPLACE) {  			if (root) {  				/* Restoring the whole config. */  				candidate->dnode = existing; @@ -954,6 +963,8 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate,  		ret = NB_ERR;  		goto done;  	} else { +		if (!existing) +			*created = true;  		/*  		 * Free existing node after replace.  		 * 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  		 * was unlinked from the tree.  		 */ -		if (existing) +		if (existing && operation == NB_OP_REPLACE)  			lyd_free_siblings(existing);  		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,  			   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)  {  	int ret = NB_ERR; @@ -1022,8 +1033,9 @@ int nb_candidate_edit_tree(struct nb_config *candidate,  	case NB_OP_MODIFY:  	case NB_OP_REPLACE:  		ret = nb_candidate_edit_tree_add(candidate, operation, format, -						 xpath, data, xpath_created, -						 errmsg, errmsg_len); +						 xpath, data, created, +						 xpath_created, errmsg, +						 errmsg_len);  		break;  	case NB_OP_DESTROY:  	case NB_OP_DELETE: diff --git a/lib/northbound.h b/lib/northbound.h index b311affa31..b2cccb6716 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -1016,6 +1016,9 @@ extern int nb_candidate_edit(struct nb_config *candidate,   * data   *    New data tree for the node.   * + * created + *    OUT param set accordingly if a node was created or just updated + *   * xpath_created   *    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.   */  extern int nb_candidate_edit_tree(struct nb_config *candidate, -				  enum nb_operation operation, -				  LYD_FORMAT format, const char *xpath, -				  const char *data, char *xpath_created, +				  enum nb_operation operation, LYD_FORMAT format, +				  const char *xpath, const char *data, +				  bool *created, char *xpath_created,  				  char *errmsg, size_t errmsg_len);  /* diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index 8ab66de687..8d305ed52f 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -1164,7 +1164,9 @@ done:  }  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;  	int ret; @@ -1173,14 +1175,19 @@ static int fe_adapter_send_edit_reply(struct mgmt_fe_session_ctx *session,  					MTYPE_MSG_NATIVE_EDIT_REPLY);  	msg->refer_id = session->session_id;  	msg->req_id = req_id; +	msg->changed = changed; +	msg->created = created;  	msg->code = MGMT_MSG_CODE_EDIT_REPLY;  	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 -	      " req-id %" PRIu64 " len %u", -	      session->adapter->name, session->session_id, req_id, -	      mgmt_msg_native_get_msg_len(msg)); +	      " req-id %" PRIu64 " changed %u created %u len %u", +	      session->adapter->name, session->session_id, req_id, changed, +	      created, mgmt_msg_native_get_msg_len(msg));  	ret = fe_adapter_send_native_msg(session->adapter, 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,  				    uint64_t req_id, bool unlock, bool commit, -				    const char *xpath, int16_t error, -				    const char *errstr) +				    bool created, const char *xpath, +				    int16_t error, const char *errstr)  {  	struct mgmt_fe_session_ctx *session;  	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",  					    errstr);  	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)  		mgmt_destroy_txn(&session->cfg_txn_id); diff --git a/mgmtd/mgmt_fe_adapter.h b/mgmtd/mgmt_fe_adapter.h index 5a7dec3e6f..4d94e7604f 100644 --- a/mgmtd/mgmt_fe_adapter.h +++ b/mgmtd/mgmt_fe_adapter.h @@ -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   *     unlock: implicit-lock 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   *     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,  					   uint64_t req_id, bool unlock, -					   bool commit, const char *xpath, -					   int16_t error, const char *errstr); +					   bool commit, bool created, +					   const char *xpath, int16_t error, +					   const char *errstr);  /**   * Send an error back to the FE client using native messaging. diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index 53d9f5c3fa..ccfdd7539f 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -94,6 +94,7 @@ DECLARE_LIST(mgmt_txn_batches, struct mgmt_txn_be_cfg_batch, list_linkage);  struct mgmt_edit_req {  	char xpath_created[XPATH_MAXLEN]; +	bool created;  	bool unlock;  }; @@ -742,6 +743,8 @@ static int mgmt_txn_send_commit_cfg_reply(struct mgmt_txn_ctx *txn,  						    .edit->unlock,  					    true,  					    txn->commit_cfg_req->req.commit_cfg +						    .edit->created, +					    txn->commit_cfg_req->req.commit_cfg  						    .edit->xpath_created,  					    success ? 0 : -1,  					    error_if_any) != 0) { @@ -2566,8 +2569,8 @@ int mgmt_txn_send_edit(uint64_t txn_id, uint64_t req_id,  	assert(nb_config);  	ret = nb_candidate_edit_tree(nb_config, operation, request_type, xpath, -				     data, edit->xpath_created, errstr, -				     sizeof(errstr)); +				     data, &edit->created, edit->xpath_created, +				     errstr, sizeof(errstr));  	if (ret)  		goto reply; @@ -2581,7 +2584,8 @@ int mgmt_txn_send_edit(uint64_t txn_id, uint64_t req_id,  	}  reply:  	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);  	XFREE(MTYPE_MGMTD_TXN_REQ, edit);  | 
