summaryrefslogtreecommitdiff
path: root/lib/mgmt_fe_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mgmt_fe_client.c')
-rw-r--r--lib/mgmt_fe_client.c1180
1 files changed, 485 insertions, 695 deletions
diff --git a/lib/mgmt_fe_client.c b/lib/mgmt_fe_client.c
index 7cb9aa3def..a107582bea 100644
--- a/lib/mgmt_fe_client.c
+++ b/lib/mgmt_fe_client.c
@@ -6,38 +6,26 @@
*/
#include <zebra.h>
+#include "compiler.h"
+#include "debug.h"
#include "memory.h"
#include "libfrr.h"
#include "mgmt_fe_client.h"
#include "mgmt_msg.h"
+#include "mgmt_msg_native.h"
#include "mgmt_pb.h"
#include "network.h"
#include "stream.h"
#include "sockopt.h"
-#ifdef REDIRECT_DEBUG_TO_STDERR
-#define MGMTD_FE_CLIENT_DBG(fmt, ...) \
- fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__)
-#define MGMTD_FE_CLIENT_ERR(fmt, ...) \
- fprintf(stderr, "%s: ERROR, " fmt "\n", __func__, ##__VA_ARGS__)
-#else /* REDIRECT_DEBUG_TO_STDERR */
-#define MGMTD_FE_CLIENT_DBG(fmt, ...) \
- do { \
- if (mgmt_debug_fe_client) \
- zlog_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
- } while (0)
-#define MGMTD_FE_CLIENT_ERR(fmt, ...) \
- zlog_err("%s: ERROR: " fmt, __func__, ##__VA_ARGS__)
-#endif /* REDIRECT_DEBUG_TO_STDERR */
-
-struct mgmt_fe_client_ctx;
+#include "lib/mgmt_fe_client_clippy.c"
PREDECL_LIST(mgmt_sessions);
struct mgmt_fe_client_session {
- uint64_t client_id;
- uint64_t session_id;
- struct mgmt_fe_client_ctx *client_ctx;
+ uint64_t client_id; /* FE client identifies itself with this ID */
+ uint64_t session_id; /* FE adapter identified session with this ID */
+ struct mgmt_fe_client *client;
uintptr_t user_ctx;
struct mgmt_sessions_item list_linkage;
@@ -45,188 +33,112 @@ struct mgmt_fe_client_session {
DECLARE_LIST(mgmt_sessions, struct mgmt_fe_client_session, list_linkage);
-DEFINE_MTYPE_STATIC(LIB, MGMTD_FE_SESSION, "MGMTD Frontend session");
+DEFINE_MTYPE_STATIC(LIB, MGMTD_FE_CLIENT, "frontend client");
+DEFINE_MTYPE_STATIC(LIB, MGMTD_FE_CLIENT_NAME, "frontend client name");
+DEFINE_MTYPE_STATIC(LIB, MGMTD_FE_SESSION, "frontend session");
-struct mgmt_fe_client_ctx {
- int conn_fd;
- struct event_loop *tm;
- struct event *conn_retry_tmr;
- struct event *conn_read_ev;
- struct event *conn_write_ev;
- struct event *conn_writes_on;
- struct event *msg_proc_ev;
- uint32_t flags;
-
- struct mgmt_msg_state mstate;
-
- struct mgmt_fe_client_params client_params;
-
- struct mgmt_sessions_head client_sessions;
+struct mgmt_fe_client {
+ struct msg_client client;
+ char *name;
+ struct mgmt_fe_client_cbs cbs;
+ uintptr_t user_data;
+ struct mgmt_sessions_head sessions;
};
-#define MGMTD_FE_CLIENT_FLAGS_WRITES_OFF (1U << 0)
-
-#define FOREACH_SESSION_IN_LIST(client_ctx, session) \
- frr_each_safe (mgmt_sessions, &(client_ctx)->client_sessions, (session))
+#define FOREACH_SESSION_IN_LIST(client, session) \
+ frr_each_safe (mgmt_sessions, &(client)->sessions, (session))
-static bool mgmt_debug_fe_client;
-
-static struct mgmt_fe_client_ctx mgmt_fe_client_ctx = {
- .conn_fd = -1,
+struct debug mgmt_dbg_fe_client = {
+ .desc = "Management frontend client operations"
};
-/* Forward declarations */
-static void
-mgmt_fe_client_register_event(struct mgmt_fe_client_ctx *client_ctx,
- enum mgmt_fe_event event);
-static void mgmt_fe_client_schedule_conn_retry(
- struct mgmt_fe_client_ctx *client_ctx, unsigned long intvl_secs);
+/* NOTE: only one client per proc for now. */
+static struct mgmt_fe_client *__fe_client;
+
+static inline const char *dsid2name(Mgmtd__DatastoreId id)
+{
+ switch ((int)id) {
+ case MGMTD_DS_NONE:
+ return "none";
+ case MGMTD_DS_RUNNING:
+ return "running";
+ case MGMTD_DS_CANDIDATE:
+ return "candidate";
+ case MGMTD_DS_OPERATIONAL:
+ return "operational";
+ default:
+ return "unknown-datastore-id";
+ }
+}
static struct mgmt_fe_client_session *
-mgmt_fe_find_session_by_client_id(struct mgmt_fe_client_ctx *client_ctx,
- uint64_t client_id)
+mgmt_fe_find_session_by_client_id(struct mgmt_fe_client *client,
+ uint64_t client_id)
{
struct mgmt_fe_client_session *session;
- FOREACH_SESSION_IN_LIST (client_ctx, session) {
+ FOREACH_SESSION_IN_LIST (client, session) {
if (session->client_id == client_id) {
- MGMTD_FE_CLIENT_DBG(
- "Found session %p for client-id %llu.", session,
- (unsigned long long)client_id);
+ debug_fe_client("Found session-id %" PRIu64
+ " using client-id %" PRIu64,
+ session->session_id, client_id);
return session;
}
}
-
+ debug_fe_client("Session not found using client-id %" PRIu64, client_id);
return NULL;
}
static struct mgmt_fe_client_session *
-mgmt_fe_find_session_by_session_id(struct mgmt_fe_client_ctx *client_ctx,
- uint64_t session_id)
+mgmt_fe_find_session_by_session_id(struct mgmt_fe_client *client,
+ uint64_t session_id)
{
struct mgmt_fe_client_session *session;
- FOREACH_SESSION_IN_LIST (client_ctx, session) {
+ FOREACH_SESSION_IN_LIST (client, session) {
if (session->session_id == session_id) {
- MGMTD_FE_CLIENT_DBG(
- "Found session %p for session-id %llu.",
- session, (unsigned long long)session_id);
+ debug_fe_client("Found session of client-id %" PRIu64
+ " using session-id %" PRIu64,
+ session->client_id, session_id);
return session;
}
}
-
+ debug_fe_client("Session not found using session-id %" PRIu64,
+ session_id);
return NULL;
}
-static void
-mgmt_fe_server_disconnect(struct mgmt_fe_client_ctx *client_ctx,
- bool reconnect)
+static int mgmt_fe_client_send_msg(struct mgmt_fe_client *client,
+ Mgmtd__FeMessage *fe_msg,
+ bool short_circuit_ok)
{
- if (client_ctx->conn_fd != -1) {
- close(client_ctx->conn_fd);
- client_ctx->conn_fd = -1;
- }
-
- if (reconnect)
- mgmt_fe_client_schedule_conn_retry(
- client_ctx,
- client_ctx->client_params.conn_retry_intvl_sec);
-}
-
-static inline void
-mgmt_fe_client_sched_msg_write(struct mgmt_fe_client_ctx *client_ctx)
-{
- if (!CHECK_FLAG(client_ctx->flags, MGMTD_FE_CLIENT_FLAGS_WRITES_OFF))
- mgmt_fe_client_register_event(client_ctx,
- MGMTD_FE_CONN_WRITE);
-}
-
-static inline void
-mgmt_fe_client_writes_on(struct mgmt_fe_client_ctx *client_ctx)
-{
- MGMTD_FE_CLIENT_DBG("Resume writing msgs");
- UNSET_FLAG(client_ctx->flags, MGMTD_FE_CLIENT_FLAGS_WRITES_OFF);
- mgmt_fe_client_sched_msg_write(client_ctx);
-}
-
-static inline void
-mgmt_fe_client_writes_off(struct mgmt_fe_client_ctx *client_ctx)
-{
- SET_FLAG(client_ctx->flags, MGMTD_FE_CLIENT_FLAGS_WRITES_OFF);
- MGMTD_FE_CLIENT_DBG("Paused writing msgs");
-}
-
-static int mgmt_fe_client_send_msg(struct mgmt_fe_client_ctx *client_ctx,
- Mgmtd__FeMessage *fe_msg)
-{
- /* users current expect this to fail here */
- if (client_ctx->conn_fd == -1) {
- MGMTD_FE_CLIENT_DBG("can't send message on closed connection");
- return -1;
- }
-
- int rv = mgmt_msg_send_msg(
- &client_ctx->mstate, fe_msg,
+ return msg_conn_send_msg(
+ &client->client.conn, MGMT_MSG_VERSION_PROTOBUF, fe_msg,
mgmtd__fe_message__get_packed_size(fe_msg),
(size_t(*)(void *, void *))mgmtd__fe_message__pack,
- mgmt_debug_fe_client);
- mgmt_fe_client_sched_msg_write(client_ctx);
- return rv;
+ short_circuit_ok);
}
-static void mgmt_fe_client_write(struct event *thread)
-{
- struct mgmt_fe_client_ctx *client_ctx;
- enum mgmt_msg_wsched rv;
-
- client_ctx = (struct mgmt_fe_client_ctx *)EVENT_ARG(thread);
- rv = mgmt_msg_write(&client_ctx->mstate, client_ctx->conn_fd,
- mgmt_debug_fe_client);
- if (rv == MSW_SCHED_STREAM)
- mgmt_fe_client_register_event(client_ctx, MGMTD_FE_CONN_WRITE);
- else if (rv == MSW_DISCONNECT)
- mgmt_fe_server_disconnect(client_ctx, true);
- else if (rv == MSW_SCHED_WRITES_OFF) {
- mgmt_fe_client_writes_off(client_ctx);
- mgmt_fe_client_register_event(client_ctx,
- MGMTD_FE_CONN_WRITES_ON);
- } else
- assert(rv == MSW_SCHED_NONE);
-}
-
-static void mgmt_fe_client_resume_writes(struct event *thread)
-{
- struct mgmt_fe_client_ctx *client_ctx;
-
- client_ctx = (struct mgmt_fe_client_ctx *)EVENT_ARG(thread);
- assert(client_ctx && client_ctx->conn_fd != -1);
-
- mgmt_fe_client_writes_on(client_ctx);
-}
-
-static int
-mgmt_fe_send_register_req(struct mgmt_fe_client_ctx *client_ctx)
+static int mgmt_fe_send_register_req(struct mgmt_fe_client *client)
{
Mgmtd__FeMessage fe_msg;
Mgmtd__FeRegisterReq rgstr_req;
mgmtd__fe_register_req__init(&rgstr_req);
- rgstr_req.client_name = client_ctx->client_params.name;
+ rgstr_req.client_name = client->name;
mgmtd__fe_message__init(&fe_msg);
fe_msg.message_case = MGMTD__FE_MESSAGE__MESSAGE_REGISTER_REQ;
fe_msg.register_req = &rgstr_req;
- MGMTD_FE_CLIENT_DBG(
- "Sending REGISTER_REQ message to MGMTD Frontend server");
+ debug_fe_client("Sending REGISTER_REQ message to MGMTD Frontend server");
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg);
+ return mgmt_fe_client_send_msg(client, &fe_msg, true);
}
-static int
-mgmt_fe_send_session_req(struct mgmt_fe_client_ctx *client_ctx,
- struct mgmt_fe_client_session *session,
- bool create)
+static int mgmt_fe_send_session_req(struct mgmt_fe_client *client,
+ struct mgmt_fe_client_session *session,
+ bool create)
{
Mgmtd__FeMessage fe_msg;
Mgmtd__FeSessionReq sess_req;
@@ -245,25 +157,22 @@ mgmt_fe_send_session_req(struct mgmt_fe_client_ctx *client_ctx,
fe_msg.message_case = MGMTD__FE_MESSAGE__MESSAGE_SESSION_REQ;
fe_msg.session_req = &sess_req;
- MGMTD_FE_CLIENT_DBG(
- "Sending SESSION_REQ message for %s session %llu to MGMTD Frontend server",
- create ? "creating" : "destroying",
- (unsigned long long)session->client_id);
+ debug_fe_client("Sending SESSION_REQ %s message for client-id %" PRIu64,
+ create ? "create" : "destroy", session->client_id);
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg);
+ return mgmt_fe_client_send_msg(client, &fe_msg, true);
}
-static int
-mgmt_fe_send_lockds_req(struct mgmt_fe_client_ctx *client_ctx,
- struct mgmt_fe_client_session *session, bool lock,
- uint64_t req_id, Mgmtd__DatastoreId ds_id)
+int mgmt_fe_send_lockds_req(struct mgmt_fe_client *client, uint64_t session_id,
+ uint64_t req_id, Mgmtd__DatastoreId ds_id,
+ bool lock, bool scok)
{
(void)req_id;
Mgmtd__FeMessage fe_msg;
Mgmtd__FeLockDsReq lockds_req;
mgmtd__fe_lock_ds_req__init(&lockds_req);
- lockds_req.session_id = session->session_id;
+ lockds_req.session_id = session_id;
lockds_req.req_id = req_id;
lockds_req.ds_id = ds_id;
lockds_req.lock = lock;
@@ -272,17 +181,14 @@ mgmt_fe_send_lockds_req(struct mgmt_fe_client_ctx *client_ctx,
fe_msg.message_case = MGMTD__FE_MESSAGE__MESSAGE_LOCKDS_REQ;
fe_msg.lockds_req = &lockds_req;
- MGMTD_FE_CLIENT_DBG(
- "Sending %sLOCK_REQ message for Ds:%d session %llu to MGMTD Frontend server",
- lock ? "" : "UN", ds_id,
- (unsigned long long)session->client_id);
+ debug_fe_client("Sending LOCKDS_REQ (%sLOCK) message for DS:%s session-id %" PRIu64,
+ lock ? "" : "UN", dsid2name(ds_id), session_id);
+
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg);
+ return mgmt_fe_client_send_msg(client, &fe_msg, scok);
}
-static int
-mgmt_fe_send_setcfg_req(struct mgmt_fe_client_ctx *client_ctx,
- struct mgmt_fe_client_session *session,
+int mgmt_fe_send_setcfg_req(struct mgmt_fe_client *client, uint64_t session_id,
uint64_t req_id, Mgmtd__DatastoreId ds_id,
Mgmtd__YangCfgDataReq **data_req, int num_data_reqs,
bool implicit_commit, Mgmtd__DatastoreId dst_ds_id)
@@ -292,7 +198,7 @@ mgmt_fe_send_setcfg_req(struct mgmt_fe_client_ctx *client_ctx,
Mgmtd__FeSetConfigReq setcfg_req;
mgmtd__fe_set_config_req__init(&setcfg_req);
- setcfg_req.session_id = session->session_id;
+ setcfg_req.session_id = session_id;
setcfg_req.ds_id = ds_id;
setcfg_req.req_id = req_id;
setcfg_req.data = data_req;
@@ -304,26 +210,25 @@ mgmt_fe_send_setcfg_req(struct mgmt_fe_client_ctx *client_ctx,
fe_msg.message_case = MGMTD__FE_MESSAGE__MESSAGE_SETCFG_REQ;
fe_msg.setcfg_req = &setcfg_req;
- MGMTD_FE_CLIENT_DBG(
- "Sending SET_CONFIG_REQ message for Ds:%d session %llu (#xpaths:%d) to MGMTD Frontend server",
- ds_id, (unsigned long long)session->client_id, num_data_reqs);
+ debug_fe_client("Sending SET_CONFIG_REQ message for DS:%s session-id %" PRIu64
+ " (#xpaths:%d)",
+ dsid2name(ds_id), session_id, num_data_reqs);
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg);
+ return mgmt_fe_client_send_msg(client, &fe_msg, false);
}
-static int mgmt_fe_send_commitcfg_req(struct mgmt_fe_client_ctx *client_ctx,
- struct mgmt_fe_client_session *session,
- uint64_t req_id,
- Mgmtd__DatastoreId src_ds_id,
- Mgmtd__DatastoreId dest_ds_id,
- bool validate_only, bool abort)
+int mgmt_fe_send_commitcfg_req(struct mgmt_fe_client *client,
+ uint64_t session_id, uint64_t req_id,
+ Mgmtd__DatastoreId src_ds_id,
+ Mgmtd__DatastoreId dest_ds_id,
+ bool validate_only, bool abort)
{
(void)req_id;
Mgmtd__FeMessage fe_msg;
Mgmtd__FeCommitConfigReq commitcfg_req;
mgmtd__fe_commit_config_req__init(&commitcfg_req);
- commitcfg_req.session_id = session->session_id;
+ commitcfg_req.session_id = session_id;
commitcfg_req.src_ds_id = src_ds_id;
commitcfg_req.dst_ds_id = dest_ds_id;
commitcfg_req.req_id = req_id;
@@ -334,83 +239,52 @@ static int mgmt_fe_send_commitcfg_req(struct mgmt_fe_client_ctx *client_ctx,
fe_msg.message_case = MGMTD__FE_MESSAGE__MESSAGE_COMMCFG_REQ;
fe_msg.commcfg_req = &commitcfg_req;
- MGMTD_FE_CLIENT_DBG(
- "Sending COMMIT_CONFIG_REQ message for Src-Ds:%d, Dst-Ds:%d session %llu to MGMTD Frontend server",
- src_ds_id, dest_ds_id, (unsigned long long)session->client_id);
+ debug_fe_client("Sending COMMIT_CONFIG_REQ message for Src-DS:%s, Dst-DS:%s session-id %" PRIu64,
+ dsid2name(src_ds_id), dsid2name(dest_ds_id), session_id);
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg);
+ return mgmt_fe_client_send_msg(client, &fe_msg, false);
}
-static int
-mgmt_fe_send_getcfg_req(struct mgmt_fe_client_ctx *client_ctx,
- struct mgmt_fe_client_session *session,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- Mgmtd__YangGetDataReq * data_req[],
- int num_data_reqs)
+int mgmt_fe_send_get_req(struct mgmt_fe_client *client, uint64_t session_id,
+ uint64_t req_id, bool is_config,
+ Mgmtd__DatastoreId ds_id,
+ Mgmtd__YangGetDataReq *data_req[], int num_data_reqs)
{
(void)req_id;
Mgmtd__FeMessage fe_msg;
- Mgmtd__FeGetConfigReq getcfg_req;
+ Mgmtd__FeGetReq getcfg_req;
- mgmtd__fe_get_config_req__init(&getcfg_req);
- getcfg_req.session_id = session->session_id;
+ mgmtd__fe_get_req__init(&getcfg_req);
+ getcfg_req.session_id = session_id;
+ getcfg_req.config = is_config;
getcfg_req.ds_id = ds_id;
getcfg_req.req_id = req_id;
getcfg_req.data = data_req;
getcfg_req.n_data = (size_t)num_data_reqs;
mgmtd__fe_message__init(&fe_msg);
- fe_msg.message_case = MGMTD__FE_MESSAGE__MESSAGE_GETCFG_REQ;
- fe_msg.getcfg_req = &getcfg_req;
-
- MGMTD_FE_CLIENT_DBG(
- "Sending GET_CONFIG_REQ message for Ds:%d session %llu (#xpaths:%d) to MGMTD Frontend server",
- ds_id, (unsigned long long)session->client_id, num_data_reqs);
-
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg);
-}
-
-static int
-mgmt_fe_send_getdata_req(struct mgmt_fe_client_ctx *client_ctx,
- struct mgmt_fe_client_session *session,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- Mgmtd__YangGetDataReq * data_req[],
- int num_data_reqs)
-{
- (void)req_id;
- Mgmtd__FeMessage fe_msg;
- Mgmtd__FeGetDataReq getdata_req;
-
- mgmtd__fe_get_data_req__init(&getdata_req);
- getdata_req.session_id = session->session_id;
- getdata_req.ds_id = ds_id;
- getdata_req.req_id = req_id;
- getdata_req.data = data_req;
- getdata_req.n_data = (size_t)num_data_reqs;
-
- mgmtd__fe_message__init(&fe_msg);
- fe_msg.message_case = MGMTD__FE_MESSAGE__MESSAGE_GETDATA_REQ;
- fe_msg.getdata_req = &getdata_req;
+ fe_msg.message_case = MGMTD__FE_MESSAGE__MESSAGE_GET_REQ;
+ fe_msg.get_req = &getcfg_req;
- MGMTD_FE_CLIENT_DBG(
- "Sending GET_CONFIG_REQ message for Ds:%d session %llu (#xpaths:%d) to MGMTD Frontend server",
- ds_id, (unsigned long long)session->client_id, num_data_reqs);
+ debug_fe_client("Sending GET_REQ (iscfg %d) message for DS:%s session-id %" PRIu64
+ " (#xpaths:%d)",
+ is_config, dsid2name(ds_id), session_id, num_data_reqs);
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg);
+ return mgmt_fe_client_send_msg(client, &fe_msg, false);
}
-static int mgmt_fe_send_regnotify_req(
- struct mgmt_fe_client_ctx *client_ctx,
- struct mgmt_fe_client_session *session, uint64_t req_id,
- Mgmtd__DatastoreId ds_id, bool register_req,
- Mgmtd__YangDataXPath * data_req[], int num_data_reqs)
+int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client,
+ uint64_t session_id, uint64_t req_id,
+ Mgmtd__DatastoreId ds_id, bool register_req,
+ Mgmtd__YangDataXPath *data_req[],
+ int num_data_reqs)
{
(void)req_id;
Mgmtd__FeMessage fe_msg;
Mgmtd__FeRegisterNotifyReq regntfy_req;
mgmtd__fe_register_notify_req__init(&regntfy_req);
- regntfy_req.session_id = session->session_id;
+ regntfy_req.session_id = session_id;
regntfy_req.ds_id = ds_id;
regntfy_req.register_req = register_req;
regntfy_req.data_xpath = data_req;
@@ -420,12 +294,44 @@ static int mgmt_fe_send_regnotify_req(
fe_msg.message_case = MGMTD__FE_MESSAGE__MESSAGE_REGNOTIFY_REQ;
fe_msg.regnotify_req = &regntfy_req;
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg);
+ return mgmt_fe_client_send_msg(client, &fe_msg, false);
+}
+
+/*
+ * Send get-data request.
+ */
+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);
+ int ret;
+
+ msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_get_data, xplen + 1,
+ MTYPE_MSG_NATIVE_GET_DATA);
+ msg->refer_id = session_id;
+ msg->req_id = req_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);
+
+ debug_fe_client("Sending GET_DATA_REQ session-id %" PRIu64
+ " req-id %" PRIu64 " xpath: %s",
+ session_id, req_id, xpath);
+
+ ret = mgmt_msg_native_send_msg(&client->client.conn, msg, false);
+ mgmt_msg_native_free_msg(msg);
+ return ret;
}
-static int
-mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
- Mgmtd__FeMessage *fe_msg)
+
+static int mgmt_fe_client_handle_msg(struct mgmt_fe_client *client,
+ Mgmtd__FeMessage *fe_msg)
{
struct mgmt_fe_client_session *session = NULL;
@@ -435,119 +341,92 @@ mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
*/
switch ((int)fe_msg->message_case) {
case MGMTD__FE_MESSAGE__MESSAGE_SESSION_REPLY:
- if (fe_msg->session_reply->create
- && fe_msg->session_reply->has_client_conn_id) {
- MGMTD_FE_CLIENT_DBG(
- "Got Session Create Reply Msg for client-id %llu with session-id: %llu.",
- (unsigned long long)
+ if (fe_msg->session_reply->create &&
+ fe_msg->session_reply->has_client_conn_id) {
+ debug_fe_client("Got SESSION_REPLY (create) for client-id %" PRIu64
+ " with session-id: %" PRIu64,
fe_msg->session_reply->client_conn_id,
- (unsigned long long)
fe_msg->session_reply->session_id);
session = mgmt_fe_find_session_by_client_id(
- client_ctx,
- fe_msg->session_reply->client_conn_id);
+ client, fe_msg->session_reply->client_conn_id);
if (session && fe_msg->session_reply->success) {
- MGMTD_FE_CLIENT_DBG(
- "Session Create for client-id %llu successful.",
- (unsigned long long)
+ debug_fe_client("Session Created for client-id %" PRIu64,
fe_msg->session_reply
->client_conn_id);
session->session_id =
fe_msg->session_reply->session_id;
} else {
- MGMTD_FE_CLIENT_ERR(
- "Session Create for client-id %llu failed.",
- (unsigned long long)
- fe_msg->session_reply
- ->client_conn_id);
+ log_err_fe_client(
+ "Session Create failed for client-id %" PRIu64,
+ fe_msg->session_reply->client_conn_id);
}
} else if (!fe_msg->session_reply->create) {
- MGMTD_FE_CLIENT_DBG(
- "Got Session Destroy Reply Msg for session-id %llu",
- (unsigned long long)
+ debug_fe_client("Got SESSION_REPLY (destroy) for session-id %" PRIu64,
fe_msg->session_reply->session_id);
session = mgmt_fe_find_session_by_session_id(
- client_ctx, fe_msg->session_req->session_id);
+ client, fe_msg->session_req->session_id);
}
- if (session && session->client_ctx
- && session->client_ctx->client_params
- .client_session_notify)
- (*session->client_ctx->client_params
- .client_session_notify)(
- (uintptr_t)client_ctx,
- client_ctx->client_params.user_data,
- session->client_id,
+ /* The session state may be deleted by the callback */
+ if (session && session->client &&
+ session->client->cbs.client_session_notify)
+ (*session->client->cbs.client_session_notify)(
+ client, client->user_data, session->client_id,
fe_msg->session_reply->create,
fe_msg->session_reply->success,
- (uintptr_t)session, session->user_ctx);
+ fe_msg->session_reply->session_id,
+ session->user_ctx);
break;
case MGMTD__FE_MESSAGE__MESSAGE_LOCKDS_REPLY:
- MGMTD_FE_CLIENT_DBG(
- "Got LockDs Reply Msg for session-id %llu",
- (unsigned long long)
+ debug_fe_client("Got LOCKDS_REPLY for session-id %" PRIu64,
fe_msg->lockds_reply->session_id);
session = mgmt_fe_find_session_by_session_id(
- client_ctx, fe_msg->lockds_reply->session_id);
-
- if (session && session->client_ctx
- && session->client_ctx->client_params
- .lock_ds_notify)
- (*session->client_ctx->client_params
- .lock_ds_notify)(
- (uintptr_t)client_ctx,
- client_ctx->client_params.user_data,
- session->client_id, (uintptr_t)session,
- session->user_ctx,
- fe_msg->lockds_reply->req_id,
+ client, fe_msg->lockds_reply->session_id);
+
+ if (session && session->client &&
+ session->client->cbs.lock_ds_notify)
+ (*session->client->cbs.lock_ds_notify)(
+ client, client->user_data, session->client_id,
+ fe_msg->lockds_reply->session_id,
+ session->user_ctx, fe_msg->lockds_reply->req_id,
fe_msg->lockds_reply->lock,
fe_msg->lockds_reply->success,
fe_msg->lockds_reply->ds_id,
fe_msg->lockds_reply->error_if_any);
break;
case MGMTD__FE_MESSAGE__MESSAGE_SETCFG_REPLY:
- MGMTD_FE_CLIENT_DBG(
- "Got Set Config Reply Msg for session-id %llu",
- (unsigned long long)
+ debug_fe_client("Got SETCFG_REPLY for session-id %" PRIu64,
fe_msg->setcfg_reply->session_id);
session = mgmt_fe_find_session_by_session_id(
- client_ctx, fe_msg->setcfg_reply->session_id);
-
- if (session && session->client_ctx
- && session->client_ctx->client_params
- .set_config_notify)
- (*session->client_ctx->client_params
- .set_config_notify)(
- (uintptr_t)client_ctx,
- client_ctx->client_params.user_data,
- session->client_id, (uintptr_t)session,
- session->user_ctx,
- fe_msg->setcfg_reply->req_id,
+ client, fe_msg->setcfg_reply->session_id);
+
+ if (session && session->client &&
+ session->client->cbs.set_config_notify)
+ (*session->client->cbs.set_config_notify)(
+ client, client->user_data, session->client_id,
+ fe_msg->setcfg_reply->session_id,
+ session->user_ctx, fe_msg->setcfg_reply->req_id,
fe_msg->setcfg_reply->success,
fe_msg->setcfg_reply->ds_id,
+ fe_msg->setcfg_reply->implicit_commit,
fe_msg->setcfg_reply->error_if_any);
break;
case MGMTD__FE_MESSAGE__MESSAGE_COMMCFG_REPLY:
- MGMTD_FE_CLIENT_DBG(
- "Got Commit Config Reply Msg for session-id %llu",
- (unsigned long long)
+ debug_fe_client("Got COMMCFG_REPLY for session-id %" PRIu64,
fe_msg->commcfg_reply->session_id);
session = mgmt_fe_find_session_by_session_id(
- client_ctx, fe_msg->commcfg_reply->session_id);
-
- if (session && session->client_ctx
- && session->client_ctx->client_params
- .commit_config_notify)
- (*session->client_ctx->client_params
- .commit_config_notify)(
- (uintptr_t)client_ctx,
- client_ctx->client_params.user_data,
- session->client_id, (uintptr_t)session,
+ client, fe_msg->commcfg_reply->session_id);
+
+ if (session && session->client &&
+ session->client->cbs.commit_config_notify)
+ (*session->client->cbs.commit_config_notify)(
+ client, client->user_data, session->client_id,
+ fe_msg->commcfg_reply->session_id,
session->user_ctx,
fe_msg->commcfg_reply->req_id,
fe_msg->commcfg_reply->success,
@@ -556,72 +435,33 @@ mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
fe_msg->commcfg_reply->validate_only,
fe_msg->commcfg_reply->error_if_any);
break;
- case MGMTD__FE_MESSAGE__MESSAGE_GETCFG_REPLY:
- MGMTD_FE_CLIENT_DBG(
- "Got Get Config Reply Msg for session-id %llu",
- (unsigned long long)
- fe_msg->getcfg_reply->session_id);
-
- session = mgmt_fe_find_session_by_session_id(
- client_ctx, fe_msg->getcfg_reply->session_id);
-
- if (session && session->client_ctx
- && session->client_ctx->client_params
- .get_data_notify)
- (*session->client_ctx->client_params
- .get_data_notify)(
- (uintptr_t)client_ctx,
- client_ctx->client_params.user_data,
- session->client_id, (uintptr_t)session,
- session->user_ctx,
- fe_msg->getcfg_reply->req_id,
- fe_msg->getcfg_reply->success,
- fe_msg->getcfg_reply->ds_id,
- fe_msg->getcfg_reply->data
- ? fe_msg->getcfg_reply->data->data
+ case MGMTD__FE_MESSAGE__MESSAGE_GET_REPLY:
+ debug_fe_client("Got GET_REPLY for session-id %" PRIu64,
+ fe_msg->get_reply->session_id);
+
+ session =
+ mgmt_fe_find_session_by_session_id(client,
+ fe_msg->get_reply
+ ->session_id);
+
+ if (session && session->client &&
+ session->client->cbs.get_data_notify)
+ (*session->client->cbs.get_data_notify)(
+ client, client->user_data, session->client_id,
+ fe_msg->get_reply->session_id,
+ session->user_ctx, fe_msg->get_reply->req_id,
+ fe_msg->get_reply->success,
+ fe_msg->get_reply->ds_id,
+ fe_msg->get_reply->data
+ ? fe_msg->get_reply->data->data
: NULL,
- fe_msg->getcfg_reply->data
- ? fe_msg->getcfg_reply->data->n_data
+ fe_msg->get_reply->data
+ ? fe_msg->get_reply->data->n_data
: 0,
- fe_msg->getcfg_reply->data
- ? fe_msg->getcfg_reply->data
- ->next_indx
+ fe_msg->get_reply->data
+ ? fe_msg->get_reply->data->next_indx
: 0,
- fe_msg->getcfg_reply->error_if_any);
- break;
- case MGMTD__FE_MESSAGE__MESSAGE_GETDATA_REPLY:
- MGMTD_FE_CLIENT_DBG(
- "Got Get Data Reply Msg for session-id %llu",
- (unsigned long long)
- fe_msg->getdata_reply->session_id);
-
- session = mgmt_fe_find_session_by_session_id(
- client_ctx, fe_msg->getdata_reply->session_id);
-
- if (session && session->client_ctx
- && session->client_ctx->client_params
- .get_data_notify)
- (*session->client_ctx->client_params
- .get_data_notify)(
- (uintptr_t)client_ctx,
- client_ctx->client_params.user_data,
- session->client_id, (uintptr_t)session,
- session->user_ctx,
- fe_msg->getdata_reply->req_id,
- fe_msg->getdata_reply->success,
- fe_msg->getdata_reply->ds_id,
- fe_msg->getdata_reply->data
- ? fe_msg->getdata_reply->data->data
- : NULL,
- fe_msg->getdata_reply->data
- ? fe_msg->getdata_reply->data
- ->n_data
- : 0,
- fe_msg->getdata_reply->data
- ? fe_msg->getdata_reply->data
- ->next_indx
- : 0,
- fe_msg->getdata_reply->error_if_any);
+ fe_msg->get_reply->error_if_any);
break;
case MGMTD__FE_MESSAGE__MESSAGE_NOTIFY_DATA_REQ:
case MGMTD__FE_MESSAGE__MESSAGE_REGNOTIFY_REQ:
@@ -638,8 +478,7 @@ mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
case MGMTD__FE_MESSAGE__MESSAGE_LOCKDS_REQ:
case MGMTD__FE_MESSAGE__MESSAGE_SETCFG_REQ:
case MGMTD__FE_MESSAGE__MESSAGE_COMMCFG_REQ:
- case MGMTD__FE_MESSAGE__MESSAGE_GETCFG_REQ:
- case MGMTD__FE_MESSAGE__MESSAGE_GETDATA_REQ:
+ case MGMTD__FE_MESSAGE__MESSAGE_GET_REQ:
case MGMTD__FE_MESSAGE__MESSAGE__NOT_SET:
default:
/*
@@ -654,397 +493,351 @@ mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
return 0;
}
-static void mgmt_fe_client_process_msg(void *user_ctx, uint8_t *data,
- size_t len)
+/*
+ * Handle a native encoded message
+ */
+static void fe_client_handle_native_msg(struct mgmt_fe_client *client,
+ struct mgmt_msg_header *msg,
+ size_t msg_len)
{
- struct mgmt_fe_client_ctx *client_ctx = user_ctx;
- Mgmtd__FeMessage *fe_msg;
-
- fe_msg = mgmtd__fe_message__unpack(NULL, len, data);
- if (!fe_msg) {
- MGMTD_FE_CLIENT_DBG("Failed to decode %zu bytes from server.",
- len);
+ struct mgmt_fe_client_session *session = NULL;
+ struct mgmt_msg_notify_data *notify_msg;
+ struct mgmt_msg_tree_data *tree_msg;
+ struct mgmt_msg_error *err_msg;
+ const char *data = NULL;
+ size_t dlen;
+
+ debug_fe_client("Got native message for session-id %" PRIu64,
+ msg->refer_id);
+
+ session = mgmt_fe_find_session_by_session_id(client, msg->refer_id);
+ if (!session || !session->client) {
+ log_err_fe_client("No session for received native msg session-id %" PRIu64,
+ msg->refer_id);
return;
}
- MGMTD_FE_CLIENT_DBG(
- "Decoded %zu bytes of message(msg: %u/%u) from server", len,
- fe_msg->message_case, fe_msg->message_case);
- (void)mgmt_fe_client_handle_msg(client_ctx, fe_msg);
- mgmtd__fe_message__free_unpacked(fe_msg, NULL);
-}
-static void mgmt_fe_client_proc_msgbufs(struct event *thread)
-{
- struct mgmt_fe_client_ctx *client_ctx;
+ switch (msg->code) {
+ case MGMT_MSG_CODE_ERROR:
+ if (!session->client->cbs.error_notify)
+ return;
- client_ctx = (struct mgmt_fe_client_ctx *)EVENT_ARG(thread);
- if (mgmt_msg_procbufs(&client_ctx->mstate, mgmt_fe_client_process_msg,
- client_ctx, mgmt_debug_fe_client))
- mgmt_fe_client_register_event(client_ctx, MGMTD_FE_PROC_MSG);
-}
+ err_msg = (typeof(err_msg))msg;
+ if (!MGMT_MSG_VALIDATE_NUL_TERM(err_msg, msg_len)) {
+ log_err_fe_client("Corrupt error msg recv");
+ return;
+ }
+ session->client->cbs.error_notify(client, client->user_data,
+ session->client_id,
+ msg->refer_id,
+ session->user_ctx,
+ msg->req_id, err_msg->error,
+ err_msg->errstr);
+ break;
+ case MGMT_MSG_CODE_TREE_DATA:
+ if (!session->client->cbs.get_tree_notify)
+ return;
+
+ tree_msg = (typeof(tree_msg))msg;
+ if (msg_len < sizeof(*tree_msg)) {
+ log_err_fe_client("Corrupt tree-data msg recv");
+ return;
+ }
+ session->client->cbs.get_tree_notify(client, client->user_data,
+ session->client_id,
+ msg->refer_id,
+ session->user_ctx,
+ msg->req_id,
+ MGMTD_DS_OPERATIONAL,
+ tree_msg->result_type,
+ tree_msg->result,
+ msg_len - sizeof(*tree_msg),
+ tree_msg->partial_error);
+ break;
+ case MGMT_MSG_CODE_NOTIFY:
+ if (!session->client->cbs.async_notification)
+ return;
+
+ notify_msg = (typeof(notify_msg))msg;
+ if (msg_len < sizeof(*notify_msg)) {
+ log_err_fe_client("Corrupt notify-data msg recv");
+ return;
+ }
-static void mgmt_fe_client_read(struct event *thread)
-{
- struct mgmt_fe_client_ctx *client_ctx;
- enum mgmt_msg_rsched rv;
+ data = mgmt_msg_native_data_decode(notify_msg, msg_len);
+ if (!data) {
+ log_err_fe_client("Corrupt error msg recv");
+ return;
+ }
+ dlen = mgmt_msg_native_data_len_decode(notify_msg, msg_len);
+ if (notify_msg->result_type != LYD_JSON)
+ data = yang_convert_lyd_format(data, dlen,
+ notify_msg->result_type,
+ LYD_JSON, true);
+ if (!data) {
+ log_err_fe_client("Can't convert format %d to JSON",
+ notify_msg->result_type);
+ return;
+ }
- client_ctx = (struct mgmt_fe_client_ctx *)EVENT_ARG(thread);
+ session->client->cbs.async_notification(client,
+ client->user_data,
+ session->client_id,
+ msg->refer_id,
+ session->user_ctx, data);
- rv = mgmt_msg_read(&client_ctx->mstate, client_ctx->conn_fd,
- mgmt_debug_fe_client);
- if (rv == MSR_DISCONNECT) {
- mgmt_fe_server_disconnect(client_ctx, true);
- return;
+ if (notify_msg->result_type != LYD_JSON)
+ darr_free(data);
+ break;
+ default:
+ log_err_fe_client("unknown native message session-id %" PRIu64
+ " req-id %" PRIu64 " code %u",
+ msg->refer_id, msg->req_id, msg->code);
+ break;
}
- if (rv == MSR_SCHED_BOTH)
- mgmt_fe_client_register_event(client_ctx, MGMTD_FE_PROC_MSG);
- mgmt_fe_client_register_event(client_ctx, MGMTD_FE_CONN_READ);
}
-static void mgmt_fe_server_connect(struct mgmt_fe_client_ctx *client_ctx)
+static void mgmt_fe_client_process_msg(uint8_t version, uint8_t *data,
+ size_t len, struct msg_conn *conn)
{
- const char *dbgtag = mgmt_debug_fe_client ? "FE-client" : NULL;
+ struct mgmt_fe_client *client;
+ struct msg_client *msg_client;
+ Mgmtd__FeMessage *fe_msg;
- assert(client_ctx->conn_fd == -1);
- client_ctx->conn_fd = mgmt_msg_connect(
- MGMTD_FE_SERVER_PATH, MGMTD_SOCKET_FE_SEND_BUF_SIZE,
- MGMTD_SOCKET_FE_RECV_BUF_SIZE, dbgtag);
+ msg_client = container_of(conn, struct msg_client, conn);
+ client = container_of(msg_client, struct mgmt_fe_client, client);
- /* Send REGISTER_REQ message */
- if (client_ctx->conn_fd == -1 ||
- mgmt_fe_send_register_req(client_ctx) != 0) {
- mgmt_fe_server_disconnect(client_ctx, true);
+ if (version == MGMT_MSG_VERSION_NATIVE) {
+ struct mgmt_msg_header *msg = (typeof(msg))data;
+
+ if (len >= sizeof(*msg))
+ fe_client_handle_native_msg(client, msg, len);
+ else
+ log_err_fe_client("native message to FE client %s too short %zu",
+ client->name, len);
return;
}
- /* Start reading from the socket */
- mgmt_fe_client_register_event(client_ctx, MGMTD_FE_CONN_READ);
-
- /* Notify client through registered callback (if any) */
- if (client_ctx->client_params.client_connect_notify)
- (void)(*client_ctx->client_params.client_connect_notify)(
- (uintptr_t)client_ctx,
- client_ctx->client_params.user_data, true);
-}
-
-
-static void mgmt_fe_client_conn_timeout(struct event *thread)
-{
- mgmt_fe_server_connect(EVENT_ARG(thread));
-}
-
-static void
-mgmt_fe_client_register_event(struct mgmt_fe_client_ctx *client_ctx,
- enum mgmt_fe_event event)
-{
- struct timeval tv = {0};
-
- switch (event) {
- case MGMTD_FE_CONN_READ:
- event_add_read(client_ctx->tm, mgmt_fe_client_read,
- client_ctx, client_ctx->conn_fd,
- &client_ctx->conn_read_ev);
- break;
- case MGMTD_FE_CONN_WRITE:
- event_add_write(client_ctx->tm, mgmt_fe_client_write,
- client_ctx, client_ctx->conn_fd,
- &client_ctx->conn_write_ev);
- break;
- case MGMTD_FE_PROC_MSG:
- tv.tv_usec = MGMTD_FE_MSG_PROC_DELAY_USEC;
- event_add_timer_tv(client_ctx->tm,
- mgmt_fe_client_proc_msgbufs, client_ctx,
- &tv, &client_ctx->msg_proc_ev);
- break;
- case MGMTD_FE_CONN_WRITES_ON:
- event_add_timer_msec(
- client_ctx->tm, mgmt_fe_client_resume_writes,
- client_ctx, MGMTD_FE_MSG_WRITE_DELAY_MSEC,
- &client_ctx->conn_writes_on);
- break;
- case MGMTD_FE_SERVER:
- assert(!"mgmt_fe_client_ctx_post_event called incorrectly");
- break;
+ fe_msg = mgmtd__fe_message__unpack(NULL, len, data);
+ if (!fe_msg) {
+ debug_fe_client("Failed to decode %zu bytes from server.", len);
+ return;
}
+ debug_fe_client("Decoded %zu bytes of message(msg: %u/%u) from server",
+ len, fe_msg->message_case, fe_msg->message_case);
+ (void)mgmt_fe_client_handle_msg(client, fe_msg);
+ mgmtd__fe_message__free_unpacked(fe_msg, NULL);
}
-static void mgmt_fe_client_schedule_conn_retry(
- struct mgmt_fe_client_ctx *client_ctx, unsigned long intvl_secs)
+static int _notify_connect_disconnect(struct msg_client *msg_client,
+ bool connected)
{
- MGMTD_FE_CLIENT_DBG(
- "Scheduling MGMTD Frontend server connection retry after %lu seconds",
- intvl_secs);
- event_add_timer(client_ctx->tm, mgmt_fe_client_conn_timeout,
- (void *)client_ctx, intvl_secs,
- &client_ctx->conn_retry_tmr);
-}
+ struct mgmt_fe_client *client =
+ container_of(msg_client, struct mgmt_fe_client, client);
+ struct mgmt_fe_client_session *session;
+ int ret;
-/*
- * Initialize library and try connecting with MGMTD.
- */
-uintptr_t mgmt_fe_client_lib_init(struct mgmt_fe_client_params *params,
- struct event_loop *master_thread)
-{
- assert(master_thread && params && strlen(params->name)
- && !mgmt_fe_client_ctx.tm);
+ /* Send REGISTER_REQ message */
+ if (connected) {
+ if ((ret = mgmt_fe_send_register_req(client)) != 0)
+ return ret;
+ }
- mgmt_fe_client_ctx.tm = master_thread;
- memcpy(&mgmt_fe_client_ctx.client_params, params,
- sizeof(mgmt_fe_client_ctx.client_params));
- if (!mgmt_fe_client_ctx.client_params.conn_retry_intvl_sec)
- mgmt_fe_client_ctx.client_params.conn_retry_intvl_sec =
- MGMTD_FE_DEFAULT_CONN_RETRY_INTVL_SEC;
+ /* Walk list of sessions for this FE client deleting them */
+ if (!connected && mgmt_sessions_count(&client->sessions)) {
+ debug_fe_client("Cleaning up existing sessions");
- mgmt_msg_init(&mgmt_fe_client_ctx.mstate, MGMTD_FE_MAX_NUM_MSG_PROC,
- MGMTD_FE_MAX_NUM_MSG_WRITE, MGMTD_FE_MSG_MAX_LEN,
- "FE-client");
+ FOREACH_SESSION_IN_LIST (client, session) {
+ assert(session->client);
- mgmt_sessions_init(&mgmt_fe_client_ctx.client_sessions);
+ /* unlink from list first this avoids double free */
+ mgmt_sessions_del(&client->sessions, session);
- /* Start trying to connect to MGMTD frontend server immediately */
- mgmt_fe_client_schedule_conn_retry(&mgmt_fe_client_ctx, 1);
+ /* notify FE client the session is being deleted */
+ if (session->client->cbs.client_session_notify) {
+ (*session->client->cbs.client_session_notify)(
+ client, client->user_data,
+ session->client_id, false, true,
+ session->session_id, session->user_ctx);
+ }
- MGMTD_FE_CLIENT_DBG("Initialized client '%s'", params->name);
+ XFREE(MTYPE_MGMTD_FE_SESSION, session);
+ }
+ }
- return (uintptr_t)&mgmt_fe_client_ctx;
+ /* Notify FE client through registered callback (if any). */
+ if (client->cbs.client_connect_notify)
+ (void)(*client->cbs.client_connect_notify)(
+ client, client->user_data, connected);
+ return 0;
}
-/*
- * Create a new Session for a Frontend Client connection.
- */
-enum mgmt_result mgmt_fe_create_client_session(uintptr_t lib_hndl,
- uint64_t client_id,
- uintptr_t user_ctx)
+static int mgmt_fe_client_notify_connect(struct msg_client *client)
{
- struct mgmt_fe_client_ctx *client_ctx;
- struct mgmt_fe_client_session *session;
-
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- session = XCALLOC(MTYPE_MGMTD_FE_SESSION,
- sizeof(struct mgmt_fe_client_session));
- assert(session);
- session->user_ctx = user_ctx;
- session->client_id = client_id;
- session->client_ctx = client_ctx;
- session->session_id = 0;
-
- if (mgmt_fe_send_session_req(client_ctx, session, true) != 0) {
- XFREE(MTYPE_MGMTD_FE_SESSION, session);
- return MGMTD_INTERNAL_ERROR;
- }
- mgmt_sessions_add_tail(&client_ctx->client_sessions, session);
-
- return MGMTD_SUCCESS;
+ return _notify_connect_disconnect(client, true);
}
-/*
- * Delete an existing Session for a Frontend Client connection.
- */
-enum mgmt_result mgmt_fe_destroy_client_session(uintptr_t lib_hndl,
- uint64_t client_id)
+static int mgmt_fe_client_notify_disconnect(struct msg_conn *conn)
{
- struct mgmt_fe_client_ctx *client_ctx;
- struct mgmt_fe_client_session *session;
-
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- session = mgmt_fe_find_session_by_client_id(client_ctx, client_id);
- if (!session || session->client_ctx != client_ctx)
- return MGMTD_INVALID_PARAM;
-
- if (session->session_id &&
- mgmt_fe_send_session_req(client_ctx, session, false) != 0)
- MGMTD_FE_CLIENT_ERR(
- "Failed to send session destroy request for the session-id %lu",
- (unsigned long)session->session_id);
-
- mgmt_sessions_del(&client_ctx->client_sessions, session);
- XFREE(MTYPE_MGMTD_FE_SESSION, session);
+ struct msg_client *client = container_of(conn, struct msg_client, conn);
- return MGMTD_SUCCESS;
+ return _notify_connect_disconnect(client, false);
}
-static void mgmt_fe_destroy_client_sessions(uintptr_t lib_hndl)
+static void mgmt_debug_client_fe_set(uint32_t mode, bool set)
{
- struct mgmt_fe_client_ctx *client_ctx;
- struct mgmt_fe_client_session *session;
+ DEBUG_FLAGS_SET(&mgmt_dbg_fe_client, mode, set);
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
+ if (!__fe_client)
return;
- FOREACH_SESSION_IN_LIST (client_ctx, session)
- mgmt_fe_destroy_client_session(lib_hndl, session->client_id);
+ __fe_client->client.conn.debug = DEBUG_MODE_CHECK(&mgmt_dbg_fe_client,
+ DEBUG_MODE_ALL);
}
-/*
- * Send UN/LOCK_DS_REQ to MGMTD for a specific Datastore DS.
- */
-enum mgmt_result mgmt_fe_lock_ds(uintptr_t lib_hndl, uintptr_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- bool lock_ds)
+DEFPY(debug_mgmt_client_fe, debug_mgmt_client_fe_cmd,
+ "[no] debug mgmt client frontend",
+ NO_STR DEBUG_STR MGMTD_STR
+ "client\n"
+ "frontend\n")
{
- struct mgmt_fe_client_ctx *client_ctx;
- struct mgmt_fe_client_session *session;
+ mgmt_debug_client_fe_set(DEBUG_NODE2MODE(vty->node), !no);
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
+ return CMD_SUCCESS;
+}
- session = (struct mgmt_fe_client_session *)session_id;
- if (!session || session->client_ctx != client_ctx)
- return MGMTD_INVALID_PARAM;
+static int mgmt_debug_fe_client_config_write(struct vty *vty)
+{
+ if (DEBUG_MODE_CHECK(&mgmt_dbg_fe_client, DEBUG_MODE_CONF))
+ vty_out(vty, "debug mgmt client frontend\n");
- if (mgmt_fe_send_lockds_req(client_ctx, session, lock_ds, req_id,
- ds_id)
- != 0)
- return MGMTD_INTERNAL_ERROR;
+ return CMD_SUCCESS;
+}
- return MGMTD_SUCCESS;
+void mgmt_debug_fe_client_show_debug(struct vty *vty)
+{
+ if (debug_check_fe_client())
+ vty_out(vty, "debug mgmt client frontend\n");
}
+static struct debug_callbacks mgmt_dbg_fe_client_cbs = {
+ .debug_set_all = mgmt_debug_client_fe_set
+};
+
+static struct cmd_node mgmt_dbg_node = {
+ .name = "debug mgmt client frontend",
+ .node = MGMT_FE_DEBUG_NODE,
+ .prompt = "",
+ .config_write = mgmt_debug_fe_client_config_write,
+};
+
/*
- * Send SET_CONFIG_REQ to MGMTD for one or more config data(s).
+ * Initialize library and try connecting with MGMTD.
*/
-enum mgmt_result
-mgmt_fe_set_config_data(uintptr_t lib_hndl, uintptr_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- Mgmtd__YangCfgDataReq **config_req, int num_reqs,
- bool implicit_commit, Mgmtd__DatastoreId dst_ds_id)
+struct mgmt_fe_client *mgmt_fe_client_create(const char *client_name,
+ struct mgmt_fe_client_cbs *cbs,
+ uintptr_t user_data,
+ struct event_loop *event_loop)
{
- struct mgmt_fe_client_ctx *client_ctx;
- struct mgmt_fe_client_session *session;
+ struct mgmt_fe_client *client;
+ char server_path[MAXPATHLEN];
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
+ if (__fe_client)
+ return NULL;
- session = (struct mgmt_fe_client_session *)session_id;
- if (!session || session->client_ctx != client_ctx)
- return MGMTD_INVALID_PARAM;
+ client = XCALLOC(MTYPE_MGMTD_FE_CLIENT, sizeof(*client));
+ __fe_client = client;
- if (mgmt_fe_send_setcfg_req(client_ctx, session, req_id, ds_id,
- config_req, num_reqs, implicit_commit,
- dst_ds_id)
- != 0)
- return MGMTD_INTERNAL_ERROR;
+ client->name = XSTRDUP(MTYPE_MGMTD_FE_CLIENT_NAME, client_name);
+ client->user_data = user_data;
+ if (cbs)
+ client->cbs = *cbs;
- return MGMTD_SUCCESS;
-}
+ mgmt_sessions_init(&client->sessions);
-/*
- * Send SET_CONFIG_REQ to MGMTD for one or more config data(s).
- */
-enum mgmt_result mgmt_fe_commit_config_data(uintptr_t lib_hndl,
- uintptr_t session_id,
- uint64_t req_id,
- Mgmtd__DatastoreId src_ds_id,
- Mgmtd__DatastoreId dst_ds_id,
- bool validate_only, bool abort)
-{
- struct mgmt_fe_client_ctx *client_ctx;
- struct mgmt_fe_client_session *session;
+ snprintf(server_path, sizeof(server_path), MGMTD_FE_SOCK_NAME);
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- session = (struct mgmt_fe_client_session *)session_id;
- if (!session || session->client_ctx != client_ctx)
- return MGMTD_INVALID_PARAM;
+ msg_client_init(&client->client, event_loop, server_path,
+ mgmt_fe_client_notify_connect,
+ mgmt_fe_client_notify_disconnect,
+ mgmt_fe_client_process_msg, MGMTD_FE_MAX_NUM_MSG_PROC,
+ MGMTD_FE_MAX_NUM_MSG_WRITE, MGMTD_FE_MAX_MSG_LEN, true,
+ "FE-client", debug_check_fe_client());
- if (mgmt_fe_send_commitcfg_req(client_ctx, session, req_id, src_ds_id,
- dst_ds_id, validate_only, abort)
- != 0)
- return MGMTD_INTERNAL_ERROR;
+ debug_fe_client("Initialized client '%s'", client_name);
- return MGMTD_SUCCESS;
+ return client;
}
-/*
- * Send GET_CONFIG_REQ to MGMTD for one or more config data item(s).
- */
-enum mgmt_result
-mgmt_fe_get_config_data(uintptr_t lib_hndl, uintptr_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- Mgmtd__YangGetDataReq * data_req[], int num_reqs)
+void mgmt_fe_client_lib_vty_init(void)
{
- struct mgmt_fe_client_ctx *client_ctx;
- struct mgmt_fe_client_session *session;
-
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
+ debug_init(&mgmt_dbg_fe_client_cbs);
+ install_node(&mgmt_dbg_node);
+ install_element(ENABLE_NODE, &debug_mgmt_client_fe_cmd);
+ install_element(CONFIG_NODE, &debug_mgmt_client_fe_cmd);
+}
- session = (struct mgmt_fe_client_session *)session_id;
- if (!session || session->client_ctx != client_ctx)
- return MGMTD_INVALID_PARAM;
+uint mgmt_fe_client_session_count(struct mgmt_fe_client *client)
+{
+ return mgmt_sessions_count(&client->sessions);
+}
- if (mgmt_fe_send_getcfg_req(client_ctx, session, req_id, ds_id,
- data_req, num_reqs)
- != 0)
- return MGMTD_INTERNAL_ERROR;
+bool mgmt_fe_client_current_msg_short_circuit(struct mgmt_fe_client *client)
+{
+ return client->client.conn.is_short_circuit;
+}
- return MGMTD_SUCCESS;
+const char *mgmt_fe_client_name(struct mgmt_fe_client *client)
+{
+ return client->name;
}
/*
- * Send GET_DATA_REQ to MGMTD for one or more config data item(s).
+ * Create a new Session for a Frontend Client connection.
*/
-enum mgmt_result mgmt_fe_get_data(uintptr_t lib_hndl, uintptr_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- Mgmtd__YangGetDataReq * data_req[],
- int num_reqs)
+enum mgmt_result mgmt_fe_create_client_session(struct mgmt_fe_client *client,
+ uint64_t client_id,
+ uintptr_t user_ctx)
{
- struct mgmt_fe_client_ctx *client_ctx;
struct mgmt_fe_client_session *session;
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
+ session = XCALLOC(MTYPE_MGMTD_FE_SESSION,
+ sizeof(struct mgmt_fe_client_session));
+ assert(session);
+ session->user_ctx = user_ctx;
+ session->client_id = client_id;
+ session->client = client;
+ session->session_id = 0;
- session = (struct mgmt_fe_client_session *)session_id;
- if (!session || session->client_ctx != client_ctx)
- return MGMTD_INVALID_PARAM;
+ mgmt_sessions_add_tail(&client->sessions, session);
- if (mgmt_fe_send_getdata_req(client_ctx, session, req_id, ds_id,
- data_req, num_reqs)
- != 0)
+ if (mgmt_fe_send_session_req(client, session, true) != 0) {
+ XFREE(MTYPE_MGMTD_FE_SESSION, session);
return MGMTD_INTERNAL_ERROR;
+ }
return MGMTD_SUCCESS;
}
/*
- * Send NOTIFY_REGISTER_REQ to MGMTD daemon.
+ * Delete an existing Session for a Frontend Client connection.
*/
-enum mgmt_result
-mgmt_fe_register_yang_notify(uintptr_t lib_hndl, uintptr_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- bool register_req,
- Mgmtd__YangDataXPath * data_req[],
- int num_reqs)
+enum mgmt_result mgmt_fe_destroy_client_session(struct mgmt_fe_client *client,
+ uint64_t client_id)
{
- struct mgmt_fe_client_ctx *client_ctx;
struct mgmt_fe_client_session *session;
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
+ session = mgmt_fe_find_session_by_client_id(client, client_id);
+ if (!session || session->client != client)
return MGMTD_INVALID_PARAM;
- session = (struct mgmt_fe_client_session *)session_id;
- if (!session || session->client_ctx != client_ctx)
- return MGMTD_INVALID_PARAM;
+ if (session->session_id &&
+ mgmt_fe_send_session_req(client, session, false) != 0)
+ log_err_fe_client("Failed to send session destroy request for the session-id %" PRIu64,
+ session->session_id);
- if (mgmt_fe_send_regnotify_req(client_ctx, session, req_id, ds_id,
- register_req, data_req, num_reqs)
- != 0)
- return MGMTD_INTERNAL_ERROR;
+ mgmt_sessions_del(&client->sessions, session);
+ XFREE(MTYPE_MGMTD_FE_SESSION, session);
return MGMTD_SUCCESS;
}
@@ -1052,24 +845,21 @@ mgmt_fe_register_yang_notify(uintptr_t lib_hndl, uintptr_t session_id,
/*
* Destroy library and cleanup everything.
*/
-void mgmt_fe_client_lib_destroy(uintptr_t lib_hndl)
+void mgmt_fe_client_destroy(struct mgmt_fe_client *client)
{
- struct mgmt_fe_client_ctx *client_ctx;
+ struct mgmt_fe_client_session *session;
+
+ assert(client == __fe_client);
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- assert(client_ctx);
+ debug_fe_client("Destroying MGMTD Frontend Client '%s'", client->name);
- MGMTD_FE_CLIENT_DBG("Destroying MGMTD Frontend Client '%s'",
- client_ctx->client_params.name);
+ FOREACH_SESSION_IN_LIST (client, session)
+ mgmt_fe_destroy_client_session(client, session->client_id);
- mgmt_fe_server_disconnect(client_ctx, false);
+ msg_client_cleanup(&client->client);
- mgmt_fe_destroy_client_sessions(lib_hndl);
+ XFREE(MTYPE_MGMTD_FE_CLIENT_NAME, client->name);
+ XFREE(MTYPE_MGMTD_FE_CLIENT, client);
- EVENT_OFF(client_ctx->conn_retry_tmr);
- EVENT_OFF(client_ctx->conn_read_ev);
- EVENT_OFF(client_ctx->conn_write_ev);
- EVENT_OFF(client_ctx->conn_writes_on);
- EVENT_OFF(client_ctx->msg_proc_ev);
- mgmt_msg_destroy(&client_ctx->mstate);
+ __fe_client = NULL;
}