Skip to content

Commit 5217b10

Browse files
authored
Merge pull request #20208 from LabNConsulting/chopps/rpc-restconf-format
Handle RESTCONF RPC/Action input format
2 parents b658361 + 50a4e60 commit 5217b10

File tree

13 files changed

+204
-42
lines changed

13 files changed

+204
-42
lines changed

lib/mgmt_be_client.c

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -837,16 +837,10 @@ static void be_client_handle_rpc(struct mgmt_be_client *client, uint64_t txn_id,
837837
return;
838838
}
839839

840-
if (data) {
841-
err = yang_parse_rpc(xpath, rpc_msg->request_type, data, false,
842-
&input);
843-
if (err) {
844-
be_client_send_error(client, txn_id, rpc_msg->req_id,
845-
false, -EINVAL,
846-
"Can't parse RPC data for: %s",
847-
xpath);
848-
return;
849-
}
840+
if (data && rpc_msg->restconf) {
841+
err = yang_parse_restconf_rpc(xpath, rpc_msg->request_type, data, false, &input);
842+
} else if (data) {
843+
err = yang_parse_rpc(xpath, rpc_msg->request_type, data, false, &input);
850844
} else {
851845
/*
852846
* If there's no input data, create an empty input container.
@@ -855,13 +849,11 @@ static void be_client_handle_rpc(struct mgmt_be_client *client, uint64_t txn_id,
855849
*/
856850
err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, 0, 0,
857851
NULL, &input);
858-
if (err) {
859-
be_client_send_error(client, txn_id, rpc_msg->req_id,
860-
false, -EINVAL,
861-
"Can't create input node for RPC: %s",
862-
xpath);
863-
return;
864-
}
852+
}
853+
if (err) {
854+
be_client_send_error(client, txn_id, rpc_msg->req_id, false, -EINVAL,
855+
"Can't parse RPC data for: %s", xpath);
856+
return;
865857
}
866858

867859
err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, 0, 0, NULL,

