mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 12:41:21 +00:00
mgmtd: add support for with-defaults parameter to get-data
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is contained in:
parent
e2caf64ef7
commit
4317c8ffa6
@ -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,
|
||||
LYD_FORMAT result_type, uint8_t flags,
|
||||
uint8_t defaults, const char *xpath)
|
||||
{
|
||||
struct mgmt_msg_get_data *msg;
|
||||
size_t xplen = strlen(xpath);
|
||||
@ -323,6 +324,7 @@ 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;
|
||||
strlcpy(msg->xpath, xpath, xplen + 1);
|
||||
|
||||
MGMTD_FE_CLIENT_DBG("Sending GET_DATA_REQ session-id %" PRIu64
|
||||
|
@ -390,6 +390,9 @@ extern int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client,
|
||||
* flags
|
||||
* Flags to control the behavior of the request.
|
||||
*
|
||||
* defaults
|
||||
* Options to control the reporting of default values.
|
||||
*
|
||||
* xpath
|
||||
* the xpath to get.
|
||||
*
|
||||
@ -399,7 +402,7 @@ 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,
|
||||
const char *xpath);
|
||||
uint8_t defaults, const char *xpath);
|
||||
|
||||
/*
|
||||
* Destroy library and cleanup everything.
|
||||
|
@ -240,17 +240,28 @@ _Static_assert(sizeof(struct mgmt_msg_tree_data) ==
|
||||
#define GET_DATA_FLAG_CONFIG 0x02 /* get only "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 defaults;
|
||||
uint8_t resv2[6];
|
||||
|
||||
alignas(8) char xpath[];
|
||||
|
@ -4102,7 +4102,8 @@ int vty_mgmt_send_get_req(struct vty *vty, bool is_config,
|
||||
}
|
||||
|
||||
int vty_mgmt_send_get_data_req(struct vty *vty, LYD_FORMAT result_type,
|
||||
uint8_t flags, const char *xpath)
|
||||
uint8_t flags, uint8_t defaults,
|
||||
const char *xpath)
|
||||
{
|
||||
LYD_FORMAT intern_format = result_type;
|
||||
|
||||
@ -4110,7 +4111,7 @@ int vty_mgmt_send_get_data_req(struct vty *vty, LYD_FORMAT result_type,
|
||||
|
||||
if (mgmt_fe_send_get_data_req(mgmt_fe_client, vty->mgmt_session_id,
|
||||
vty->mgmt_req_id, intern_format, flags,
|
||||
xpath)) {
|
||||
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);
|
||||
|
@ -421,7 +421,8 @@ 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);
|
||||
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);
|
||||
|
@ -1080,7 +1080,7 @@ 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)
|
||||
|
||||
@ -1105,8 +1105,7 @@ static int fe_adapter_send_tree_data(struct mgmt_fe_session_ctx *session,
|
||||
|
||||
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
|
||||
@ -1147,6 +1146,7 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session,
|
||||
char *xpath_resolved = NULL;
|
||||
uint64_t req_id = msg->req_id;
|
||||
uint64_t clients;
|
||||
uint32_t wd_options;
|
||||
bool simple_xpath;
|
||||
LY_ERR err;
|
||||
int ret;
|
||||
@ -1171,6 +1171,25 @@ 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;
|
||||
}
|
||||
|
||||
err = yang_resolve_snode_xpath(ly_native_ctx, msg->xpath, &snodes,
|
||||
&simple_xpath);
|
||||
@ -1190,7 +1209,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;
|
||||
}
|
||||
|
||||
@ -1210,7 +1229,7 @@ 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);
|
||||
wd_options, simple_xpath, msg->xpath);
|
||||
if (ret) {
|
||||
/* destroy the just created txn */
|
||||
mgmt_destroy_txn(&session->txn_id);
|
||||
@ -1469,6 +1488,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)
|
||||
{
|
||||
@ -1480,7 +1500,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);
|
||||
|
||||
|
@ -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.
|
||||
@ -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.
|
||||
|
@ -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
|
||||
@ -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.
|
||||
*/
|
||||
|
@ -175,6 +175,7 @@ struct txn_req_get_tree {
|
||||
uint64_t recv_clients; /* Bitmask of clients recv reply from */
|
||||
int32_t partial_error; /* an error while gather results */
|
||||
uint8_t result_type; /* LYD_FORMAT for results */
|
||||
uint8_t wd_options; /* LYD_PRINT_WD_* flags for results */
|
||||
uint8_t exact; /* if exact node is requested */
|
||||
uint8_t simple_xpath; /* if xpath is simple */
|
||||
struct lyd_node *client_results; /* result tree from clients */
|
||||
@ -1282,6 +1283,7 @@ static int txn_get_tree_data_done(struct mgmt_txn_ctx *txn,
|
||||
txn->txn_id,
|
||||
txn_req->req_id,
|
||||
get_tree->result_type,
|
||||
get_tree->wd_options,
|
||||
result,
|
||||
get_tree->partial_error,
|
||||
false);
|
||||
@ -2340,8 +2342,8 @@ int mgmt_txn_send_get_req(uint64_t txn_id, uint64_t req_id,
|
||||
*/
|
||||
int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id,
|
||||
uint64_t clients, LYD_FORMAT result_type,
|
||||
uint8_t flags, bool simple_xpath,
|
||||
const char *xpath)
|
||||
uint8_t flags, uint32_t wd_options,
|
||||
bool simple_xpath, const char *xpath)
|
||||
{
|
||||
struct mgmt_msg_get_tree *msg;
|
||||
struct mgmt_txn_ctx *txn;
|
||||
@ -2359,6 +2361,7 @@ int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id,
|
||||
txn_req = mgmt_txn_req_alloc(txn, req_id, MGMTD_TXN_PROC_GETTREE);
|
||||
get_tree = txn_req->req.get_tree;
|
||||
get_tree->result_type = result_type;
|
||||
get_tree->wd_options = wd_options;
|
||||
get_tree->exact = CHECK_FLAG(flags, GET_DATA_FLAG_EXACT);
|
||||
get_tree->simple_xpath = simple_xpath;
|
||||
get_tree->xpath = XSTRDUP(MTYPE_MGMTD_XPATH, xpath);
|
||||
|
@ -204,6 +204,7 @@ extern int mgmt_txn_send_get_req(uint64_t txn_id, uint64_t req_id,
|
||||
* clients: Bitmask of clients to send get-tree to.
|
||||
* result_type: LYD_FORMAT result format.
|
||||
* flags: option flags for the request.
|
||||
* wd_options: LYD_PRINT_WD_* flags for the result.
|
||||
* simple_xpath: true if xpath is simple (only key predicates).
|
||||
* xpath: The xpath to get the tree from.
|
||||
*
|
||||
@ -212,8 +213,8 @@ extern int mgmt_txn_send_get_req(uint64_t txn_id, uint64_t req_id,
|
||||
*/
|
||||
extern int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id,
|
||||
uint64_t clients, LYD_FORMAT result_type,
|
||||
uint8_t flags, bool simple_xpath,
|
||||
const char *xpath);
|
||||
uint8_t flags, uint32_t wd_options,
|
||||
bool simple_xpath, const char *xpath);
|
||||
|
||||
/*
|
||||
* Notifiy backend adapter on connection.
|
||||
|
@ -258,7 +258,7 @@ DEFPY(show_mgmt_get_config, show_mgmt_get_config_cmd,
|
||||
}
|
||||
|
||||
DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
|
||||
"show mgmt get-data WORD$path [with-config|only-config]$content [exact]$exact [json|xml]$fmt",
|
||||
"show mgmt get-data WORD$path [with-config|only-config]$content [exact]$exact [with-defaults <trim|all-tag|all>$wd] [json|xml]$fmt",
|
||||
SHOW_STR
|
||||
MGMTD_STR
|
||||
"Get a data from the operational datastore\n"
|
||||
@ -266,6 +266,10 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
|
||||
"Include \"config true\" data\n"
|
||||
"Get only \"config true\" data\n"
|
||||
"Get exact node instead of the whole data tree\n"
|
||||
"Configure 'with-defaults' mode per RFC 6243 (\"explicit\" mode by default)\n"
|
||||
"Use \"trim\" mode\n"
|
||||
"Use \"report-all-tagged\" mode\n"
|
||||
"Use \"report-all\" mode\n"
|
||||
"JSON output format\n"
|
||||
"XML output format\n")
|
||||
{
|
||||
@ -273,6 +277,7 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
|
||||
int plen = strlen(path);
|
||||
char *xpath = NULL;
|
||||
uint8_t flags = content ? GET_DATA_FLAG_CONFIG : GET_DATA_FLAG_STATE;
|
||||
uint8_t defaults = GET_DATA_DEFAULTS_EXPLICIT;
|
||||
|
||||
if (content && content[0] == 'w')
|
||||
flags |= GET_DATA_FLAG_STATE;
|
||||
@ -280,6 +285,15 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
|
||||
if (exact)
|
||||
flags |= GET_DATA_FLAG_EXACT;
|
||||
|
||||
if (wd) {
|
||||
if (wd[0] == 't')
|
||||
defaults = GET_DATA_DEFAULTS_TRIM;
|
||||
else if (wd[3] == '-')
|
||||
defaults = GET_DATA_DEFAULTS_ALL_ADD_TAG;
|
||||
else
|
||||
defaults = GET_DATA_DEFAULTS_ALL;
|
||||
}
|
||||
|
||||
/* get rid of extraneous trailing slash-* or single '/' unless root */
|
||||
if (plen > 2 && ((path[plen - 2] == '/' && path[plen - 1] == '*') ||
|
||||
(path[plen - 2] != '/' && path[plen - 1] == '/'))) {
|
||||
@ -289,7 +303,7 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
|
||||
path = xpath;
|
||||
}
|
||||
|
||||
vty_mgmt_send_get_data_req(vty, format, flags, path);
|
||||
vty_mgmt_send_get_data_req(vty, format, flags, defaults, path);
|
||||
|
||||
if (xpath)
|
||||
XFREE(MTYPE_TMP, xpath);
|
||||
|
@ -61,6 +61,9 @@ mgmtd_mgmtd_SOURCES = \
|
||||
# end
|
||||
nodist_mgmtd_mgmtd_SOURCES = \
|
||||
yang/frr-zebra.yang.c \
|
||||
yang/ietf/ietf-netconf-acm.yang.c \
|
||||
yang/ietf/ietf-netconf.yang.c \
|
||||
yang/ietf/ietf-netconf-with-defaults.yang.c \
|
||||
# nothing
|
||||
mgmtd_mgmtd_CFLAGS = $(AM_CFLAGS) -I ./
|
||||
mgmtd_mgmtd_LDADD = mgmtd/libmgmtd.a lib/libfrr.la $(LIBCAP) $(LIBM) $(LIBYANG_LIBS) $(UST_LIBS)
|
||||
|
Loading…
Reference in New Issue
Block a user