summaryrefslogtreecommitdiffstats
path: root/mgmtd
diff options
context:
space:
mode:
Diffstat (limited to 'mgmtd')
-rw-r--r--mgmtd/mgmt_fe_adapter.c18
-rw-r--r--mgmtd/mgmt_main.c7
-rw-r--r--mgmtd/mgmt_txn.c64
-rw-r--r--mgmtd/mgmt_txn.h4
-rw-r--r--mgmtd/mgmt_vty.c14
5 files changed, 93 insertions, 14 deletions
diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c
index a69d27fc5..d91987d88 100644
--- a/mgmtd/mgmt_fe_adapter.c
+++ b/mgmtd/mgmt_fe_adapter.c
@@ -1132,15 +1132,15 @@ done:
}
/**
- * fe_adapter_handle_get_tree() - Handle a get-tree message from a FE client.
+ * fe_adapter_handle_get_data() - Handle a get-tree message from a FE client.
* @session: the client session.
* @msg_raw: the message data.
* @msg_len: the length of the message data.
*/
-static void fe_adapter_handle_get_tree(struct mgmt_fe_session_ctx *session,
+static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session,
void *__msg, size_t msg_len)
{
- struct mgmt_msg_get_tree *msg = __msg;
+ struct mgmt_msg_get_data *msg = __msg;
struct lysc_node **snodes = NULL;
char *xpath_resolved = NULL;
uint64_t req_id = msg->req_id;
@@ -1149,7 +1149,7 @@ static void fe_adapter_handle_get_tree(struct mgmt_fe_session_ctx *session,
LY_ERR err;
int ret;
- MGMTD_FE_ADAPTER_DBG("Received get-tree request from client %s for session-id %" PRIu64
+ MGMTD_FE_ADAPTER_DBG("Received get-data request from client %s for session-id %" PRIu64
" req-id %" PRIu64,
session->adapter->name, session->session_id,
msg->req_id);
@@ -1181,7 +1181,7 @@ static void fe_adapter_handle_get_tree(struct mgmt_fe_session_ctx *session,
darr_free(snodes);
clients = mgmt_be_interested_clients(msg->xpath, false);
- if (!clients) {
+ if (!clients && !CHECK_FLAG(msg->flags, GET_DATA_FLAG_CONFIG)) {
MGMTD_FE_ADAPTER_DBG("No backends provide xpath: %s for txn-id: %" PRIu64
" session-id: %" PRIu64,
msg->xpath, session->txn_id,
@@ -1207,8 +1207,8 @@ static void fe_adapter_handle_get_tree(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, simple_xpath,
- msg->xpath);
+ msg->result_type, msg->flags,
+ simple_xpath, msg->xpath);
if (ret) {
/* destroy the just created txn */
mgmt_destroy_txn(&session->txn_id);
@@ -1238,8 +1238,8 @@ static void fe_adapter_handle_native_msg(struct mgmt_fe_client_adapter *adapter,
assert(session->adapter == adapter);
switch (msg->code) {
- case MGMT_MSG_CODE_GET_TREE:
- fe_adapter_handle_get_tree(session, msg, msg_len);
+ case MGMT_MSG_CODE_GET_DATA:
+ fe_adapter_handle_get_data(session, msg, msg_len);
break;
default:
MGMTD_FE_ADAPTER_ERR("unknown native message session-id %" PRIu64
diff --git a/mgmtd/mgmt_main.c b/mgmtd/mgmt_main.c
index 72bb353b2..743091e5c 100644
--- a/mgmtd/mgmt_main.c
+++ b/mgmtd/mgmt_main.c
@@ -22,6 +22,7 @@ static const struct option longopts[] = {
{"skip_runas", no_argument, NULL, 'S'},
{"no_zebra", no_argument, NULL, 'Z'},
{"socket_size", required_argument, NULL, 's'},
+ {"vrfwnetns", no_argument, NULL, 'n'},
{0}};
static void mgmt_exit(int);
@@ -237,6 +238,9 @@ int main(int argc, char **argv)
case 's':
buffer_size = atoi(optarg);
break;
+ case 'n':
+ vrf_configure_backend(VRF_BACKEND_NETNS);
+ break;
default:
frr_help_exit(1);
break;
@@ -249,6 +253,9 @@ int main(int argc, char **argv)
/* VRF commands initialization. */
vrf_cmd_init(NULL);
+ /* Interface commands initialization. */
+ if_cmd_init(NULL);
+
/* MGMTD related initialization. */
mgmt_init();
diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c
index 679eaa7d7..842e13cf1 100644
--- a/mgmtd/mgmt_txn.c
+++ b/mgmtd/mgmt_txn.c
@@ -176,6 +176,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 exact; /* if exact node is requested */
uint8_t simple_xpath; /* if xpath is simple */
struct lyd_node *client_results; /* result tree from clients */
};
@@ -1258,6 +1259,7 @@ static int txn_get_tree_data_done(struct mgmt_txn_ctx *txn,
{
struct txn_req_get_tree *get_tree = txn_req->req.get_tree;
uint64_t req_id = txn_req->req_id;
+ struct lyd_node *result;
int ret = NB_OK;
/* cancel timer and send reply onward */
@@ -1272,12 +1274,17 @@ static int txn_get_tree_data_done(struct mgmt_txn_ctx *txn,
ret = NB_ERR;
}
+ result = get_tree->client_results;
+
+ if (ret == NB_OK && result && get_tree->exact)
+ result = yang_dnode_get(result, get_tree->xpath);
+
if (ret == NB_OK)
ret = mgmt_fe_adapter_send_tree_data(txn->session_id,
txn->txn_id,
txn_req->req_id,
get_tree->result_type,
- get_tree->client_results,
+ result,
get_tree->partial_error,
false);
@@ -2364,7 +2371,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,
- bool simple_xpath, const char *xpath)
+ uint8_t flags, bool simple_xpath,
+ const char *xpath)
{
struct mgmt_msg_get_tree *msg;
struct mgmt_txn_ctx *txn;
@@ -2382,9 +2390,61 @@ 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->exact = CHECK_FLAG(flags, GET_DATA_FLAG_EXACT);
get_tree->simple_xpath = simple_xpath;
get_tree->xpath = XSTRDUP(MTYPE_MGMTD_XPATH, xpath);
+ if (CHECK_FLAG(flags, GET_DATA_FLAG_CONFIG)) {
+ struct mgmt_ds_ctx *ds =
+ mgmt_ds_get_ctx_by_id(mm, MGMTD_DS_RUNNING);
+ struct nb_config *config = mgmt_ds_get_nb_config(ds);
+
+ if (config) {
+ struct ly_set *set = NULL;
+ LY_ERR err;
+
+ err = lyd_find_xpath(config->dnode, xpath, &set);
+ if (err) {
+ get_tree->partial_error = err;
+ goto state;
+ }
+
+ /*
+ * If there's a single result, duplicate the returned
+ * node. If there are multiple results, duplicate the
+ * whole config and mark simple_xpath as false so the
+ * result is trimmed later in txn_get_tree_data_done.
+ */
+ if (set->count == 1) {
+ err = lyd_dup_single(set->dnodes[0], NULL,
+ LYD_DUP_WITH_PARENTS |
+ LYD_DUP_WITH_FLAGS |
+ LYD_DUP_RECURSIVE,
+ &get_tree->client_results);
+ if (!err)
+ while (get_tree->client_results->parent)
+ get_tree->client_results = lyd_parent(
+ get_tree->client_results);
+ } else if (set->count > 1) {
+ err = lyd_dup_siblings(config->dnode, NULL,
+ LYD_DUP_RECURSIVE |
+ LYD_DUP_WITH_FLAGS,
+ &get_tree->client_results);
+ if (!err)
+ get_tree->simple_xpath = false;
+ }
+
+ if (err)
+ get_tree->partial_error = err;
+
+ ly_set_free(set, NULL);
+ }
+ }
+state:
+ /* If we are only getting config, we are done */
+ if (!CHECK_FLAG(flags, GET_DATA_FLAG_STATE) || !clients)
+ return txn_get_tree_data_done(txn, txn_req);
+
msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_get_tree, slen + 1,
MTYPE_MSG_NATIVE_GET_TREE);
msg->refer_id = txn_id;
diff --git a/mgmtd/mgmt_txn.h b/mgmtd/mgmt_txn.h
index 39d8cde16..3f27f2f07 100644
--- a/mgmtd/mgmt_txn.h
+++ b/mgmtd/mgmt_txn.h
@@ -203,6 +203,7 @@ extern int mgmt_txn_send_get_req(uint64_t txn_id, uint64_t req_id,
* req_id: FE client request identifier.
* clients: Bitmask of clients to send get-tree to.
* result_type: LYD_FORMAT result format.
+ * flags: option flags for the request.
* simple_xpath: true if xpath is simple (only key predicates).
* xpath: The xpath to get the tree from.
*
@@ -211,7 +212,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,
- bool simple_xpath, const char *xpath);
+ uint8_t flags, bool simple_xpath,
+ const char *xpath);
/*
* Notifiy backend adapter on connection.
diff --git a/mgmtd/mgmt_vty.c b/mgmtd/mgmt_vty.c
index 2591930e4..f4b24acf3 100644
--- a/mgmtd/mgmt_vty.c
+++ b/mgmtd/mgmt_vty.c
@@ -251,17 +251,27 @@ 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 [json|xml]$fmt",
+ "show mgmt get-data WORD$path [with-config|only-config]$content [exact]$exact [json|xml]$fmt",
SHOW_STR
MGMTD_STR
"Get a data from the operational datastore\n"
"XPath expression specifying the YANG data root\n"
+ "Include \"config true\" data\n"
+ "Get only \"config true\" data\n"
+ "Get exact node instead of the whole data tree\n"
"JSON output format\n"
"XML output format\n")
{
LYD_FORMAT format = (fmt && fmt[0] == 'x') ? LYD_XML : LYD_JSON;
int plen = strlen(path);
char *xpath = NULL;
+ uint8_t flags = content ? GET_DATA_FLAG_CONFIG : GET_DATA_FLAG_STATE;
+
+ if (content && content[0] == 'w')
+ flags |= GET_DATA_FLAG_STATE;
+
+ if (exact)
+ flags |= GET_DATA_FLAG_EXACT;
/* get rid of extraneous trailing slash-* or single '/' unless root */
if (plen > 2 && ((path[plen - 2] == '/' && path[plen - 1] == '*') ||
@@ -272,7 +282,7 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
path = xpath;
}
- vty_mgmt_send_get_tree_req(vty, format, path);
+ vty_mgmt_send_get_data_req(vty, format, flags, path);
if (xpath)
XFREE(MTYPE_TMP, xpath);