Skip to content

Commit

Permalink
Merge pull request #15246 from idryzhov/mgmt-get-data-improvements
Browse files Browse the repository at this point in the history
mgmt get-data improvements
  • Loading branch information
choppsv1 authored Jan 31, 2024
2 parents 642078d + 3afea9c commit 25d3086
Show file tree
Hide file tree
Showing 24 changed files with 1,776 additions and 43 deletions.
9 changes: 6 additions & 3 deletions lib/mgmt_fe_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,10 @@ int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client,
/*
* Send get-data request.
*/
int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client, uint64_t session_id,
uint64_t req_id, LYD_FORMAT result_type,
uint8_t flags, const char *xpath)
int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client,
uint64_t session_id, uint64_t req_id,
uint8_t datastore, LYD_FORMAT result_type,
uint8_t flags, uint8_t defaults, const char *xpath)
{
struct mgmt_msg_get_data *msg;
size_t xplen = strlen(xpath);
Expand All @@ -323,6 +324,8 @@ int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client, uint64_t session_id
msg->code = MGMT_MSG_CODE_GET_DATA;
msg->result_type = result_type;
msg->flags = flags;
msg->defaults = defaults;
msg->datastore = datastore;
strlcpy(msg->xpath, xpath, xplen + 1);

MGMTD_FE_CLIENT_DBG("Sending GET_DATA_REQ session-id %" PRIu64
Expand Down
9 changes: 8 additions & 1 deletion lib/mgmt_fe_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,12 +384,18 @@ extern int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client,
* req_id
* Client request ID.
*
* datastore
* Datastore for getting data.
*
* result_type
* The LYD_FORMAT of the result.
*
* flags
* Flags to control the behavior of the request.
*
* defaults
* Options to control the reporting of default values.
*
* xpath
* the xpath to get.
*
Expand All @@ -398,7 +404,8 @@ extern int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client,
*/
extern int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client,
uint64_t session_id, uint64_t req_id,
LYD_FORMAT result_type, uint8_t flags,
uint8_t datastore, LYD_FORMAT result_type,
uint8_t flags, uint8_t defaults,
const char *xpath);

/*
Expand Down
42 changes: 39 additions & 3 deletions lib/mgmt_msg_native.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,30 @@ DECLARE_MTYPE(MSG_NATIVE_NOTIFY);
#define MGMT_MSG_CODE_GET_DATA 3
#define MGMT_MSG_CODE_NOTIFY 4

/*
* Datastores
*/
#define MGMT_MSG_DATASTORE_STARTUP 0
#define MGMT_MSG_DATASTORE_CANDIDATE 1
#define MGMT_MSG_DATASTORE_RUNNING 2
#define MGMT_MSG_DATASTORE_OPERATIONAL 3

/*
* Formats
*/
#define MGMT_MSG_FORMAT_XML 1
#define MGMT_MSG_FORMAT_JSON 2
#define MGMT_MSG_FORMAT_BINARY 3 /* non-standard libyang internal format */

/*
* Now we're using LYD_FORMAT directly to avoid mapping code, but having our
* own definitions allows us to create such a mapping in the future if libyang
* makes a backwards incompatible change.
*/
_Static_assert(MGMT_MSG_FORMAT_XML == LYD_XML, "Format mismatch");
_Static_assert(MGMT_MSG_FORMAT_JSON == LYD_JSON, "Format mismatch");
_Static_assert(MGMT_MSG_FORMAT_BINARY == LYD_LYB, "Format mismatch");

/**
* struct mgmt_msg_header - Header common to all native messages.
*
Expand Down Expand Up @@ -236,22 +260,34 @@ _Static_assert(sizeof(struct mgmt_msg_tree_data) ==
"Size mismatch");

/* Flags for get-data request */
#define GET_DATA_FLAG_STATE 0x01 /* get only "config false" data */
#define GET_DATA_FLAG_CONFIG 0x02 /* get only "config true" data */
#define GET_DATA_FLAG_STATE 0x01 /* include "config false" data */
#define GET_DATA_FLAG_CONFIG 0x02 /* include "config true" data */
#define GET_DATA_FLAG_EXACT 0x04 /* get exact data node instead of the full tree */

/*
* Modes of reporting default values. Non-default values are always reported.
* These options reflect "with-defaults" modes as defined in RFC 6243.
*/
#define GET_DATA_DEFAULTS_EXPLICIT 0 /* "explicit" */
#define GET_DATA_DEFAULTS_TRIM 1 /* "trim" */
#define GET_DATA_DEFAULTS_ALL 2 /* "report-all" */
#define GET_DATA_DEFAULTS_ALL_ADD_TAG 3 /* "report-all-tagged" */

/**
* struct mgmt_msg_get_data - frontend get-data request.
*
* @result_type: ``LYD_FORMAT`` for the returned result.
* @flags: combination of ``GET_DATA_FLAG_*`` flags.
* @defaults: one of ``GET_DATA_DEFAULTS_*`` values.
* @xpath: the query for the data to return.
*/
struct mgmt_msg_get_data {
struct mgmt_msg_header;
uint8_t result_type;
uint8_t flags;
uint8_t resv2[6];
uint8_t defaults;
uint8_t datastore;
uint8_t resv2[4];

alignas(8) char xpath[];
};
Expand Down
9 changes: 5 additions & 4 deletions lib/vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -4101,16 +4101,17 @@ int vty_mgmt_send_get_req(struct vty *vty, bool is_config,
return 0;
}

int vty_mgmt_send_get_data_req(struct vty *vty, LYD_FORMAT result_type,
uint8_t flags, const char *xpath)
int vty_mgmt_send_get_data_req(struct vty *vty, uint8_t datastore,
LYD_FORMAT result_type, uint8_t flags,
uint8_t defaults, const char *xpath)
{
LYD_FORMAT intern_format = result_type;

vty->mgmt_req_id++;

if (mgmt_fe_send_get_data_req(mgmt_fe_client, vty->mgmt_session_id,
vty->mgmt_req_id, intern_format, flags,
xpath)) {
vty->mgmt_req_id, datastore,
intern_format, flags, defaults, xpath)) {
zlog_err("Failed to send GET-DATA to MGMTD session-id: %" PRIu64
" req-id %" PRIu64 ".",
vty->mgmt_session_id, vty->mgmt_req_id);
Expand Down
5 changes: 3 additions & 2 deletions lib/vty.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,8 +420,9 @@ extern int vty_mgmt_send_commit_config(struct vty *vty, bool validate_only,
extern int vty_mgmt_send_get_req(struct vty *vty, bool is_config,
Mgmtd__DatastoreId datastore,
const char **xpath_list, int num_req);
extern int vty_mgmt_send_get_data_req(struct vty *vty, LYD_FORMAT result_type,
uint8_t flags, const char *xpath);
extern int vty_mgmt_send_get_data_req(struct vty *vty, uint8_t datastore,
LYD_FORMAT result_type, uint8_t flags,
uint8_t defaults, const char *xpath);
extern int vty_mgmt_send_lockds_req(struct vty *vty, Mgmtd__DatastoreId ds_id,
bool lock, bool scok);
extern void vty_mgmt_resume_response(struct vty *vty, int ret);
Expand Down
62 changes: 47 additions & 15 deletions mgmtd/mgmt_fe_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1080,13 +1080,12 @@ mgmt_fe_adapter_handle_msg(struct mgmt_fe_client_adapter *adapter,
*/
static int fe_adapter_send_tree_data(struct mgmt_fe_session_ctx *session,
uint64_t req_id, bool short_circuit_ok,
uint8_t result_type,
uint8_t result_type, uint32_t wd_options,
const struct lyd_node *tree,
int partial_error)

{
struct mgmt_msg_tree_data *msg;
struct lyd_node *empty = NULL;
uint8_t **darrp = NULL;
int ret = 0;

Expand All @@ -1098,15 +1097,9 @@ static int fe_adapter_send_tree_data(struct mgmt_fe_session_ctx *session,
msg->partial_error = partial_error;
msg->result_type = result_type;

if (!tree) {
empty = yang_dnode_new(ly_native_ctx, false);
tree = empty;
}

darrp = mgmt_msg_native_get_darrp(msg);
ret = yang_print_tree_append(darrp, tree, result_type,
(LYD_PRINT_WD_EXPLICIT |
LYD_PRINT_WITHSIBLINGS));
(wd_options | LYD_PRINT_WITHSIBLINGS));
if (ret != LY_SUCCESS) {
MGMTD_FE_ADAPTER_ERR("Error building get-tree result for client %s session-id %" PRIu64
" req-id %" PRIu64
Expand All @@ -1126,8 +1119,6 @@ static int fe_adapter_send_tree_data(struct mgmt_fe_session_ctx *session,
mgmt_msg_native_get_msg_len(msg),
short_circuit_ok);
done:
if (empty)
yang_dnode_free(empty);
mgmt_msg_native_free_msg(msg);

return ret;
Expand All @@ -1146,7 +1137,9 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session,
struct lysc_node **snodes = NULL;
char *xpath_resolved = NULL;
uint64_t req_id = msg->req_id;
Mgmtd__DatastoreId ds_id;
uint64_t clients;
uint32_t wd_options;
bool simple_xpath;
LY_ERR err;
int ret;
Expand All @@ -1171,6 +1164,43 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session,
goto done;
}

switch (msg->defaults) {
case GET_DATA_DEFAULTS_EXPLICIT:
wd_options = LYD_PRINT_WD_EXPLICIT;
break;
case GET_DATA_DEFAULTS_TRIM:
wd_options = LYD_PRINT_WD_TRIM;
break;
case GET_DATA_DEFAULTS_ALL:
wd_options = LYD_PRINT_WD_ALL;
break;
case GET_DATA_DEFAULTS_ALL_ADD_TAG:
wd_options = LYD_PRINT_WD_IMPL_TAG;
break;
default:
fe_adapter_send_error(session, req_id, false, -EINVAL,
"Invalid defaults value %u for session-id: %" PRIu64,
msg->defaults, session->session_id);
goto done;
}

switch (msg->datastore) {
case MGMT_MSG_DATASTORE_CANDIDATE:
ds_id = MGMTD_DS_CANDIDATE;
break;
case MGMT_MSG_DATASTORE_RUNNING:
ds_id = MGMTD_DS_RUNNING;
break;
case MGMT_MSG_DATASTORE_OPERATIONAL:
ds_id = MGMTD_DS_OPERATIONAL;
break;
default:
fe_adapter_send_error(session, req_id, false, -EINVAL,
"Unsupported datastore %" PRIu8
" requested from session-id: %" PRIu64,
msg->datastore, session->session_id);
goto done;
}

err = yang_resolve_snode_xpath(ly_native_ctx, msg->xpath, &snodes,
&simple_xpath);
Expand All @@ -1190,7 +1220,7 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session,
session->session_id);

fe_adapter_send_tree_data(session, req_id, false,
msg->result_type, NULL, 0);
msg->result_type, wd_options, NULL, 0);
goto done;
}

Expand All @@ -1209,8 +1239,8 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session,

/* Create a GET-TREE request under the transaction */
ret = mgmt_txn_send_get_tree_oper(session->txn_id, req_id, clients,
msg->result_type, msg->flags,
simple_xpath, msg->xpath);
ds_id, msg->result_type, msg->flags,
wd_options, simple_xpath, msg->xpath);
if (ret) {
/* destroy the just created txn */
mgmt_destroy_txn(&session->txn_id);
Expand Down Expand Up @@ -1469,6 +1499,7 @@ int mgmt_fe_send_get_reply(uint64_t session_id, uint64_t txn_id,

int mgmt_fe_adapter_send_tree_data(uint64_t session_id, uint64_t txn_id,
uint64_t req_id, LYD_FORMAT result_type,
uint32_t wd_options,
const struct lyd_node *tree,
int partial_error, bool short_circuit_ok)
{
Expand All @@ -1480,7 +1511,8 @@ int mgmt_fe_adapter_send_tree_data(uint64_t session_id, uint64_t txn_id,
return -1;

ret = fe_adapter_send_tree_data(session, req_id, short_circuit_ok,
result_type, tree, partial_error);
result_type, wd_options, tree,
partial_error);

mgmt_destroy_txn(&session->txn_id);

Expand Down
12 changes: 6 additions & 6 deletions mgmtd/mgmt_fe_adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ extern int mgmt_fe_send_get_reply(uint64_t session_id, uint64_t txn_id,
* txn_id: the txn_id this data pertains to
* req_id: the req id for the get_tree message
* result_type: the format of the result data.
* wd_options: with-defaults options.
* tree: the results.
* partial_error: if there were errors while gather results.
* short_circuit_ok: True if OK to short-circuit the call.
Expand All @@ -156,12 +157,11 @@ extern int mgmt_fe_send_get_reply(uint64_t session_id, uint64_t txn_id,
* the return value from the underlying send function.
*
*/
extern int mgmt_fe_adapter_send_tree_data(uint64_t session_id, uint64_t txn_id,
uint64_t req_id,
LYD_FORMAT result_type,
const struct lyd_node *tree,
int partial_error,
bool short_circuit_ok);
extern int
mgmt_fe_adapter_send_tree_data(uint64_t session_id, uint64_t txn_id,
uint64_t req_id, LYD_FORMAT result_type,
uint32_t wd_options, const struct lyd_node *tree,
int partial_error, bool short_circuit_ok);

/**
* Send an error back to the FE client using native messaging.
Expand Down
13 changes: 13 additions & 0 deletions mgmtd/mgmt_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ static struct frr_signal_t mgmt_signals[] = {
extern const struct frr_yang_module_info frr_staticd_cli_info;
#endif

/*
* These are modules that are only needed by mgmtd and hence not included into
* the lib and backend daemons.
*/
const struct frr_yang_module_info ietf_netconf_with_defaults_info = {
.name = "ietf-netconf-with-defaults",
.ignore_cfg_cbs = true,
.nodes = { { .xpath = NULL } },
};

/*
* These are stub info structs that are used to load the modules used by backend
* clients into mgmtd. The modules are used by libyang in order to support
Expand All @@ -167,6 +177,9 @@ static const struct frr_yang_module_info *const mgmt_yang_modules[] = {
&frr_vrf_info,
&frr_affinity_map_cli_info,

/* mgmtd-only modules */
&ietf_netconf_with_defaults_info,

/*
* YANG module info used by backend clients get added here.
*/
Expand Down
Loading

0 comments on commit 25d3086

Please sign in to comment.