summaryrefslogtreecommitdiffstats
path: root/lib/vty.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/vty.c146
1 files changed, 129 insertions, 17 deletions
diff --git a/lib/vty.c b/lib/vty.c
index 1c9cff4..d0bbf0e 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -39,6 +39,7 @@
#include "libfrr.h"
#include "frrstr.h"
#include "lib_errors.h"
+#include <libyang/version.h>
#include "northbound_cli.h"
#include "printfrr.h"
#include "json.h"
@@ -389,6 +390,21 @@ int vty_json_no_pretty(struct vty *vty, struct json_object *json)
return vty_json_helper(vty, json, JSON_C_TO_STRING_NOSLASHESCAPE);
}
+
+void vty_json_key(struct vty *vty, const char *key, bool *first_key)
+{
+ vty_out(vty, "%s\"%s\":", *first_key ? "{" : ",", key);
+ *first_key = false;
+}
+
+void vty_json_close(struct vty *vty, bool first_key)
+{
+ if (first_key)
+ /* JSON was not opened */
+ vty_out(vty, "{");
+ vty_out(vty, "}\n");
+}
+
void vty_json_empty(struct vty *vty, struct json_object *json)
{
json_object *jsonobj = json;
@@ -3486,7 +3502,7 @@ static void vty_mgmt_server_connected(struct mgmt_fe_client *client,
/* Start or stop listening for vty connections */
if (connected)
- frr_vty_serv_start();
+ frr_vty_serv_start(true);
else
frr_vty_serv_stop();
}
@@ -3570,12 +3586,14 @@ static void vty_mgmt_set_config_result_notified(
zlog_err("SET_CONFIG request for client 0x%" PRIx64
" failed, Error: '%s'",
client_id, errmsg_if_any ? errmsg_if_any : "Unknown");
- vty_out(vty, "ERROR: SET_CONFIG request failed, Error: %s\n",
- errmsg_if_any ? errmsg_if_any : "Unknown");
+ vty_out(vty, "%% Configuration failed.\n\n");
+ if (errmsg_if_any)
+ vty_out(vty, "%s\n", errmsg_if_any);
} else {
debug_fe_client("SET_CONFIG request for client 0x%" PRIx64
- " req-id %" PRIu64 " was successfull",
- client_id, req_id);
+ " req-id %" PRIu64 " was successfull%s%s",
+ client_id, req_id, errmsg_if_any ? ": " : "",
+ errmsg_if_any ?: "");
}
if (implicit_commit) {
@@ -3602,12 +3620,14 @@ static void vty_mgmt_commit_config_result_notified(
zlog_err("COMMIT_CONFIG request for client 0x%" PRIx64
" failed, Error: '%s'",
client_id, errmsg_if_any ? errmsg_if_any : "Unknown");
- vty_out(vty, "ERROR: COMMIT_CONFIG request failed, Error: %s\n",
- errmsg_if_any ? errmsg_if_any : "Unknown");
+ vty_out(vty, "%% Configuration failed.\n\n");
+ if (errmsg_if_any)
+ vty_out(vty, "%s\n", errmsg_if_any);
} else {
debug_fe_client("COMMIT_CONFIG request for client 0x%" PRIx64
- " req-id %" PRIu64 " was successfull",
- client_id, req_id);
+ " req-id %" PRIu64 " was successfull%s%s",
+ client_id, req_id, errmsg_if_any ? ": " : "",
+ errmsg_if_any ?: "");
if (errmsg_if_any)
vty_out(vty, "MGMTD: %s\n", errmsg_if_any);
}
@@ -3638,8 +3658,9 @@ static int vty_mgmt_get_data_result_notified(
}
debug_fe_client("GET_DATA request succeeded, client 0x%" PRIx64
- " req-id %" PRIu64,
- client_id, req_id);
+ " req-id %" PRIu64 "%s%s",
+ client_id, req_id, errmsg_if_any ? ": " : "",
+ errmsg_if_any ?: "");
if (req_id != mgmt_last_req_id) {
mgmt_last_req_id = req_id;
@@ -3668,15 +3689,24 @@ static ssize_t vty_mgmt_libyang_print(void *user_data, const void *buf,
}
static void vty_out_yang_error(struct vty *vty, LYD_FORMAT format,
- struct ly_err_item *ei)
+ const struct ly_err_item *ei)
{
+#if (LY_VERSION_MAJOR < 3)
+#define data_path path
+#else
+#define data_path data_path
+#endif
bool have_apptag = ei->apptag && ei->apptag[0] != 0;
- bool have_path = ei->path && ei->path[0] != 0;
+ bool have_path = ei->data_path && ei->data_path[0] != 0;
bool have_msg = ei->msg && ei->msg[0] != 0;
const char *severity = NULL;
const char *evalid = NULL;
const char *ecode = NULL;
+#if (LY_VERSION_MAJOR < 3)
LY_ERR err = ei->no;
+#else
+ LY_ERR err = ei->err;
+#endif
if (ei->level == LY_LLERR)
severity = "error";
@@ -3701,7 +3731,8 @@ static void vty_out_yang_error(struct vty *vty, LYD_FORMAT format,
vty_out(vty, "<error-validation>%s</error-validation>\n",
evalid);
if (have_path)
- vty_out(vty, "<error-path>%s</error-path>\n", ei->path);
+ vty_out(vty, "<error-path>%s</error-path>\n",
+ ei->data_path);
if (have_apptag)
vty_out(vty, "<error-app-tag>%s</error-app-tag>\n",
ei->apptag);
@@ -3720,7 +3751,7 @@ static void vty_out_yang_error(struct vty *vty, LYD_FORMAT format,
if (evalid)
vty_out(vty, ", \"error-validation\": \"%s\"", evalid);
if (have_path)
- vty_out(vty, ", \"error-path\": \"%s\"", ei->path);
+ vty_out(vty, ", \"error-path\": \"%s\"", ei->data_path);
if (have_apptag)
vty_out(vty, ", \"error-app-tag\": \"%s\"", ei->apptag);
if (have_msg)
@@ -3737,18 +3768,19 @@ static void vty_out_yang_error(struct vty *vty, LYD_FORMAT format,
if (evalid)
vty_out(vty, " invalid: %s", evalid);
if (have_path)
- vty_out(vty, " path: %s", ei->path);
+ vty_out(vty, " path: %s", ei->data_path);
if (have_apptag)
vty_out(vty, " app-tag: %s", ei->apptag);
if (have_msg)
vty_out(vty, " msg: %s", ei->msg);
break;
}
+#undef data_path
}
static uint vty_out_yang_errors(struct vty *vty, LYD_FORMAT format)
{
- struct ly_err_item *ei = ly_err_first(ly_native_ctx);
+ const struct ly_err_item *ei = ly_err_first(ly_native_ctx);
uint count;
if (!ei)
@@ -3824,6 +3856,43 @@ static int vty_mgmt_get_tree_result_notified(
return 0;
}
+static int vty_mgmt_edit_result_notified(struct mgmt_fe_client *client,
+ uintptr_t user_data,
+ uint64_t client_id, uint64_t session_id,
+ uintptr_t session_ctx, uint64_t req_id,
+ const char *xpath)
+{
+ struct vty *vty = (struct vty *)session_ctx;
+
+ debug_fe_client("EDIT request for client 0x%" PRIx64 " req-id %" PRIu64
+ " was successful, xpath: %s",
+ client_id, req_id, xpath);
+
+ vty_mgmt_resume_response(vty, CMD_SUCCESS);
+
+ return 0;
+}
+
+static int vty_mgmt_rpc_result_notified(struct mgmt_fe_client *client,
+ uintptr_t user_data, uint64_t client_id,
+ uint64_t session_id,
+ uintptr_t session_ctx, uint64_t req_id,
+ const char *result)
+{
+ struct vty *vty = (struct vty *)session_ctx;
+
+ debug_fe_client("RPC request for client 0x%" PRIx64 " req-id %" PRIu64
+ " was successful",
+ client_id, req_id);
+
+ if (result)
+ vty_out(vty, "%s\n", result);
+
+ vty_mgmt_resume_response(vty, CMD_SUCCESS);
+
+ return 0;
+}
+
static int vty_mgmt_error_notified(struct mgmt_fe_client *client,
uintptr_t user_data, uint64_t client_id,
uint64_t session_id, uintptr_t session_ctx,
@@ -3865,6 +3934,8 @@ static struct mgmt_fe_client_cbs mgmt_cbs = {
.commit_config_notify = vty_mgmt_commit_config_result_notified,
.get_data_notify = vty_mgmt_get_data_result_notified,
.get_tree_notify = vty_mgmt_get_tree_result_notified,
+ .edit_notify = vty_mgmt_edit_result_notified,
+ .rpc_notify = vty_mgmt_rpc_result_notified,
.error_notify = vty_mgmt_error_notified,
};
@@ -4120,6 +4191,47 @@ int vty_mgmt_send_get_data_req(struct vty *vty, uint8_t datastore,
return 0;
}
+int vty_mgmt_send_edit_req(struct vty *vty, uint8_t datastore,
+ LYD_FORMAT request_type, uint8_t flags,
+ uint8_t operation, const char *xpath,
+ const char *data)
+{
+ vty->mgmt_req_id++;
+
+ if (mgmt_fe_send_edit_req(mgmt_fe_client, vty->mgmt_session_id,
+ vty->mgmt_req_id, datastore, request_type,
+ flags, operation, xpath, data)) {
+ zlog_err("Failed to send EDIT to MGMTD session-id: %" PRIu64
+ " req-id %" PRIu64 ".",
+ vty->mgmt_session_id, vty->mgmt_req_id);
+ vty_out(vty, "Failed to send EDIT to MGMTD!\n");
+ return -1;
+ }
+
+ vty->mgmt_req_pending_cmd = "MESSAGE_EDIT_REQ";
+
+ return 0;
+}
+
+int vty_mgmt_send_rpc_req(struct vty *vty, LYD_FORMAT request_type,
+ const char *xpath, const char *data)
+{
+ vty->mgmt_req_id++;
+
+ if (mgmt_fe_send_rpc_req(mgmt_fe_client, vty->mgmt_session_id,
+ vty->mgmt_req_id, request_type, xpath, data)) {
+ zlog_err("Failed to send RPC to MGMTD session-id: %" PRIu64
+ " req-id %" PRIu64 ".",
+ vty->mgmt_session_id, vty->mgmt_req_id);
+ vty_out(vty, "Failed to send RPC to MGMTD!\n");
+ return -1;
+ }
+
+ vty->mgmt_req_pending_cmd = "MESSAGE_RPC_REQ";
+
+ return 0;
+}
+
/* Install vty's own commands like `who' command. */
void vty_init(struct event_loop *master_thread, bool do_command_logging)
{