]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib, mgmtd: add ability to request the exact node in get-data request
authorIgor Ryzhov <iryzhov@nfware.com>
Sat, 13 Jan 2024 22:53:21 +0000 (00:53 +0200)
committerIgor Ryzhov <iryzhov@nfware.com>
Mon, 15 Jan 2024 08:27:33 +0000 (10:27 +0200)
RESTCONF expects to receive the exact node as a result, not the whole
data tree.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
lib/mgmt_msg_native.h
mgmtd/mgmt_txn.c
mgmtd/mgmt_vty.c

index 88c1065fc84edf7577c9d8d95e37ae42d4b7883d..069cb9b150751b50eb4d43463ac9b43c672fec3b 100644 (file)
@@ -236,6 +236,7 @@ _Static_assert(sizeof(struct mgmt_msg_tree_data) ==
 /* 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_EXACT    0x04    /* get exact data node instead of the full tree */
 
 /**
  * struct mgmt_msg_get_data - frontend get-data request.
index 3a2a23d9e9d849b05a6bc2c15c10040ab87b8e42..842e13cf117b116ef0a36527061bd1b4f6a39ef6 100644 (file)
@@ -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);
 
@@ -2383,6 +2390,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->exact = CHECK_FLAG(flags, GET_DATA_FLAG_EXACT);
        get_tree->simple_xpath = simple_xpath;
        get_tree->xpath = XSTRDUP(MTYPE_MGMTD_XPATH, xpath);
 
index e6f74c31290e920c365df9f8ec7a610edf95af92..f4b24acf3ace129afcfdc59195a4cc0d96ddac04 100644 (file)
@@ -251,13 +251,14 @@ 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 [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")
 {
@@ -269,6 +270,9 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd,
        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] == '*') ||
                         (path[plen - 2] != '/' && path[plen - 1] == '/'))) {