lib/mgmt_msg_native.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -448,30 +448,34 @@ _Static_assert(sizeof(struct mgmt_msg_edit_reply) ==
448448
* struct mgmt_msg_rpc - RPC/action request.
449449
*
450450
* @request_type: ``LYD_FORMAT`` for the @data.
451+
* @restconf: If true the and tree data is present it is in RESTCONF format
452+
* (i.e., the topmost node is `input`)
451453
* @data: the xpath followed by the tree data for the operation.
452454
*/
453455
struct mgmt_msg_rpc {
454456
struct mgmt_msg_header;
455457
uint8_t request_type;
456-
uint8_t resv2[7];
458+
uint8_t restconf;
459+
uint8_t resv2[6];
457460

458461
alignas(8) char data[];
459462
};
460463

461-
_Static_assert(sizeof(struct mgmt_msg_rpc) ==
462-
offsetof(struct mgmt_msg_rpc, data),
463-
"Size mismatch");
464+
_Static_assert(sizeof(struct mgmt_msg_rpc) == offsetof(struct mgmt_msg_rpc, data), "Size mismatch");
464465

465466
/**
466467
* struct mgmt_msg_rpc_reply - RPC/action reply.
467468
*
468469
* @result_type: ``LYD_FORMAT`` for the @data.
470+
* @restconf: If true the and tree data is present it is in RESTCONF format
471+
* (i.e., the topmost node is `output`)
469472
* @data: the tree data for the reply.
470473
*/
471474
struct mgmt_msg_rpc_reply {
472475
struct mgmt_msg_header;
473476
uint8_t result_type;
474-
uint8_t resv2[7];
477+
uint8_t restconf;
478+
uint8_t resv2[6];
475479

476480
alignas(8) char data[];
477481
};

lib/yang.c

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -979,8 +979,56 @@ LY_ERR yang_parse_notification(const char *xpath, LYD_FORMAT format,
979979
return LY_SUCCESS;
980980
}
981981

982-
LY_ERR yang_parse_rpc(const char *xpath, LYD_FORMAT format, const char *data,
983-
bool reply, struct lyd_node **rpc)
982+
LY_ERR yang_parse_restconf_rpc(const char *xpath, LYD_FORMAT format, const char *data, bool reply,
983+
struct lyd_node **rpc)
984+
{
985+
const struct lysc_node *snode;
986+
struct lyd_node *dnode = NULL;
987+
struct ly_in *in = NULL;
988+
LY_ERR err;
989+
990+
snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
991+
if (!snode) {
992+
zlog_err("Failed to find RPC/action schema node: %s", xpath);
993+
return LY_ENOTFOUND;
994+
}
995+
if (snode->nodetype != LYS_RPC && snode->nodetype != LYS_ACTION) {
996+
zlog_err("Node '%s' is not an RPC/action", xpath);
997+
return LY_ENOTFOUND;
998+
}
999+
/* Get the tree for the RPC/Action */
1000+
err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, 0, 0, NULL, &dnode);
1001+
if (err) {
1002+
zlog_err("Failed to create parent node for action: %s", ly_last_errmsg());
1003+
goto done;
1004+
}
1005+
1006+
if (!data)
1007+
goto done;
1008+
1009+
err = ly_in_new_memory(data, &in);
1010+
if (err) {
1011+
zlog_err("Failed to initialize ly_in: %s", ly_last_errmsg());
1012+
goto done;
1013+
}
1014+
1015+
err = lyd_parse_op(ly_native_ctx, dnode, in, format,
1016+
reply ? LYD_TYPE_REPLY_RESTCONF : LYD_TYPE_RPC_RESTCONF, NULL, NULL);
1017+
ly_in_free(in, 0);
1018+
if (err) {
1019+
zlog_err("Failed to parse RPC/action: %s", ly_last_errmsg());
1020+
goto done;
1021+
}
1022+
done:
1023+
if (err)
1024+
lyd_free_all(dnode);
1025+
else
1026+
*rpc = dnode;
1027+
return err;
1028+
}
1029+
1030+
LY_ERR yang_parse_rpc(const char *xpath, LYD_FORMAT format, const char *data, bool reply,
1031+
struct lyd_node **rpc)
9841032
{
9851033
const struct lysc_node *snode;
9861034
struct lyd_node *parent = NULL;

lib/yang.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,8 @@ extern LY_ERR yang_parse_notification(const char *xpath, LYD_FORMAT format,
736736
*/
737737
LY_ERR yang_parse_rpc(const char *xpath, LYD_FORMAT format, const char *data,
738738
bool reply, struct lyd_node **rpc);
739+
LY_ERR yang_parse_restconf_rpc(const char *xpath, LYD_FORMAT format, const char *data, bool reply,
740+
struct lyd_node **rpc);
739741

740742
/*
741743
* "Print" the yang tree in `root` into dynamic sized array.
@@ -748,8 +750,7 @@ LY_ERR yang_parse_rpc(const char *xpath, LYD_FORMAT format, const char *data,
748750
* Return:
749751
* A darr dynamic array with the "printed" output or NULL on failure.
750752
*/
751-
extern uint8_t *yang_print_tree(const struct lyd_node *root, LYD_FORMAT format,
752-
uint32_t options);
753+
extern uint8_t *yang_print_tree(const struct lyd_node *root, LYD_FORMAT format, uint32_t options);
753754

754755

755756
/**

mgmtd/mgmt_fe_adapter.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -842,10 +842,16 @@ static void fe_session_handle_get_data(struct mgmt_fe_session_ctx *session, void
842842
"Error getting yang-library data, session-id: %" PRIu64
843843
" error: %s",
844844
session->session_id, ly_last_errmsg());
845+
goto done;
845846
} else if (nb_oper_is_yang_lib_query(msg->xpath)) {
847+
struct lyd_node *result;
848+
846849
yang_lyd_trim_xpath(&ylib, msg->xpath);
850+
result = ylib;
851+
if (CHECK_FLAG(msg->flags, GET_DATA_FLAG_EXACT))
852+
result = yang_dnode_get(result, msg->xpath);
847853
(void)fe_session_send_tree_data(session, req_id, false, msg->result_type,
848-
wd_options, ylib, 0);
854+
wd_options, result, 0);
849855
goto done;
850856
}
851857
}
@@ -1241,7 +1247,8 @@ static void fe_session_handle_notify_select(struct mgmt_fe_session_ctx *session,
12411247
/* ----------- */
12421248

12431249
static int fe_session_send_rpc_reply(struct mgmt_fe_session_ctx *session, uint64_t req_id,
1244-
uint8_t result_type, const struct lyd_node *result)
1250+
uint8_t result_type, bool restconf,
1251+
const struct lyd_node *result)
12451252
{
12461253
struct mgmt_msg_rpc_reply *msg;
12471254
uint8_t **darrp = NULL;
@@ -1252,6 +1259,7 @@ static int fe_session_send_rpc_reply(struct mgmt_fe_session_ctx *session, uint64
12521259
msg->req_id = req_id;
12531260
msg->code = MGMT_MSG_CODE_RPC_REPLY;
12541261
msg->result_type = result_type;
1262+
msg->restconf = restconf;
12551263

12561264
if (result) {
12571265
darrp = mgmt_msg_native_get_darrp(msg);
@@ -1276,7 +1284,8 @@ static int fe_session_send_rpc_reply(struct mgmt_fe_session_ctx *session, uint64
12761284
}
12771285

12781286
void mgmt_fe_adapter_send_rpc_reply(uint64_t session_id, uint64_t txn_id, uint64_t req_id,
1279-
LYD_FORMAT result_type, const struct lyd_node *result)
1287+
LYD_FORMAT result_type, bool restconf,
1288+
const struct lyd_node *result)
12801289
{
12811290
struct mgmt_fe_session_ctx *session;
12821291

@@ -1287,7 +1296,7 @@ void mgmt_fe_adapter_send_rpc_reply(uint64_t session_id, uint64_t txn_id, uint64
12871296
/* XXXchopps why do we care about this? Why not allow multple? */
12881297
assert(session->txn_id == txn_id);
12891298

1290-
if (fe_session_send_rpc_reply(session, req_id, result_type, result))
1299+
if (fe_session_send_rpc_reply(session, req_id, result_type, restconf, result))
12911300
fe_session_send_error(session, req_id, false, -EIO, "Failed sending RPC reply");
12921301

12931302
mgmt_destroy_txn(&session->txn_id);
@@ -1354,8 +1363,8 @@ static void fe_session_handle_rpc(struct mgmt_fe_session_ctx *session, void *_ms
13541363
session->session_id);
13551364

13561365
/* Create an RPC request under the transaction */
1357-
mgmt_txn_send_rpc(session->txn_id, req_id, clients, msg->request_type, xpath, data,
1358-
mgmt_msg_native_data_len_decode(msg, msg_len));
1366+
mgmt_txn_send_rpc(session->txn_id, req_id, clients, msg->request_type, msg->restconf,
1367+
xpath, data, mgmt_msg_native_data_len_decode(msg, msg_len));
13591368
}
13601369

13611370
/* -------------------- */

mgmtd/mgmt_fe_adapter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,12 @@ extern void mgmt_fe_adapter_send_tree_data(uint64_t session_id, uint64_t txn_id,
8787
* txn_id: the txn_id this data pertains to
8888
* req_id: the req id for the rpc message
8989
* result_type: the format of the result data.
90+
* restconf: true if the RPC is formatted from RESTCONF operation.
9091
* result: the results.
9192
*/
9293
extern void mgmt_fe_adapter_send_rpc_reply(uint64_t session_id, uint64_t txn_id, uint64_t req_id,
93-
LYD_FORMAT result_type, const struct lyd_node *result);
94+
LYD_FORMAT result_type, bool restconf,
95+
const struct lyd_node *result);
9496

9597
/**
9698
* Send edit reply back to client. If error is not 0, a native error is sent.

mgmtd/mgmt_txn.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct txn_req_rpc {
4545
uint64_t clients; /* Bitmask of clients sent req to */
4646
uint64_t clients_wait; /* Bitmask of clients waiting for reply from */
4747
uint8_t result_type; /* LYD_FORMAT for results */
48+
uint8_t restconf; /* if restconf formatted data */
4849
struct lyd_node *client_results; /* result tree from clients */
4950
};
5051
#define as_rpc(txn_req) \
@@ -433,7 +434,8 @@ static void txn_rpc_done(struct txn_req_rpc *rpc)
433434
txn_req->err_info);
434435
else
435436
mgmt_fe_adapter_send_rpc_reply(txn->session_id, txn->txn_id, req_id,
436-
rpc->result_type, rpc->client_results);
437+
rpc->result_type, rpc->restconf,
438+
rpc->client_results);
437439

438440
/* we're done with the request */
439441
txn_req_free(txn_req);
@@ -521,7 +523,7 @@ void mgmt_txn_handle_rpc_reply(struct mgmt_be_client_adapter *adapter,
521523
}
522524

523525
void mgmt_txn_send_rpc(uint64_t txn_id, uint64_t req_id, uint64_t clients, LYD_FORMAT result_type,
524-
const char *xpath, const char *data, size_t data_len)
526+
bool restconf, const char *xpath, const char *data, size_t data_len)
525527
{
526528
struct mgmt_be_client_adapter *adapter;
527529
struct mgmt_txn *txn;
@@ -536,13 +538,15 @@ void mgmt_txn_send_rpc(uint64_t txn_id, uint64_t req_id, uint64_t clients, LYD_F
536538
rpc = txn_req_rpc_alloc(txn, req_id);
537539
rpc->xpath = XSTRDUP(MTYPE_MGMTD_XPATH, xpath);
538540
rpc->result_type = result_type;
541+
rpc->restconf = restconf;
539542

540543
msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_rpc, 0,
541544
MTYPE_MSG_NATIVE_RPC);
542545
msg->refer_id = txn_id;
543546
msg->req_id = req_id;
544547
msg->code = MGMT_MSG_CODE_RPC;
545548
msg->request_type = result_type;
549+
msg->restconf = restconf;
546550

547551
mgmt_msg_native_xpath_encode(msg, xpath);
548552
if (data)

mgmtd/mgmt_txn.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,14 @@ extern int mgmt_txn_send_get_tree(uint64_t txn_id, uint64_t req_id, uint64_t cli
145145
* @req_id: FE client request identifier.
146146
* @clients: Bitmask of clients to send RPC to.
147147
* @result_type: LYD_FORMAT result format.
148+
* @restconf: true if the RPC is formatted from RESTCONF operation.
148149
* @xpath: The xpath of the RPC.
149150
* @data: The input parameters data tree.
150151
* @data_len: The length of the input parameters data.
151152
*/
152153
extern void mgmt_txn_send_rpc(uint64_t txn_id, uint64_t req_id, uint64_t clients,
153-
LYD_FORMAT result_type, const char *xpath, const char *data,
154-
size_t data_len);
154+
LYD_FORMAT result_type, bool restconf, const char *xpath,
155+
const char *data, size_t data_len);
155156

156157
/**
157158
* mgmt_txn_send_notify_selectors() - Send NOTIFY SELECT request.

0 commit comments

Comments
 (0)