summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/mgmt_be_client.c410
-rw-r--r--lib/mgmt_be_client.h155
-rw-r--r--lib/mgmt_fe_client.c506
-rw-r--r--lib/mgmt_fe_client.h190
-rw-r--r--lib/mgmt_msg.c6
-rw-r--r--lib/northbound.c7
-rw-r--r--lib/northbound_cli.c13
-rw-r--r--lib/vty.c178
-rw-r--r--lib/vty.h11
9 files changed, 598 insertions, 878 deletions
diff --git a/lib/mgmt_be_client.c b/lib/mgmt_be_client.c
index 534dc43405..fdeff3ec0a 100644
--- a/lib/mgmt_be_client.c
+++ b/lib/mgmt_be_client.c
@@ -20,14 +20,8 @@
#include "lib/mgmt_be_client_clippy.c"
-#define MGMTD_BE_CLIENT_DBG(fmt, ...) \
- DEBUGD(&mgmt_dbg_be_client, "BE-CLIENT: %s:" fmt, __func__, \
- ##__VA_ARGS__)
-#define MGMTD_BE_CLIENT_ERR(fmt, ...) \
- zlog_err("BE-CLIENT: %s: ERROR: " fmt, __func__, ##__VA_ARGS__)
-#define MGMTD_DBG_BE_CLIENT_CHECK() \
- DEBUG_MODE_CHECK(&mgmt_dbg_be_client, DEBUG_MODE_ALL)
-
+DEFINE_MTYPE_STATIC(LIB, MGMTD_BE_CLIENT, "backend client");
+DEFINE_MTYPE_STATIC(LIB, MGMTD_BE_CLIENT_NAME, "backend client name");
DEFINE_MTYPE_STATIC(LIB, MGMTD_BE_BATCH, "backend transaction batch data");
DEFINE_MTYPE_STATIC(LIB, MGMTD_BE_TXN, "backend transaction data");
@@ -70,8 +64,6 @@ struct mgmt_be_batch_ctx {
#define MGMTD_BE_TXN_FLAGS_CFG_APPLIED (1U << 1)
DECLARE_LIST(mgmt_be_batches, struct mgmt_be_batch_ctx, list_linkage);
-struct mgmt_be_client_ctx;
-
PREDECL_LIST(mgmt_be_txns);
struct mgmt_be_txn_ctx {
/* Txn-Id as assigned by MGMTD */
@@ -79,7 +71,7 @@ struct mgmt_be_txn_ctx {
uint32_t flags;
struct mgmt_be_client_txn_ctx client_data;
- struct mgmt_be_client_ctx *client_ctx;
+ struct mgmt_be_client *client;
/* List of batches belonging to this transaction */
struct mgmt_be_batches_head cfg_batches;
@@ -100,9 +92,11 @@ DECLARE_LIST(mgmt_be_txns, struct mgmt_be_txn_ctx, list_linkage);
#define FOREACH_BE_APPLY_BATCH_IN_LIST(txn, batch) \
frr_each_safe (mgmt_be_batches, &(txn)->apply_cfgs, (batch))
-struct mgmt_be_client_ctx {
+struct mgmt_be_client {
struct msg_client client;
+ char *name;
+
struct nb_config *candidate_config;
struct nb_config *running_config;
@@ -114,7 +108,9 @@ struct mgmt_be_client_ctx {
unsigned long avg_apply_nb_cfg_tm;
struct mgmt_be_txns_head txn_head;
- struct mgmt_be_client_params client_params;
+
+ struct mgmt_be_client_cbs cbs;
+ uintptr_t user_data;
};
#define FOREACH_BE_TXN_IN_LIST(client_ctx, txn) \
@@ -122,9 +118,6 @@ struct mgmt_be_client_ctx {
struct debug mgmt_dbg_be_client = {0, "Management backend client operations"};
-static struct mgmt_be_client_ctx mgmt_be_client_ctx = {
- .client = {.conn = {.fd = -1}}};
-
const char *mgmt_be_client_names[MGMTD_BE_CLIENT_ID_MAX + 1] = {
#ifdef HAVE_STATICD
[MGMTD_BE_CLIENT_ID_STATICD] = "staticd",
@@ -132,7 +125,7 @@ const char *mgmt_be_client_names[MGMTD_BE_CLIENT_ID_MAX + 1] = {
[MGMTD_BE_CLIENT_ID_MAX] = "Unknown/Invalid",
};
-static int mgmt_be_client_send_msg(struct mgmt_be_client_ctx *client_ctx,
+static int mgmt_be_client_send_msg(struct mgmt_be_client *client_ctx,
Mgmtd__BeMessage *be_msg)
{
return msg_conn_send_msg(
@@ -216,45 +209,46 @@ static void mgmt_be_cleanup_all_batches(struct mgmt_be_txn_ctx *txn)
}
static struct mgmt_be_txn_ctx *
-mgmt_be_find_txn_by_id(struct mgmt_be_client_ctx *client_ctx,
- uint64_t txn_id)
+mgmt_be_find_txn_by_id(struct mgmt_be_client *client_ctx, uint64_t txn_id,
+ bool warn)
{
struct mgmt_be_txn_ctx *txn = NULL;
- FOREACH_BE_TXN_IN_LIST (client_ctx, txn) {
+ FOREACH_BE_TXN_IN_LIST (client_ctx, txn)
if (txn->txn_id == txn_id)
return txn;
- }
+ if (warn)
+ MGMTD_BE_CLIENT_ERR("Unknown txn-id: %" PRIu64, txn_id);
return NULL;
}
static struct mgmt_be_txn_ctx *
-mgmt_be_txn_create(struct mgmt_be_client_ctx *client_ctx,
- uint64_t txn_id)
+mgmt_be_txn_create(struct mgmt_be_client *client_ctx, uint64_t txn_id)
{
struct mgmt_be_txn_ctx *txn = NULL;
- txn = mgmt_be_find_txn_by_id(client_ctx, txn_id);
- if (!txn) {
- txn = XCALLOC(MTYPE_MGMTD_BE_TXN,
- sizeof(struct mgmt_be_txn_ctx));
- assert(txn);
+ txn = mgmt_be_find_txn_by_id(client_ctx, txn_id, false);
+ if (txn) {
+ MGMTD_BE_CLIENT_ERR("Can't create existing txn-id: %" PRIu64,
+ txn_id);
+ return NULL;
+ }
- txn->txn_id = txn_id;
- txn->client_ctx = client_ctx;
- mgmt_be_batches_init(&txn->cfg_batches);
- mgmt_be_batches_init(&txn->apply_cfgs);
- mgmt_be_txns_add_tail(&client_ctx->txn_head, txn);
+ txn = XCALLOC(MTYPE_MGMTD_BE_TXN, sizeof(struct mgmt_be_txn_ctx));
+ txn->txn_id = txn_id;
+ txn->client = client_ctx;
+ mgmt_be_batches_init(&txn->cfg_batches);
+ mgmt_be_batches_init(&txn->apply_cfgs);
+ mgmt_be_txns_add_tail(&client_ctx->txn_head, txn);
- MGMTD_BE_CLIENT_DBG("Added new txn-id: %" PRIu64, txn_id);
- }
+ MGMTD_BE_CLIENT_DBG("Created new txn-id: %" PRIu64, txn_id);
return txn;
}
-static void mgmt_be_txn_delete(struct mgmt_be_client_ctx *client_ctx,
- struct mgmt_be_txn_ctx **txn)
+static void mgmt_be_txn_delete(struct mgmt_be_client *client_ctx,
+ struct mgmt_be_txn_ctx **txn)
{
char err_msg[] = "MGMT Transaction Delete";
@@ -274,12 +268,10 @@ static void mgmt_be_txn_delete(struct mgmt_be_client_ctx *client_ctx,
* CFGDATA_CREATE_REQs. But first notify the client
* about the transaction delete.
*/
- if (client_ctx->client_params.txn_notify)
- (void)(*client_ctx->client_params
- .txn_notify)(
- (uintptr_t)client_ctx,
- client_ctx->client_params.user_data,
- &(*txn)->client_data, true);
+ if (client_ctx->cbs.txn_notify)
+ (void)(*client_ctx->cbs.txn_notify)(client_ctx,
+ client_ctx->user_data,
+ &(*txn)->client_data, true);
mgmt_be_cleanup_all_batches(*txn);
if ((*txn)->nb_txn)
@@ -290,8 +282,7 @@ static void mgmt_be_txn_delete(struct mgmt_be_client_ctx *client_ctx,
*txn = NULL;
}
-static void
-mgmt_be_cleanup_all_txns(struct mgmt_be_client_ctx *client_ctx)
+static void mgmt_be_cleanup_all_txns(struct mgmt_be_client *client_ctx)
{
struct mgmt_be_txn_ctx *txn = NULL;
@@ -300,9 +291,8 @@ mgmt_be_cleanup_all_txns(struct mgmt_be_client_ctx *client_ctx)
}
}
-static int mgmt_be_send_txn_reply(struct mgmt_be_client_ctx *client_ctx,
- uint64_t txn_id, bool create,
- bool success)
+static int mgmt_be_send_txn_reply(struct mgmt_be_client *client_ctx,
+ uint64_t txn_id, bool create)
{
Mgmtd__BeMessage be_msg;
Mgmtd__BeTxnReply txn_reply;
@@ -310,7 +300,7 @@ static int mgmt_be_send_txn_reply(struct mgmt_be_client_ctx *client_ctx,
mgmtd__be_txn_reply__init(&txn_reply);
txn_reply.create = create;
txn_reply.txn_id = txn_id;
- txn_reply.success = success;
+ txn_reply.success = true;
mgmtd__be_message__init(&be_msg);
be_msg.message_case = MGMTD__BE_MESSAGE__MESSAGE_TXN_REPLY;
@@ -321,57 +311,40 @@ static int mgmt_be_send_txn_reply(struct mgmt_be_client_ctx *client_ctx,
return mgmt_be_client_send_msg(client_ctx, &be_msg);
}
-static int mgmt_be_process_txn_req(struct mgmt_be_client_ctx *client_ctx,
- uint64_t txn_id, bool create)
+static int mgmt_be_process_txn_req(struct mgmt_be_client *client_ctx,
+ uint64_t txn_id, bool create)
{
struct mgmt_be_txn_ctx *txn;
- txn = mgmt_be_find_txn_by_id(client_ctx, txn_id);
if (create) {
- if (txn) {
- /*
- * Transaction with same txn-id already exists.
- * Should not happen under any circumstances.
- */
- MGMTD_BE_CLIENT_ERR(
- "txn-id: %" PRIu64 " already exists", txn_id);
- mgmt_be_send_txn_reply(client_ctx, txn_id, create,
- false);
- }
+ MGMTD_BE_CLIENT_DBG("Creating new txn-id %" PRIu64, txn_id);
- MGMTD_BE_CLIENT_DBG("Created new txn-id %" PRIu64, txn_id);
txn = mgmt_be_txn_create(client_ctx, txn_id);
+ if (!txn)
+ goto failed;
- if (client_ctx->client_params.txn_notify)
- (void)(*client_ctx->client_params
- .txn_notify)(
- (uintptr_t)client_ctx,
- client_ctx->client_params.user_data,
- &txn->client_data, false);
+ if (client_ctx->cbs.txn_notify)
+ (*client_ctx->cbs.txn_notify)(client_ctx,
+ client_ctx->user_data,
+ &txn->client_data, false);
} else {
- if (!txn) {
- /*
- * Transaction with same txn-id does not exists.
- * Return sucess anyways.
- */
- MGMTD_BE_CLIENT_DBG("txn-id: %" PRIu64
- " for delete does NOT exists",
- txn_id);
- } else {
- MGMTD_BE_CLIENT_DBG("Delete txn-id: %" PRIu64, txn_id);
+ MGMTD_BE_CLIENT_DBG("Deleting txn-id: %" PRIu64, txn_id);
+ txn = mgmt_be_find_txn_by_id(client_ctx, txn_id, false);
+ if (txn)
mgmt_be_txn_delete(client_ctx, &txn);
- }
}
- mgmt_be_send_txn_reply(client_ctx, txn_id, create, true);
+ return mgmt_be_send_txn_reply(client_ctx, txn_id, create);
- return 0;
+failed:
+ msg_conn_disconnect(&client_ctx->client.conn, true);
+ return -1;
}
-static int
-mgmt_be_send_cfgdata_create_reply(struct mgmt_be_client_ctx *client_ctx,
- uint64_t txn_id, uint64_t batch_id,
- bool success, const char *error_if_any)
+static int mgmt_be_send_cfgdata_create_reply(struct mgmt_be_client *client_ctx,
+ uint64_t txn_id, uint64_t batch_id,
+ bool success,
+ const char *error_if_any)
{
Mgmtd__BeMessage be_msg;
Mgmtd__BeCfgDataCreateReply cfgdata_reply;
@@ -398,7 +371,7 @@ static void mgmt_be_txn_cfg_abort(struct mgmt_be_txn_ctx *txn)
{
char errmsg[BUFSIZ] = {0};
- assert(txn && txn->client_ctx);
+ assert(txn && txn->client);
if (txn->nb_txn) {
MGMTD_BE_CLIENT_ERR(
"Aborting configs after prep for txn-id: %" PRIu64,
@@ -416,13 +389,13 @@ static void mgmt_be_txn_cfg_abort(struct mgmt_be_txn_ctx *txn)
MGMTD_BE_CLIENT_DBG(
"Reset candidate configurations after abort of txn-id: %" PRIu64,
txn->txn_id);
- nb_config_replace(txn->client_ctx->candidate_config,
- txn->client_ctx->running_config, true);
+ nb_config_replace(txn->client->candidate_config,
+ txn->client->running_config, true);
}
static int mgmt_be_txn_cfg_prepare(struct mgmt_be_txn_ctx *txn)
{
- struct mgmt_be_client_ctx *client_ctx;
+ struct mgmt_be_client *client_ctx;
struct mgmt_be_txn_req *txn_req = NULL;
struct nb_context nb_ctx = {0};
struct timeval edit_nb_cfg_start;
@@ -437,15 +410,15 @@ static int mgmt_be_txn_cfg_prepare(struct mgmt_be_txn_ctx *txn)
size_t num_processed;
int err;
- assert(txn && txn->client_ctx);
- client_ctx = txn->client_ctx;
+ assert(txn && txn->client);
+ client_ctx = txn->client;
num_processed = 0;
FOREACH_BE_TXN_BATCH_IN_LIST (txn, batch) {
txn_req = &batch->txn_req;
error = false;
nb_ctx.client = NB_CLIENT_CLI;
- nb_ctx.user = (void *)client_ctx->client_params.user_data;
+ nb_ctx.user = (void *)client_ctx->user_data;
if (!txn->nb_txn) {
/*
@@ -492,7 +465,7 @@ static int mgmt_be_txn_cfg_prepare(struct mgmt_be_txn_ctx *txn)
* Now prepare all the batches we have applied in one go.
*/
nb_ctx.client = NB_CLIENT_CLI;
- nb_ctx.user = (void *)client_ctx->client_params.user_data;
+ nb_ctx.user = (void *)client_ctx->user_data;
gettimeofday(&prep_nb_cfg_start, NULL);
err = nb_candidate_commit_prepare(nb_ctx, client_ctx->candidate_config,
@@ -556,12 +529,11 @@ static int mgmt_be_txn_cfg_prepare(struct mgmt_be_txn_ctx *txn)
/*
* Process all CFG_DATA_REQs received so far and prepare them all in one go.
*/
-static int
-mgmt_be_update_setcfg_in_batch(struct mgmt_be_client_ctx *client_ctx,
- struct mgmt_be_txn_ctx *txn,
- uint64_t batch_id,
- Mgmtd__YangCfgDataReq * cfg_req[],
- int num_req)
+static int mgmt_be_update_setcfg_in_batch(struct mgmt_be_client *client_ctx,
+ struct mgmt_be_txn_ctx *txn,
+ uint64_t batch_id,
+ Mgmtd__YangCfgDataReq *cfg_req[],
+ int num_req)
{
struct mgmt_be_batch_ctx *batch = NULL;
struct mgmt_be_txn_req *txn_req = NULL;
@@ -611,39 +583,36 @@ mgmt_be_update_setcfg_in_batch(struct mgmt_be_client_ctx *client_ctx,
return 0;
}
-static int
-mgmt_be_process_cfgdata_req(struct mgmt_be_client_ctx *client_ctx,
- uint64_t txn_id, uint64_t batch_id,
- Mgmtd__YangCfgDataReq * cfg_req[], int num_req,
- bool end_of_data)
+static int mgmt_be_process_cfgdata_req(struct mgmt_be_client *client_ctx,
+ uint64_t txn_id, uint64_t batch_id,
+ Mgmtd__YangCfgDataReq *cfg_req[],
+ int num_req, bool end_of_data)
{
struct mgmt_be_txn_ctx *txn;
- txn = mgmt_be_find_txn_by_id(client_ctx, txn_id);
- if (!txn) {
- MGMTD_BE_CLIENT_ERR("Invalid txn-id: %" PRIu64
- " from MGMTD server",
- txn_id);
- mgmt_be_send_cfgdata_create_reply(
- client_ctx, txn_id, batch_id, false,
- "Transaction context not created yet");
- } else {
- mgmt_be_update_setcfg_in_batch(client_ctx, txn, batch_id,
- cfg_req, num_req);
- }
+ txn = mgmt_be_find_txn_by_id(client_ctx, txn_id, true);
+ if (!txn)
+ goto failed;
+
+ mgmt_be_update_setcfg_in_batch(client_ctx, txn, batch_id, cfg_req,
+ num_req);
if (txn && end_of_data) {
- MGMTD_BE_CLIENT_DBG("Triggering CFG_PREPARE_REQ processing");
- mgmt_be_txn_cfg_prepare(txn);
+ MGMTD_BE_CLIENT_DBG("End of data; CFG_PREPARE_REQ processing");
+ if (mgmt_be_txn_cfg_prepare(txn))
+ goto failed;
}
return 0;
+failed:
+ msg_conn_disconnect(&client_ctx->client.conn, true);
+ return -1;
}
-static int mgmt_be_send_apply_reply(struct mgmt_be_client_ctx *client_ctx,
- uint64_t txn_id, uint64_t batch_ids[],
- size_t num_batch_ids, bool success,
- const char *error_if_any)
+static int mgmt_be_send_apply_reply(struct mgmt_be_client *client_ctx,
+ uint64_t txn_id, uint64_t batch_ids[],
+ size_t num_batch_ids, bool success,
+ const char *error_if_any)
{
Mgmtd__BeMessage be_msg;
Mgmtd__BeCfgDataApplyReply apply_reply;
@@ -673,7 +642,7 @@ static int mgmt_be_send_apply_reply(struct mgmt_be_client_ctx *client_ctx,
static int mgmt_be_txn_proc_cfgapply(struct mgmt_be_txn_ctx *txn)
{
- struct mgmt_be_client_ctx *client_ctx;
+ struct mgmt_be_client *client_ctx;
struct timeval apply_nb_cfg_start;
struct timeval apply_nb_cfg_end;
unsigned long apply_nb_cfg_tm;
@@ -682,8 +651,8 @@ static int mgmt_be_txn_proc_cfgapply(struct mgmt_be_txn_ctx *txn)
size_t num_processed;
static uint64_t batch_ids[MGMTD_BE_MAX_BATCH_IDS_IN_REQ];
- assert(txn && txn->client_ctx);
- client_ctx = txn->client_ctx;
+ assert(txn && txn->client);
+ client_ctx = txn->client;
assert(txn->nb_txn);
num_processed = 0;
@@ -735,30 +704,33 @@ static int mgmt_be_txn_proc_cfgapply(struct mgmt_be_txn_ctx *txn)
return 0;
}
-static int
-mgmt_be_process_cfg_apply(struct mgmt_be_client_ctx *client_ctx,
- uint64_t txn_id)
+static int mgmt_be_process_cfg_apply(struct mgmt_be_client *client_ctx,
+ uint64_t txn_id)
{
struct mgmt_be_txn_ctx *txn;
- txn = mgmt_be_find_txn_by_id(client_ctx, txn_id);
- if (!txn) {
- mgmt_be_send_apply_reply(client_ctx, txn_id, NULL, 0, false,
- "Transaction not created yet!");
- return -1;
- }
+ txn = mgmt_be_find_txn_by_id(client_ctx, txn_id, true);
+ if (!txn)
+ goto failed;
MGMTD_BE_CLIENT_DBG("Trigger CFG_APPLY_REQ processing");
- mgmt_be_txn_proc_cfgapply(txn);
+ if (mgmt_be_txn_proc_cfgapply(txn))
+ goto failed;
return 0;
+failed:
+ msg_conn_disconnect(&client_ctx->client.conn, true);
+ return -1;
}
-static int
-mgmt_be_client_handle_msg(struct mgmt_be_client_ctx *client_ctx,
- Mgmtd__BeMessage *be_msg)
+
+static int mgmt_be_client_handle_msg(struct mgmt_be_client *client_ctx,
+ Mgmtd__BeMessage *be_msg)
{
/*
+ * On error we may have closed the connection so don't do anything with
+ * the client_ctx on return.
+ *
* protobuf-c adds a max size enum with an internal, and changing by
* version, name; cast to an int to avoid unhandled enum warnings
*/
@@ -833,12 +805,12 @@ mgmt_be_client_handle_msg(struct mgmt_be_client_ctx *client_ctx,
static void mgmt_be_client_process_msg(uint8_t version, uint8_t *data,
size_t len, struct msg_conn *conn)
{
- struct mgmt_be_client_ctx *client_ctx;
+ struct mgmt_be_client *client_ctx;
struct msg_client *client;
Mgmtd__BeMessage *be_msg;
client = container_of(conn, struct msg_client, conn);
- client_ctx = container_of(client, struct mgmt_be_client_ctx, client);
+ client_ctx = container_of(client, struct mgmt_be_client, client);
be_msg = mgmtd__be_message__unpack(NULL, len, data);
if (!be_msg) {
@@ -853,17 +825,17 @@ static void mgmt_be_client_process_msg(uint8_t version, uint8_t *data,
mgmtd__be_message__free_unpacked(be_msg, NULL);
}
-static int mgmt_be_send_subscr_req(struct mgmt_be_client_ctx *client_ctx,
- bool subscr_xpaths, uint16_t num_reg_xpaths,
- char **reg_xpaths)
+int mgmt_be_send_subscr_req(struct mgmt_be_client *client_ctx,
+ bool subscr_xpaths, int num_xpaths,
+ char **reg_xpaths)
{
Mgmtd__BeMessage be_msg;
Mgmtd__BeSubscribeReq subscr_req;
mgmtd__be_subscribe_req__init(&subscr_req);
- subscr_req.client_name = client_ctx->client_params.name;
- subscr_req.n_xpath_reg = num_reg_xpaths;
- if (num_reg_xpaths)
+ subscr_req.client_name = client_ctx->name;
+ subscr_req.n_xpath_reg = num_xpaths;
+ if (num_xpaths)
subscr_req.xpath_reg = reg_xpaths;
else
subscr_req.xpath_reg = NULL;
@@ -881,24 +853,29 @@ static int mgmt_be_send_subscr_req(struct mgmt_be_client_ctx *client_ctx,
return mgmt_be_client_send_msg(client_ctx, &be_msg);
}
-static int _notify_conenct_disconnect(struct msg_client *client, bool connected)
+static int _notify_conenct_disconnect(struct msg_client *msg_client,
+ bool connected)
{
- struct mgmt_be_client_ctx *client_ctx =
- container_of(client, struct mgmt_be_client_ctx, client);
+ struct mgmt_be_client *client =
+ container_of(msg_client, struct mgmt_be_client, client);
int ret;
if (connected) {
- assert(client->conn.fd != -1);
- ret = mgmt_be_send_subscr_req(client_ctx, false, 0, NULL);
+ assert(msg_client->conn.fd != -1);
+ ret = mgmt_be_send_subscr_req(client, false, 0, NULL);
if (ret)
return ret;
}
/* Notify BE 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, connected);
+ if (client->cbs.client_connect_notify)
+ (void)(*client->cbs.client_connect_notify)(
+ client, client->user_data, connected);
+
+ /* Cleanup any in-progress TXN on disconnect */
+ if (!connected)
+ mgmt_be_cleanup_all_txns(client);
+
return 0;
}
@@ -914,6 +891,10 @@ static int mgmt_be_client_notify_disconenct(struct msg_conn *conn)
return _notify_conenct_disconnect(client, false);
}
+/*
+ * Debug Flags
+ */
+
DEFPY(debug_mgmt_client_be, debug_mgmt_client_be_cmd,
"[no] debug mgmt client backend",
NO_STR DEBUG_STR MGMTD_STR
@@ -956,32 +937,33 @@ static struct cmd_node mgmt_dbg_node = {
.config_write = mgmt_debug_be_client_config_write,
};
-/*
- * Initialize library and try connecting with MGMTD.
- */
-uintptr_t mgmt_be_client_lib_init(struct mgmt_be_client_params *params,
- struct event_loop *master_thread)
+struct mgmt_be_client *mgmt_be_client_create(const char *client_name,
+ struct mgmt_be_client_cbs *cbs,
+ uintptr_t user_data,
+ struct event_loop *event_loop)
{
- /* Don't call twice */
- assert(!mgmt_be_client_ctx.client.conn.loop);
+ struct mgmt_be_client *client =
+ XCALLOC(MTYPE_MGMTD_BE_CLIENT, sizeof(*client));
/* Only call after frr_init() */
assert(running_config);
- mgmt_be_client_ctx.running_config = running_config;
- mgmt_be_client_ctx.candidate_config = nb_config_new(NULL);
- mgmt_be_client_ctx.client_params = *params;
- mgmt_be_txns_init(&mgmt_be_client_ctx.txn_head);
- msg_client_init(&mgmt_be_client_ctx.client, master_thread,
- MGMTD_BE_SERVER_PATH, mgmt_be_client_notify_conenct,
+ client->name = XSTRDUP(MTYPE_MGMTD_BE_CLIENT_NAME, client_name);
+ client->running_config = running_config;
+ client->candidate_config = nb_config_new(NULL);
+ if (cbs)
+ client->cbs = *cbs;
+ mgmt_be_txns_init(&client->txn_head);
+ msg_client_init(&client->client, event_loop, MGMTD_BE_SERVER_PATH,
+ mgmt_be_client_notify_conenct,
mgmt_be_client_notify_disconenct,
mgmt_be_client_process_msg, MGMTD_BE_MAX_NUM_MSG_PROC,
MGMTD_BE_MAX_NUM_MSG_WRITE, MGMTD_BE_MSG_MAX_LEN, false,
"BE-client", MGMTD_DBG_BE_CLIENT_CHECK());
- MGMTD_BE_CLIENT_DBG("Initialized client '%s'", params->name);
+ MGMTD_BE_CLIENT_DBG("Initialized client '%s'", client_name);
- return (uintptr_t)&mgmt_be_client_ctx;
+ return client;
}
@@ -993,86 +975,16 @@ void mgmt_be_client_lib_vty_init(void)
install_element(CONFIG_NODE, &debug_mgmt_client_be_cmd);
}
-
-/*
- * Subscribe with MGMTD for one or more YANG subtree(s).
- */
-enum mgmt_result mgmt_be_subscribe_yang_data(uintptr_t lib_hndl,
- char *reg_yang_xpaths[],
- int num_reg_xpaths)
+void mgmt_be_client_destroy(struct mgmt_be_client *client)
{
- struct mgmt_be_client_ctx *client_ctx;
-
- if (!num_reg_xpaths)
- return MGMTD_SUCCESS;
-
- client_ctx = (struct mgmt_be_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- if (mgmt_be_send_subscr_req(client_ctx, true, num_reg_xpaths,
- reg_yang_xpaths)
- != 0)
- return MGMTD_INTERNAL_ERROR;
-
- return MGMTD_SUCCESS;
-}
-
-/*
- * Unsubscribe with MGMTD for one or more YANG subtree(s).
- */
-enum mgmt_result mgmt_be_unsubscribe_yang_data(uintptr_t lib_hndl,
- char *reg_yang_xpaths[],
- int num_reg_xpaths)
-{
- struct mgmt_be_client_ctx *client_ctx;
-
- if (!num_reg_xpaths)
- return MGMTD_SUCCESS;
-
- client_ctx = (struct mgmt_be_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
-
- if (mgmt_be_send_subscr_req(client_ctx, false, num_reg_xpaths,
- reg_yang_xpaths)
- < 0)
- return MGMTD_INTERNAL_ERROR;
-
- return MGMTD_SUCCESS;
-}
-
-/*
- * Send one or more YANG notifications to MGMTD daemon.
- */
-enum mgmt_result mgmt_be_send_yang_notify(uintptr_t lib_hndl,
- Mgmtd__YangData * data_elems[],
- int num_elems)
-{
- struct mgmt_be_client_ctx *client_ctx;
-
- client_ctx = (struct mgmt_be_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- return MGMTD_SUCCESS;
-}
-
-/*
- * Destroy library and cleanup everything.
- */
-void mgmt_be_client_lib_destroy(void)
-{
- struct mgmt_be_client_ctx *client_ctx = &mgmt_be_client_ctx;
-
MGMTD_BE_CLIENT_DBG("Destroying MGMTD Backend Client '%s'",
- client_ctx->client_params.name);
+ client->name);
- msg_client_cleanup(&client_ctx->client);
- mgmt_be_cleanup_all_txns(client_ctx);
- mgmt_be_txns_fini(&client_ctx->txn_head);
- nb_config_free(client_ctx->candidate_config);
+ msg_client_cleanup(&client->client);
+ mgmt_be_cleanup_all_txns(client);
+ mgmt_be_txns_fini(&client->txn_head);
+ nb_config_free(client->candidate_config);
- memset(client_ctx, 0, sizeof(*client_ctx));
+ XFREE(MTYPE_MGMTD_BE_CLIENT_NAME, client->name);
+ XFREE(MTYPE_MGMTD_BE_CLIENT, client);
}
diff --git a/lib/mgmt_be_client.h b/lib/mgmt_be_client.h
index bbe938b5b4..4ad5ca5957 100644
--- a/lib/mgmt_be_client.h
+++ b/lib/mgmt_be_client.h
@@ -82,67 +82,26 @@ enum mgmt_be_client_id {
#define MGMTD_BE_MAX_CLIENTS_PER_XPATH_REG 32
+struct mgmt_be_client;
+
struct mgmt_be_client_txn_ctx {
uintptr_t *user_ctx;
};
-/*
- * All the client-specific information this library needs to
- * initialize itself, setup connection with MGMTD BackEnd interface
- * and carry on all required procedures appropriately.
+/**
+ * Backend client callbacks.
*
- * BackEnd clients need to initialise a instance of this structure
- * with appropriate data and pass it while calling the API
- * to initialize the library (See mgmt_be_client_lib_init for
- * more details).
+ * Callbacks:
+ * client_connect_notify: called when connection is made/lost to mgmtd.
+ * txn_notify: called when a txn has been created
*/
-struct mgmt_be_client_params {
- char name[MGMTD_CLIENT_NAME_MAX_LEN];
- uintptr_t user_data;
- unsigned long conn_retry_intvl_sec;
-
- void (*client_connect_notify)(uintptr_t lib_hndl,
- uintptr_t usr_data,
- bool connected);
-
- void (*client_subscribe_notify)(
- uintptr_t lib_hndl, uintptr_t usr_data,
- struct nb_yang_xpath **xpath,
- enum mgmt_result subscribe_result[], int num_paths);
-
- void (*txn_notify)(
- uintptr_t lib_hndl, uintptr_t usr_data,
- struct mgmt_be_client_txn_ctx *txn_ctx, bool destroyed);
-
- enum mgmt_result (*data_validate)(
- uintptr_t lib_hndl, uintptr_t usr_data,
- struct mgmt_be_client_txn_ctx *txn_ctx,
- struct nb_yang_xpath *xpath, struct nb_yang_value *data,
- bool delete, char *error_if_any);
-
- enum mgmt_result (*data_apply)(
- uintptr_t lib_hndl, uintptr_t usr_data,
- struct mgmt_be_client_txn_ctx *txn_ctx,
- struct nb_yang_xpath *xpath, struct nb_yang_value *data,
- bool delete);
-
- enum mgmt_result (*get_data_elem)(
- uintptr_t lib_hndl, uintptr_t usr_data,
- struct mgmt_be_client_txn_ctx *txn_ctx,
- struct nb_yang_xpath *xpath, struct nb_yang_xpath_elem *elem);
-
- enum mgmt_result (*get_data)(
- uintptr_t lib_hndl, uintptr_t usr_data,
- struct mgmt_be_client_txn_ctx *txn_ctx,
- struct nb_yang_xpath *xpath, bool keys_only,
- struct nb_yang_xpath_elem **elems, int *num_elems,
- int *next_key);
-
- enum mgmt_result (*get_next_data)(
- uintptr_t lib_hndl, uintptr_t usr_data,
- struct mgmt_be_client_txn_ctx *txn_ctx,
- struct nb_yang_xpath *xpath, bool keys_only,
- struct nb_yang_xpath_elem **elems, int *num_elems);
+struct mgmt_be_client_cbs {
+ void (*client_connect_notify)(struct mgmt_be_client *client,
+ uintptr_t usr_data, bool connected);
+
+ void (*txn_notify)(struct mgmt_be_client *client, uintptr_t usr_data,
+ struct mgmt_be_client_txn_ctx *txn_ctx,
+ bool destroyed);
};
/***************************************************************
@@ -172,24 +131,34 @@ mgmt_be_client_name2id(const char *name)
return MGMTD_BE_CLIENT_ID_MAX;
}
+extern struct debug mgmt_dbg_be_client;
+
/***************************************************************
* API prototypes
***************************************************************/
-/*
- * Initialize library and try connecting with MGMTD.
- *
- * params
- * Backend client parameters.
+#define MGMTD_BE_CLIENT_DBG(fmt, ...) \
+ DEBUGD(&mgmt_dbg_be_client, "BE-CLIENT: %s: " fmt, __func__, \
+ ##__VA_ARGS__)
+#define MGMTD_BE_CLIENT_ERR(fmt, ...) \
+ zlog_err("BE-CLIENT: %s: ERROR: " fmt, __func__, ##__VA_ARGS__)
+#define MGMTD_DBG_BE_CLIENT_CHECK() \
+ DEBUG_MODE_CHECK(&mgmt_dbg_be_client, DEBUG_MODE_ALL)
+
+/**
+ * Create backend client and connect to MGMTD.
*
- * master_thread
- * Thread master.
+ * Args:
+ * client_name: the name of the client
+ * cbs: callbacks for various events.
+ * event_loop: the main event loop.
*
* Returns:
- * Backend client lib handler (nothing but address of mgmt_be_client_ctx)
+ * Backend client object.
*/
-extern uintptr_t mgmt_be_client_lib_init(struct mgmt_be_client_params *params,
- struct event_loop *master_thread);
+extern struct mgmt_be_client *
+mgmt_be_client_create(const char *name, struct mgmt_be_client_cbs *cbs,
+ uintptr_t user_data, struct event_loop *event_loop);
/*
* Initialize library vty (adds debug support).
@@ -206,13 +175,13 @@ extern void mgmt_be_client_lib_vty_init(void);
extern void mgmt_debug_be_client_show_debug(struct vty *vty);
/*
- * Subscribe with MGMTD for one or more YANG subtree(s).
+ * [Un]-subscribe with MGMTD for one or more YANG subtree(s).
*
- * lib_hndl
- * Client library handler.
+ * client
+ * The client object.
*
* reg_yang_xpaths
- * Yang xpath(s) that needs to be subscribed to.
+ * Yang xpath(s) that needs to be [un]-subscribed from/to
*
* num_xpaths
* Number of xpaths
@@ -220,52 +189,14 @@ extern void mgmt_debug_be_client_show_debug(struct vty *vty);
* Returns:
* MGMTD_SUCCESS on success, MGMTD_* otherwise.
*/
-extern enum mgmt_result mgmt_be_subscribe_yang_data(uintptr_t lib_hndl,
- char **reg_yang_xpaths,
- int num_xpaths);
-
-/*
- * Send one or more YANG notifications to MGMTD daemon.
- *
- * lib_hndl
- * Client library handler.
- *
- * data_elems
- * Yang data elements from data tree.
- *
- * num_elems
- * Number of data elements.
- *
- * Returns:
- * MGMTD_SUCCESS on success, MGMTD_* otherwise.
- */
-extern enum mgmt_result
-mgmt_be_send_yang_notify(uintptr_t lib_hndl, Mgmtd__YangData **data_elems,
- int num_elems);
-
-/*
- * Un-subscribe with MGMTD for one or more YANG subtree(s).
- *
- * lib_hndl
- * Client library handler.
- *
- * reg_yang_xpaths
- * Yang xpath(s) that needs to be un-subscribed from.
- *
- * num_reg_xpaths
- * Number of subscribed xpaths
- *
- * Returns:
- * MGMTD_SUCCESS on success, MGMTD_* otherwise.
- */
-enum mgmt_result mgmt_be_unsubscribe_yang_data(uintptr_t lib_hndl,
- char **reg_yang_xpaths,
- int num_reg_xpaths);
+extern int mgmt_be_send_subscr_req(struct mgmt_be_client *client,
+ bool subscr_xpaths, int num_xpaths,
+ char **reg_xpaths);
/*
- * Destroy library and cleanup everything.
+ * Destroy backend client and cleanup everything.
*/
-extern void mgmt_be_client_lib_destroy(void);
+extern void mgmt_be_client_destroy(struct mgmt_be_client *client);
#ifdef __cplusplus
}
diff --git a/lib/mgmt_fe_client.c b/lib/mgmt_fe_client.c
index 83f60ea58b..be7263f21b 100644
--- a/lib/mgmt_fe_client.c
+++ b/lib/mgmt_fe_client.c
@@ -19,14 +19,12 @@
#include "lib/mgmt_fe_client_clippy.c"
-struct mgmt_fe_client_ctx;
-
PREDECL_LIST(mgmt_sessions);
struct mgmt_fe_client_session {
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_ctx *client_ctx;
+ struct mgmt_fe_client *client;
uintptr_t user_ctx;
struct mgmt_sessions_item list_linkage;
@@ -34,29 +32,47 @@ 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 {
+struct mgmt_fe_client {
struct msg_client client;
- struct mgmt_fe_client_params client_params;
- struct mgmt_sessions_head client_sessions;
+ char *name;
+ struct mgmt_fe_client_cbs cbs;
+ uintptr_t user_data;
+ struct mgmt_sessions_head sessions;
};
-#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))
struct debug mgmt_dbg_fe_client = {0, "Management frontend client operations"};
-static struct mgmt_fe_client_ctx mgmt_fe_client_ctx = {
- .client = {.conn = {.fd = -1}}};
+
+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,
+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-id %" PRIu64
" using client-id %" PRIu64,
@@ -70,12 +86,12 @@ mgmt_fe_find_session_by_client_id(struct mgmt_fe_client_ctx *client_ctx,
}
static struct mgmt_fe_client_session *
-mgmt_fe_find_session_by_session_id(struct mgmt_fe_client_ctx *client_ctx,
+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 of client-id %" PRIu64
@@ -89,24 +105,24 @@ mgmt_fe_find_session_by_session_id(struct mgmt_fe_client_ctx *client_ctx,
return NULL;
}
-static int mgmt_fe_client_send_msg(struct mgmt_fe_client_ctx *client_ctx,
+static int mgmt_fe_client_send_msg(struct mgmt_fe_client *client,
Mgmtd__FeMessage *fe_msg,
bool short_circuit_ok)
{
return msg_conn_send_msg(
- &client_ctx->client.conn, MGMT_MSG_VERSION_PROTOBUF, fe_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,
short_circuit_ok);
}
-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;
@@ -115,27 +131,24 @@ static int mgmt_fe_send_register_req(struct mgmt_fe_client_ctx *client_ctx)
MGMTD_FE_CLIENT_DBG(
"Sending REGISTER_REQ message to MGMTD Frontend server");
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg, true);
+ return mgmt_fe_client_send_msg(client, &fe_msg, true);
}
-static int mgmt_fe_send_session_req(struct mgmt_fe_client_ctx *client_ctx,
+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;
- bool scok;
mgmtd__fe_session_req__init(&sess_req);
sess_req.create = create;
if (create) {
sess_req.id_case = MGMTD__FE_SESSION_REQ__ID_CLIENT_CONN_ID;
sess_req.client_conn_id = session->client_id;
- scok = true;
} else {
sess_req.id_case = MGMTD__FE_SESSION_REQ__ID_SESSION_ID;
sess_req.session_id = session->session_id;
- scok = false;
}
mgmtd__fe_message__init(&fe_msg);
@@ -146,12 +159,12 @@ static int mgmt_fe_send_session_req(struct mgmt_fe_client_ctx *client_ctx,
"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, scok);
+ return mgmt_fe_client_send_msg(client, &fe_msg, true);
}
-static int mgmt_fe_send_lockds_req(struct mgmt_fe_client_ctx *client_ctx,
- uint64_t session_id, 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)
{
(void)req_id;
Mgmtd__FeMessage fe_msg;
@@ -168,18 +181,17 @@ static int mgmt_fe_send_lockds_req(struct mgmt_fe_client_ctx *client_ctx,
fe_msg.lockds_req = &lockds_req;
MGMTD_FE_CLIENT_DBG(
- "Sending %sLOCK_REQ message for Ds:%d session-id %" PRIu64,
- lock ? "" : "UN", ds_id, session_id);
+ "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, false);
+
+ return mgmt_fe_client_send_msg(client, &fe_msg, false);
}
-static int mgmt_fe_send_setcfg_req(struct mgmt_fe_client_ctx *client_ctx,
- 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)
+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)
{
(void)req_id;
Mgmtd__FeMessage fe_msg;
@@ -199,18 +211,18 @@ static int mgmt_fe_send_setcfg_req(struct mgmt_fe_client_ctx *client_ctx,
fe_msg.setcfg_req = &setcfg_req;
MGMTD_FE_CLIENT_DBG(
- "Sending SET_CONFIG_REQ message for Ds:%d session-id %" PRIu64
+ "Sending SET_CONFIG_REQ message for DS:%s session-id %" PRIu64
" (#xpaths:%d)",
- ds_id, session_id, num_data_reqs);
+ dsid2name(ds_id), session_id, num_data_reqs);
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg, false);
+ return mgmt_fe_client_send_msg(client, &fe_msg, false);
}
-static int mgmt_fe_send_commitcfg_req(struct mgmt_fe_client_ctx *client_ctx,
- uint64_t session_id, 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;
@@ -229,17 +241,16 @@ static int mgmt_fe_send_commitcfg_req(struct mgmt_fe_client_ctx *client_ctx,
fe_msg.commcfg_req = &commitcfg_req;
MGMTD_FE_CLIENT_DBG(
- "Sending COMMIT_CONFIG_REQ message for Src-Ds:%d, Dst-Ds:%d session-id %" PRIu64,
- src_ds_id, dest_ds_id, session_id);
+ "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, false);
+ return mgmt_fe_client_send_msg(client, &fe_msg, false);
}
-static int mgmt_fe_send_getcfg_req(struct mgmt_fe_client_ctx *client_ctx,
- uint64_t session_id, uint64_t req_id,
- Mgmtd__DatastoreId ds_id,
- Mgmtd__YangGetDataReq *data_req[],
- int num_data_reqs)
+int mgmt_fe_send_getcfg_req(struct mgmt_fe_client *client, uint64_t session_id,
+ uint64_t req_id, Mgmtd__DatastoreId ds_id,
+ Mgmtd__YangGetDataReq *data_req[],
+ int num_data_reqs)
{
(void)req_id;
Mgmtd__FeMessage fe_msg;
@@ -257,18 +268,17 @@ static int mgmt_fe_send_getcfg_req(struct mgmt_fe_client_ctx *client_ctx,
fe_msg.getcfg_req = &getcfg_req;
MGMTD_FE_CLIENT_DBG(
- "Sending GET_CONFIG_REQ message for Ds:%d session-id %" PRIu64
+ "Sending GET_CONFIG_REQ message for DS:%s session-id %" PRIu64
" (#xpaths:%d)",
- ds_id, session_id, num_data_reqs);
+ dsid2name(ds_id), session_id, num_data_reqs);
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg, false);
+ return mgmt_fe_client_send_msg(client, &fe_msg, false);
}
-static int mgmt_fe_send_getdata_req(struct mgmt_fe_client_ctx *client_ctx,
- uint64_t session_id, uint64_t req_id,
- Mgmtd__DatastoreId ds_id,
- Mgmtd__YangGetDataReq *data_req[],
- int num_data_reqs)
+int mgmt_fe_send_getdata_req(struct mgmt_fe_client *client, uint64_t session_id,
+ uint64_t req_id, Mgmtd__DatastoreId ds_id,
+ Mgmtd__YangGetDataReq *data_req[],
+ int num_data_reqs)
{
(void)req_id;
Mgmtd__FeMessage fe_msg;
@@ -286,19 +296,18 @@ static int mgmt_fe_send_getdata_req(struct mgmt_fe_client_ctx *client_ctx,
fe_msg.getdata_req = &getdata_req;
MGMTD_FE_CLIENT_DBG(
- "Sending GET_CONFIG_REQ message for Ds:%d session-id %" PRIu64
+ "Sending GET_CONFIG_REQ message for DS:%s session-id %" PRIu64
" (#xpaths:%d)",
- ds_id, session_id, num_data_reqs);
+ dsid2name(ds_id), session_id, num_data_reqs);
- return mgmt_fe_client_send_msg(client_ctx, &fe_msg, false);
+ return mgmt_fe_client_send_msg(client, &fe_msg, false);
}
-static int mgmt_fe_send_regnotify_req(struct mgmt_fe_client_ctx *client_ctx,
- uint64_t session_id, 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;
@@ -315,10 +324,10 @@ static int mgmt_fe_send_regnotify_req(struct mgmt_fe_client_ctx *client_ctx,
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, false);
+ return mgmt_fe_client_send_msg(client, &fe_msg, false);
}
-static int mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
+static int mgmt_fe_client_handle_msg(struct mgmt_fe_client *client,
Mgmtd__FeMessage *fe_msg)
{
struct mgmt_fe_client_session *session = NULL;
@@ -338,8 +347,7 @@ static int mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
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(
@@ -358,17 +366,14 @@ static int mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
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);
}
/* The session state may be deleted by the callback */
- 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,
+ 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,
fe_msg->session_reply->session_id,
@@ -378,14 +383,12 @@ static int mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
MGMTD_FE_CLIENT_DBG("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,
+ 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,
@@ -398,14 +401,12 @@ static int mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
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,
+ 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,
@@ -417,15 +418,12 @@ static int mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
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,
+ 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,
@@ -440,14 +438,12 @@ static int mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
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,
+ client, fe_msg->getcfg_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->getcfg_reply->session_id,
session->user_ctx, fe_msg->getcfg_reply->req_id,
fe_msg->getcfg_reply->success,
@@ -468,14 +464,12 @@ static int mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
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,
+ client, fe_msg->getdata_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->getdata_reply->session_id,
session->user_ctx,
fe_msg->getdata_reply->req_id,
@@ -526,12 +520,12 @@ static int mgmt_fe_client_handle_msg(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)
{
- struct mgmt_fe_client_ctx *client_ctx;
- struct msg_client *client;
+ struct mgmt_fe_client *client;
+ struct msg_client *msg_client;
Mgmtd__FeMessage *fe_msg;
- client = container_of(conn, struct msg_client, conn);
- client_ctx = container_of(client, struct mgmt_fe_client_ctx, client);
+ msg_client = container_of(conn, struct msg_client, conn);
+ client = container_of(msg_client, struct mgmt_fe_client, client);
fe_msg = mgmtd__fe_message__unpack(NULL, len, data);
if (!fe_msg) {
@@ -542,41 +536,38 @@ static void mgmt_fe_client_process_msg(uint8_t version, uint8_t *data,
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);
+ (void)mgmt_fe_client_handle_msg(client, fe_msg);
mgmtd__fe_message__free_unpacked(fe_msg, NULL);
}
-static int _notify_connect_disconnect(struct msg_client *client, bool connected)
+static int _notify_connect_disconnect(struct msg_client *msg_client,
+ bool connected)
{
- struct mgmt_fe_client_ctx *client_ctx =
- container_of(client, struct mgmt_fe_client_ctx, client);
+ struct mgmt_fe_client *client =
+ container_of(msg_client, struct mgmt_fe_client, client);
struct mgmt_fe_client_session *session;
int ret;
/* Send REGISTER_REQ message */
if (connected) {
- if ((ret = mgmt_fe_send_register_req(client_ctx)) != 0)
+ if ((ret = mgmt_fe_send_register_req(client)) != 0)
return ret;
}
/* Walk list of sessions for this FE client deleting them */
- if (!connected && mgmt_sessions_count(&client_ctx->client_sessions)) {
+ if (!connected && mgmt_sessions_count(&client->sessions)) {
MGMTD_FE_CLIENT_DBG("Cleaning up existing sessions");
- FOREACH_SESSION_IN_LIST (client_ctx, session) {
- assert(session->client_ctx);
+ FOREACH_SESSION_IN_LIST (client, session) {
+ assert(session->client);
/* unlink from list first this avoids double free */
- mgmt_sessions_del(&client_ctx->client_sessions,
- session);
+ mgmt_sessions_del(&client->sessions, session);
/* notify FE client the session is being deleted */
- if (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,
+ 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);
}
@@ -586,10 +577,9 @@ static int _notify_connect_disconnect(struct msg_client *client, bool connected)
}
/* Notify FE 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, connected);
+ if (client->cbs.client_connect_notify)
+ (void)(*client->cbs.client_connect_notify)(
+ client, client->user_data, connected);
return 0;
}
@@ -651,26 +641,31 @@ static struct cmd_node mgmt_dbg_node = {
/*
* 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)
+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)
{
- /* Don't call twice */
- assert(!mgmt_fe_client_ctx.client.conn.loop);
+ struct mgmt_fe_client *client =
+ XCALLOC(MTYPE_MGMTD_FE_CLIENT, sizeof(*client));
- mgmt_fe_client_ctx.client_params = *params;
+ client->name = XSTRDUP(MTYPE_MGMTD_FE_CLIENT_NAME, client_name);
+ client->user_data = user_data;
+ if (cbs)
+ client->cbs = *cbs;
- mgmt_sessions_init(&mgmt_fe_client_ctx.client_sessions);
+ mgmt_sessions_init(&client->sessions);
- msg_client_init(&mgmt_fe_client_ctx.client, master_thread,
- MGMTD_FE_SERVER_PATH, mgmt_fe_client_notify_connect,
+ msg_client_init(&client->client, event_loop, MGMTD_FE_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_MSG_MAX_LEN, true,
"FE-client", MGMTD_DBG_FE_CLIENT_CHECK());
- MGMTD_FE_CLIENT_DBG("Initialized client '%s'", params->name);
+ MGMTD_FE_CLIENT_DBG("Initialized client '%s'", client_name);
- return (uintptr_t)&mgmt_fe_client_ctx;
+ return client;
}
void mgmt_fe_client_lib_vty_init(void)
@@ -681,39 +676,31 @@ void mgmt_fe_client_lib_vty_init(void)
install_element(CONFIG_NODE, &debug_mgmt_client_fe_cmd);
}
-uint mgmt_fe_client_session_count(uintptr_t lib_hndl)
+uint mgmt_fe_client_session_count(struct mgmt_fe_client *client)
{
- struct mgmt_fe_client_ctx *client_ctx =
- (struct mgmt_fe_client_ctx *)lib_hndl;
-
- return mgmt_sessions_count(&client_ctx->client_sessions);
+ return mgmt_sessions_count(&client->sessions);
}
/*
* Create a new Session for a Frontend Client connection.
*/
-enum mgmt_result mgmt_fe_create_client_session(uintptr_t lib_hndl,
+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_ctx = client_ctx;
+ session->client = client;
session->session_id = 0;
- mgmt_sessions_add_tail(&client_ctx->client_sessions, session);
+ mgmt_sessions_add_tail(&client->sessions, session);
- if (mgmt_fe_send_session_req(client_ctx, session, true) != 0) {
+ if (mgmt_fe_send_session_req(client, session, true) != 0) {
XFREE(MTYPE_MGMTD_FE_SESSION, session);
return MGMTD_INTERNAL_ERROR;
}
@@ -724,189 +711,42 @@ enum mgmt_result mgmt_fe_create_client_session(uintptr_t lib_hndl,
/*
* Delete an existing Session for a Frontend Client connection.
*/
-enum mgmt_result mgmt_fe_destroy_client_session(uintptr_t lib_hndl,
+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)
- return MGMTD_INVALID_PARAM;
-
- session = mgmt_fe_find_session_by_client_id(client_ctx, client_id);
- if (!session || session->client_ctx != client_ctx)
+ session = mgmt_fe_find_session_by_client_id(client, client_id);
+ if (!session || session->client != client)
return MGMTD_INVALID_PARAM;
if (session->session_id &&
- mgmt_fe_send_session_req(client_ctx, session, false) != 0)
+ mgmt_fe_send_session_req(client, session, false) != 0)
MGMTD_FE_CLIENT_ERR(
"Failed to send session destroy request for the session-id %" PRIu64,
session->session_id);
- mgmt_sessions_del(&client_ctx->client_sessions, session);
+ mgmt_sessions_del(&client->sessions, session);
XFREE(MTYPE_MGMTD_FE_SESSION, session);
return MGMTD_SUCCESS;
}
-static void mgmt_fe_destroy_client_sessions(uintptr_t lib_hndl)
-{
- 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;
-
- FOREACH_SESSION_IN_LIST (client_ctx, session)
- mgmt_fe_destroy_client_session(lib_hndl, session->client_id);
-}
-
-/*
- * Send UN/LOCK_DS_REQ to MGMTD for a specific Datastore DS.
- */
-enum mgmt_result mgmt_fe_lock_ds(uintptr_t lib_hndl, uint64_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- bool lock_ds)
-{
- struct mgmt_fe_client_ctx *client_ctx;
-
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- if (mgmt_fe_send_lockds_req(client_ctx, session_id, lock_ds, req_id,
- ds_id) != 0)
- return MGMTD_INTERNAL_ERROR;
-
- return MGMTD_SUCCESS;
-}
-
-/*
- * Send SET_CONFIG_REQ to MGMTD for one or more config data(s).
- */
-enum mgmt_result mgmt_fe_set_config_data(uintptr_t lib_hndl,
- uint64_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_ctx *client_ctx;
-
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- if (mgmt_fe_send_setcfg_req(client_ctx, session_id, req_id, ds_id,
- config_req, num_reqs, implicit_commit,
- dst_ds_id) != 0)
- return MGMTD_INTERNAL_ERROR;
-
- return MGMTD_SUCCESS;
-}
-
-/*
- * 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,
- uint64_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;
-
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- if (mgmt_fe_send_commitcfg_req(client_ctx, session_id, req_id,
- src_ds_id, dst_ds_id, validate_only,
- abort) != 0)
- return MGMTD_INTERNAL_ERROR;
-
- return MGMTD_SUCCESS;
-}
-
-/*
- * 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,
- uint64_t session_id, uint64_t req_id,
- Mgmtd__DatastoreId ds_id,
- Mgmtd__YangGetDataReq *data_req[],
- int num_reqs)
-{
- struct mgmt_fe_client_ctx *client_ctx;
-
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- if (mgmt_fe_send_getcfg_req(client_ctx, session_id, req_id, ds_id,
- data_req, num_reqs) != 0)
- return MGMTD_INTERNAL_ERROR;
-
- return MGMTD_SUCCESS;
-}
-
-/*
- * Send GET_DATA_REQ to MGMTD for one or more config data item(s).
- */
-enum mgmt_result mgmt_fe_get_data(uintptr_t lib_hndl, uint64_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- Mgmtd__YangGetDataReq *data_req[],
- int num_reqs)
-{
- struct mgmt_fe_client_ctx *client_ctx;
-
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- if (mgmt_fe_send_getdata_req(client_ctx, session_id, req_id, ds_id,
- data_req, num_reqs) != 0)
- return MGMTD_INTERNAL_ERROR;
-
- return MGMTD_SUCCESS;
-}
-
-/*
- * Send NOTIFY_REGISTER_REQ to MGMTD daemon.
- */
-enum mgmt_result
-mgmt_fe_register_yang_notify(uintptr_t lib_hndl, uint64_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- bool register_req,
- Mgmtd__YangDataXPath *data_req[], int num_reqs)
-{
- struct mgmt_fe_client_ctx *client_ctx;
-
- client_ctx = (struct mgmt_fe_client_ctx *)lib_hndl;
- if (!client_ctx)
- return MGMTD_INVALID_PARAM;
-
- if (mgmt_fe_send_regnotify_req(client_ctx, session_id, req_id, ds_id,
- register_req, data_req, num_reqs) != 0)
- return MGMTD_INTERNAL_ERROR;
-
- return MGMTD_SUCCESS;
-}
-
/*
* Destroy library and cleanup everything.
*/
-void mgmt_fe_client_lib_destroy(void)
+void mgmt_fe_client_destroy(struct mgmt_fe_client *client)
{
- struct mgmt_fe_client_ctx *client_ctx = &mgmt_fe_client_ctx;
+ struct mgmt_fe_client_session *session;
MGMTD_FE_CLIENT_DBG("Destroying MGMTD Frontend Client '%s'",
- client_ctx->client_params.name);
+ client->name);
+
+ FOREACH_SESSION_IN_LIST (client, session)
+ mgmt_fe_destroy_client_session(client, session->client_id);
+
+ msg_client_cleanup(&client->client);
- mgmt_fe_destroy_client_sessions((uintptr_t)client_ctx);
- msg_client_cleanup(&client_ctx->client);
- memset(client_ctx, 0, sizeof(*client_ctx));
+ XFREE(MTYPE_MGMTD_FE_CLIENT_NAME, client->name);
+ XFREE(MTYPE_MGMTD_FE_CLIENT, client);
}
diff --git a/lib/mgmt_fe_client.h b/lib/mgmt_fe_client.h
index 7ce6c5eef5..b0ac44bb3e 100644
--- a/lib/mgmt_fe_client.h
+++ b/lib/mgmt_fe_client.h
@@ -56,6 +56,9 @@ extern "C" {
#define MGMTD_DS_OPERATIONAL MGMTD__DATASTORE_ID__OPERATIONAL_DS
#define MGMTD_DS_MAX_ID MGMTD_DS_OPERATIONAL + 1
+struct mgmt_fe_client;
+
+
/*
* All the client specific information this library needs to
* initialize itself, setup connection with MGMTD FrontEnd interface
@@ -66,69 +69,68 @@ extern "C" {
* to initialize the library (See mgmt_fe_client_lib_init for
* more details).
*/
-struct mgmt_fe_client_params {
- char name[MGMTD_CLIENT_NAME_MAX_LEN];
- uintptr_t user_data;
- unsigned long conn_retry_intvl_sec;
-
- void (*client_connect_notify)(uintptr_t lib_hndl,
- uintptr_t user_data,
- bool connected);
-
- void (*client_session_notify)(uintptr_t lib_hndl,
- uintptr_t user_data,
- uint64_t client_id,
+struct mgmt_fe_client_cbs {
+ void (*client_connect_notify)(struct mgmt_fe_client *client,
+ uintptr_t user_data, bool connected);
+
+ void (*client_session_notify)(struct mgmt_fe_client *client,
+ uintptr_t user_data, uint64_t client_id,
bool create, bool success,
uintptr_t session_id,
- uintptr_t user_session_ctx);
+ uintptr_t user_session_client);
- void (*lock_ds_notify)(uintptr_t lib_hndl, uintptr_t user_data,
- uint64_t client_id, uintptr_t session_id,
- uintptr_t user_session_ctx, uint64_t req_id,
+ void (*lock_ds_notify)(struct mgmt_fe_client *client,
+ uintptr_t user_data, uint64_t client_id,
+ uintptr_t session_id,
+ uintptr_t user_session_client, uint64_t req_id,
bool lock_ds, bool success,
Mgmtd__DatastoreId ds_id, char *errmsg_if_any);
- void (*set_config_notify)(uintptr_t lib_hndl, uintptr_t user_data,
- uint64_t client_id, uintptr_t session_id,
- uintptr_t user_session_ctx, uint64_t req_id,
- bool success, Mgmtd__DatastoreId ds_id,
+ void (*set_config_notify)(struct mgmt_fe_client *client,
+ uintptr_t user_data, uint64_t client_id,
+ uintptr_t session_id,
+ uintptr_t user_session_client,
+ uint64_t req_id, bool success,
+ Mgmtd__DatastoreId ds_id,
char *errmsg_if_any);
- void (*commit_config_notify)(
- uintptr_t lib_hndl, uintptr_t user_data, uint64_t client_id,
- uintptr_t session_id, uintptr_t user_session_ctx,
- uint64_t req_id, bool success, Mgmtd__DatastoreId src_ds_id,
- Mgmtd__DatastoreId dst_ds_id, bool validate_only,
- char *errmsg_if_any);
-
- enum mgmt_result (*get_data_notify)(
- uintptr_t lib_hndl, uintptr_t user_data, uint64_t client_id,
- uintptr_t session_id, uintptr_t user_session_ctx,
- uint64_t req_id, bool success, Mgmtd__DatastoreId ds_id,
- Mgmtd__YangData **yang_data, size_t num_data, int next_key,
- char *errmsg_if_any);
-
- enum mgmt_result (*data_notify)(
- uint64_t client_id, uint64_t session_id, uintptr_t user_data,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- Mgmtd__YangData **yang_data, size_t num_data);
+ void (*commit_config_notify)(struct mgmt_fe_client *client,
+ uintptr_t user_data, uint64_t client_id,
+ uintptr_t session_id,
+ uintptr_t user_session_client,
+ uint64_t req_id, bool success,
+ Mgmtd__DatastoreId src_ds_id,
+ Mgmtd__DatastoreId dst_ds_id,
+ bool validate_only, char *errmsg_if_any);
+
+ int (*get_data_notify)(struct mgmt_fe_client *client,
+ uintptr_t user_data, uint64_t client_id,
+ uintptr_t session_id,
+ uintptr_t user_session_client, uint64_t req_id,
+ bool success, Mgmtd__DatastoreId ds_id,
+ Mgmtd__YangData **yang_data, size_t num_data,
+ int next_key, char *errmsg_if_any);
+
+ int (*data_notify)(uint64_t client_id, uint64_t session_id,
+ uintptr_t user_data, uint64_t req_id,
+ Mgmtd__DatastoreId ds_id,
+ Mgmtd__YangData **yang_data, size_t num_data);
};
extern struct debug mgmt_dbg_fe_client;
+/***************************************************************
+ * API prototypes
+ ***************************************************************/
+
#define MGMTD_FE_CLIENT_DBG(fmt, ...) \
- DEBUGD(&mgmt_dbg_fe_client, "FE-CLIENT: %s:" fmt, __func__, \
+ DEBUGD(&mgmt_dbg_fe_client, "FE-CLIENT: %s: " fmt, __func__, \
##__VA_ARGS__)
#define MGMTD_FE_CLIENT_ERR(fmt, ...) \
zlog_err("FE-CLIENT: %s: ERROR: " fmt, __func__, ##__VA_ARGS__)
#define MGMTD_DBG_FE_CLIENT_CHECK() \
DEBUG_MODE_CHECK(&mgmt_dbg_fe_client, DEBUG_MODE_ALL)
-
-/***************************************************************
- * API prototypes
- ***************************************************************/
-
/*
* Initialize library and try connecting with MGMTD FrontEnd interface.
*
@@ -139,17 +141,18 @@ extern struct debug mgmt_dbg_fe_client;
* Thread master.
*
* Returns:
- * Frontend client lib handler (nothing but address of mgmt_fe_client_ctx)
+ * Frontend client lib handler (nothing but address of mgmt_fe_client)
*/
-extern uintptr_t mgmt_fe_client_lib_init(struct mgmt_fe_client_params *params,
- struct event_loop *master_thread);
+extern 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);
/*
* Initialize library vty (adds debug support).
*
- * This call should be added to your component when enabling other vty code to
- * enable mgmtd client debugs. When adding, one needs to also add a their
- * component in `xref2vtysh.py` as well.
+ * This call should be added to your component when enabling other vty
+ * code to enable mgmtd client debugs. When adding, one needs to also
+ * add a their component in `xref2vtysh.py` as well.
*/
extern void mgmt_fe_client_lib_vty_init(void);
@@ -167,15 +170,15 @@ extern void mgmt_debug_fe_client_show_debug(struct vty *vty);
* client_id
* Unique identifier of client.
*
- * user_ctx
+ * user_client
* Client context.
*
* Returns:
* MGMTD_SUCCESS on success, MGMTD_* otherwise.
*/
-extern enum mgmt_result mgmt_fe_create_client_session(uintptr_t lib_hndl,
- uint64_t client_id,
- uintptr_t user_ctx);
+extern enum mgmt_result
+mgmt_fe_create_client_session(struct mgmt_fe_client *client, uint64_t client_id,
+ uintptr_t user_client);
/*
* Delete an existing Session for a Frontend Client connection.
@@ -187,10 +190,11 @@ extern enum mgmt_result mgmt_fe_create_client_session(uintptr_t lib_hndl,
* Unique identifier of client.
*
* Returns:
- * MGMTD_SUCCESS on success, MGMTD_* otherwise.
+ * 0 on success, otherwise msg_conn_send_msg() return values.
*/
-extern enum mgmt_result mgmt_fe_destroy_client_session(uintptr_t lib_hndl,
- uint64_t client_id);
+extern enum mgmt_result
+mgmt_fe_destroy_client_session(struct mgmt_fe_client *client,
+ uint64_t client_id);
/*
* Send UN/LOCK_DS_REQ to MGMTD for a specific Datastore DS.
@@ -211,11 +215,11 @@ extern enum mgmt_result mgmt_fe_destroy_client_session(uintptr_t lib_hndl,
* TRUE for lock request, FALSE for unlock request.
*
* Returns:
- * MGMTD_SUCCESS on success, MGMTD_* otherwise.
+ * 0 on success, otherwise msg_conn_send_msg() return values.
*/
-extern enum mgmt_result mgmt_fe_lock_ds(uintptr_t lib_hndl, uint64_t session_id,
- uint64_t req_id,
- Mgmtd__DatastoreId ds_id, bool lock_ds);
+extern 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_ds);
/*
* Send SET_CONFIG_REQ to MGMTD for one or more config data(s).
@@ -245,13 +249,15 @@ extern enum mgmt_result mgmt_fe_lock_ds(uintptr_t lib_hndl, uint64_t session_id,
* Destination Datastore ID where data needs to be set.
*
* Returns:
- * MGMTD_SUCCESS on success, MGMTD_* otherwise.
+ * 0 on success, otherwise msg_conn_send_msg() return values.
*/
-extern enum mgmt_result
-mgmt_fe_set_config_data(uintptr_t lib_hndl, uint64_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- Mgmtd__YangCfgDataReq **config_req, int num_req,
- bool implicit_commit, Mgmtd__DatastoreId dst_ds_id);
+
+extern 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 **config_req,
+ int num_req, bool implicit_commit,
+ Mgmtd__DatastoreId dst_ds_id);
/*
* Send SET_COMMMIT_REQ to MGMTD for one or more config data(s).
@@ -278,13 +284,13 @@ mgmt_fe_set_config_data(uintptr_t lib_hndl, uint64_t session_id,
* TRUE if need to restore Src DS back to Dest DS, FALSE otherwise.
*
* Returns:
- * MGMTD_SUCCESS on success, MGMTD_* otherwise.
+ * 0 on success, otherwise msg_conn_send_msg() return values.
*/
-extern enum mgmt_result
-mgmt_fe_commit_config_data(uintptr_t lib_hndl, uint64_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId src_ds_id,
- Mgmtd__DatastoreId dst_ds_id, bool validate_only,
- bool abort);
+extern 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 dst_ds_id,
+ bool validate_only, bool abort);
/*
* Send GET_CONFIG_REQ to MGMTD for one or more config data item(s).
@@ -308,12 +314,13 @@ mgmt_fe_commit_config_data(uintptr_t lib_hndl, uint64_t session_id,
* Number of get config requests.
*
* Returns:
- * MGMTD_SUCCESS on success, MGMTD_* otherwise.
+ * 0 on success, otherwise msg_conn_send_msg() return values.
*/
-extern enum mgmt_result
-mgmt_fe_get_config_data(uintptr_t lib_hndl, uint64_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- Mgmtd__YangGetDataReq **data_req, int num_reqs);
+extern int mgmt_fe_send_getcfg_req(struct mgmt_fe_client *client,
+ uint64_t session_id, uint64_t req_id,
+ Mgmtd__DatastoreId ds_id,
+ Mgmtd__YangGetDataReq **data_req,
+ int num_reqs);
/*
* Send GET_DATA_REQ to MGMTD for one or more data item(s).
@@ -321,11 +328,11 @@ mgmt_fe_get_config_data(uintptr_t lib_hndl, uint64_t session_id,
* Similar to get config request but supports getting data
* from operational ds aka backend clients directly.
*/
-extern enum mgmt_result mgmt_fe_get_data(uintptr_t lib_hndl,
- uint64_t session_id, uint64_t req_id,
- Mgmtd__DatastoreId ds_id,
- Mgmtd__YangGetDataReq **data_req,
- int num_reqs);
+extern int mgmt_fe_send_getdata_req(struct mgmt_fe_client *client,
+ uint64_t session_id, uint64_t req_id,
+ Mgmtd__DatastoreId ds_id,
+ Mgmtd__YangGetDataReq **data_req,
+ int num_reqs);
/*
* Send NOTIFY_REGISTER_REQ to MGMTD daemon.
@@ -352,23 +359,24 @@ extern enum mgmt_result mgmt_fe_get_data(uintptr_t lib_hndl,
* Number of data requests.
*
* Returns:
- * MGMTD_SUCCESS on success, MGMTD_* otherwise.
+ * 0 on success, otherwise msg_conn_send_msg() return values.
*/
-extern enum mgmt_result
-mgmt_fe_register_yang_notify(uintptr_t lib_hndl, uint64_t session_id,
- uint64_t req_id, Mgmtd__DatastoreId ds_id,
- bool register_req, Mgmtd__YangDataXPath **data_req,
- int num_reqs);
+extern 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_reqs);
/*
* Destroy library and cleanup everything.
*/
-extern void mgmt_fe_client_lib_destroy(void);
+extern void mgmt_fe_client_destroy(struct mgmt_fe_client *client);
/*
* Get count of open sessions.
*/
-extern uint mgmt_fe_client_session_count(uintptr_t lib_hndl);
+extern uint mgmt_fe_client_session_count(struct mgmt_fe_client *client);
#ifdef __cplusplus
}
diff --git a/lib/mgmt_msg.c b/lib/mgmt_msg.c
index 0d9802a2b3..ba69c20aba 100644
--- a/lib/mgmt_msg.c
+++ b/lib/mgmt_msg.c
@@ -59,11 +59,12 @@ enum mgmt_msg_rsched mgmt_msg_read(struct mgmt_msg_state *ms, int fd,
*/
while (avail > sizeof(struct mgmt_msg_hdr)) {
n = stream_read_try(ms->ins, fd, avail);
- MGMT_MSG_DBG(dbgtag, "got %zd bytes", n);
/* -2 is normal nothing read, and to retry */
- if (n == -2)
+ if (n == -2) {
+ MGMT_MSG_DBG(dbgtag, "nothing more to read");
break;
+ }
if (n <= 0) {
if (n == 0)
MGMT_MSG_ERR(ms, "got EOF/disconnect");
@@ -73,6 +74,7 @@ enum mgmt_msg_rsched mgmt_msg_read(struct mgmt_msg_state *ms, int fd,
safe_strerror(errno));
return MSR_DISCONNECT;
}
+ MGMT_MSG_DBG(dbgtag, "read %zd bytes", n);
ms->nrxb += n;
avail -= n;
}
diff --git a/lib/northbound.c b/lib/northbound.c
index 775f6ff92f..ef2344ee11 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -792,18 +792,19 @@ static void nb_update_candidate_changes(struct nb_config *candidate,
LYD_TREE_DFS_BEGIN (root, dnode) {
op = nb_lyd_diff_get_op(dnode);
switch (op) {
- case 'c':
+ case 'c': /* create */
nb_config_diff_created(dnode, seq, cfg_chgs);
LYD_TREE_DFS_continue = 1;
break;
- case 'd':
+ case 'd': /* delete */
nb_config_diff_deleted(dnode, seq, cfg_chgs);
LYD_TREE_DFS_continue = 1;
break;
- case 'r':
+ case 'r': /* replace */
nb_config_diff_add_change(cfg_chgs, NB_OP_MODIFY, seq,
dnode);
break;
+ case 'n': /* none */
default:
break;
}
diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c
index e9c89d2029..9d6ec66689 100644
--- a/lib/northbound_cli.c
+++ b/lib/northbound_cli.c
@@ -202,7 +202,7 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...)
return CMD_SUCCESS;
implicit_commit = vty_needs_implicit_commit(vty);
- ret = vty_mgmt_send_config_data(vty);
+ ret = vty_mgmt_send_config_data(vty, implicit_commit);
if (ret >= 0 && !implicit_commit)
vty->mgmt_num_pending_setcfg++;
return ret;
@@ -229,9 +229,16 @@ int nb_cli_apply_changes_clear_pending(struct vty *vty,
if (vty_mgmt_should_process_cli_apply_changes(vty)) {
VTY_CHECK_XPATH;
-
+ /*
+ * The legacy user wanted to clear pending (i.e., perform a
+ * commit immediately) due to some non-yang compatible
+ * functionality. This new mgmtd code however, continues to send
+ * changes putting off the commit until XFRR_end is received
+ * (i.e., end-of-config-file). This should be fine b/c all
+ * conversions to mgmtd require full proper implementations.
+ */
implicit_commit = vty_needs_implicit_commit(vty);
- ret = vty_mgmt_send_config_data(vty);
+ ret = vty_mgmt_send_config_data(vty, implicit_commit);
if (ret >= 0 && !implicit_commit)
vty->mgmt_num_pending_setcfg++;
return ret;
diff --git a/lib/vty.c b/lib/vty.c
index 4cf63508bf..fd00e11c5f 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -68,7 +68,7 @@ enum vty_event {
struct nb_config *vty_mgmt_candidate_config;
-static uintptr_t mgmt_lib_hndl;
+static struct mgmt_fe_client *mgmt_fe_client;
static bool mgmt_fe_connected;
static bool mgmt_candidate_ds_wr_locked;
static uint64_t mgmt_client_id_next;
@@ -134,18 +134,22 @@ void vty_mgmt_resume_response(struct vty *vty, bool success)
uint8_t header[4] = {0, 0, 0, 0};
int ret = CMD_SUCCESS;
- if (!vty->mgmt_req_pending) {
+ if (!vty->mgmt_req_pending_cmd) {
zlog_err(
- "vty response called without setting mgmt_req_pending");
+ "vty resume response called without mgmt_req_pending_cmd");
return;
}
if (!success)
ret = CMD_WARNING_CONFIG_FAILED;
- vty->mgmt_req_pending = false;
+ MGMTD_FE_CLIENT_DBG(
+ "resuming CLI cmd after %s on vty session-id: %" PRIu64
+ " with '%s'",
+ vty->mgmt_req_pending_cmd, vty->mgmt_session_id,
+ success ? "succeeded" : "failed");
- MGMTD_FE_CLIENT_DBG("resuming: %s:", success ? "succeeded" : "failed");
+ vty->mgmt_req_pending_cmd = NULL;
if (vty->type != VTY_FILE) {
header[3] = ret;
@@ -1640,12 +1644,12 @@ struct vty *vty_new(void)
new->max = VTY_BUFSIZ;
new->pass_fd = -1;
- if (mgmt_lib_hndl) {
+ if (mgmt_fe_client) {
if (!mgmt_client_id_next)
mgmt_client_id_next++;
new->mgmt_client_id = mgmt_client_id_next++;
if (mgmt_fe_create_client_session(
- mgmt_lib_hndl, new->mgmt_client_id,
+ mgmt_fe_client, new->mgmt_client_id,
(uintptr_t) new) != MGMTD_SUCCESS)
zlog_err(
"Failed to open a MGMTD Frontend session for VTY session %p!!",
@@ -2217,6 +2221,8 @@ bool mgmt_vty_read_configs(void)
line_num = 0;
(void)config_from_file(vty, confp, &line_num);
count++;
+
+ fclose(confp);
}
snprintf(path, sizeof(path), "%s/mgmtd.conf", frr_sysconfdir);
@@ -2240,6 +2246,8 @@ bool mgmt_vty_read_configs(void)
line_num = 0;
(void)config_from_file(vty, confp, &line_num);
count++;
+
+ fclose(confp);
}
vty->pending_allowed = false;
@@ -2270,6 +2278,19 @@ static void vtysh_read(struct event *thread)
sock = EVENT_FD(thread);
vty = EVENT_ARG(thread);
+ /*
+ * This code looks like it can read multiple commands from the `buf`
+ * value returned by read(); however, it cannot in some cases.
+ *
+ * There are multiple paths out of the "copying to vty->buf" loop, which
+ * lose any content not yet copied from the stack `buf`, `passfd`,
+ * `CMD_SUSPEND` and finally if a front-end for mgmtd (generally this
+ * would be mgmtd itself). So these code paths are counting on vtysh not
+ * sending us more than 1 command line before waiting on the reply to
+ * that command.
+ */
+ assert(vty->type == VTY_SHELL_SERV);
+
if ((nbytes = read(sock, buf, VTY_READ_BUFSIZ)) <= 0) {
if (nbytes < 0) {
if (ERRNO_IO_RETRY(errno)) {
@@ -2344,8 +2365,13 @@ static void vtysh_read(struct event *thread)
/* with new infra we need to stop response till
* we get response through callback.
*/
- if (vty->mgmt_req_pending)
+ if (vty->mgmt_req_pending_cmd) {
+ MGMTD_FE_CLIENT_DBG(
+ "postpone CLI cmd response pending mgmtd %s on vty session-id %" PRIu64,
+ vty->mgmt_req_pending_cmd,
+ vty->mgmt_session_id);
return;
+ }
/* warning: watchfrr hardcodes this result write
*/
@@ -2419,8 +2445,17 @@ void vty_close(struct vty *vty)
vty->status = VTY_CLOSE;
- if (mgmt_lib_hndl && vty->mgmt_session_id) {
- mgmt_fe_destroy_client_session(mgmt_lib_hndl,
+ /*
+ * If we reach here with pending config to commit we will be losing it
+ * so warn the user.
+ */
+ if (vty->mgmt_num_pending_setcfg)
+ MGMTD_FE_CLIENT_ERR(
+ "vty closed, uncommitted config will be lost.");
+
+ if (mgmt_fe_client && vty->mgmt_session_id) {
+ MGMTD_FE_CLIENT_DBG("closing vty session");
+ mgmt_fe_destroy_client_session(mgmt_fe_client,
vty->mgmt_client_id);
vty->mgmt_session_id = 0;
}
@@ -3391,8 +3426,8 @@ void vty_init_vtysh(void)
* functionality linked into it. This design choice was taken for efficiency.
*/
-static void vty_mgmt_server_connected(uintptr_t lib_hndl, uintptr_t usr_data,
- bool connected)
+static void vty_mgmt_server_connected(struct mgmt_fe_client *client,
+ uintptr_t usr_data, bool connected)
{
MGMTD_FE_CLIENT_DBG("Got %sconnected %s MGMTD Frontend Server",
!connected ? "dis: " : "",
@@ -3403,7 +3438,7 @@ static void vty_mgmt_server_connected(uintptr_t lib_hndl, uintptr_t usr_data,
* The fe client library will delete all session on disconnect before
* calling us.
*/
- assert(mgmt_fe_client_session_count(lib_hndl) == 0);
+ assert(mgmt_fe_client_session_count(client) == 0);
mgmt_fe_connected = connected;
@@ -3417,10 +3452,10 @@ static void vty_mgmt_server_connected(uintptr_t lib_hndl, uintptr_t usr_data,
/*
* A session has successfully been created for a vty.
*/
-static void vty_mgmt_session_notify(uintptr_t lib_hndl, uintptr_t usr_data,
- uint64_t client_id, bool create,
- bool success, uintptr_t session_id,
- uintptr_t session_ctx)
+static void vty_mgmt_session_notify(struct mgmt_fe_client *client,
+ uintptr_t usr_data, uint64_t client_id,
+ bool create, bool success,
+ uintptr_t session_id, uintptr_t session_ctx)
{
struct vty *vty;
@@ -3440,12 +3475,15 @@ static void vty_mgmt_session_notify(uintptr_t lib_hndl, uintptr_t usr_data,
vty->mgmt_session_id = session_id;
} else {
vty->mgmt_session_id = 0;
- vty_close(vty);
+ /* We may come here by way of vty_close() and short-circuits */
+ if (vty->status != VTY_CLOSE)
+ vty_close(vty);
}
}
-static void vty_mgmt_ds_lock_notified(uintptr_t lib_hndl, uintptr_t usr_data,
- uint64_t client_id, uintptr_t session_id,
+static void vty_mgmt_ds_lock_notified(struct mgmt_fe_client *client,
+ uintptr_t usr_data, uint64_t client_id,
+ uintptr_t session_id,
uintptr_t session_ctx, uint64_t req_id,
bool lock_ds, bool success,
Mgmtd__DatastoreId ds_id,
@@ -3469,7 +3507,7 @@ static void vty_mgmt_ds_lock_notified(uintptr_t lib_hndl, uintptr_t usr_data,
}
static void vty_mgmt_set_config_result_notified(
- uintptr_t lib_hndl, uintptr_t usr_data, uint64_t client_id,
+ struct mgmt_fe_client *client, uintptr_t usr_data, uint64_t client_id,
uintptr_t session_id, uintptr_t session_ctx, uint64_t req_id,
bool success, Mgmtd__DatastoreId ds_id, char *errmsg_if_any)
{
@@ -3493,7 +3531,7 @@ static void vty_mgmt_set_config_result_notified(
}
static void vty_mgmt_commit_config_result_notified(
- uintptr_t lib_hndl, uintptr_t usr_data, uint64_t client_id,
+ struct mgmt_fe_client *client, uintptr_t usr_data, uint64_t client_id,
uintptr_t session_id, uintptr_t session_ctx, uint64_t req_id,
bool success, Mgmtd__DatastoreId src_ds_id,
Mgmtd__DatastoreId dst_ds_id, bool validate_only, char *errmsg_if_any)
@@ -3520,8 +3558,8 @@ static void vty_mgmt_commit_config_result_notified(
vty_mgmt_resume_response(vty, success);
}
-static enum mgmt_result vty_mgmt_get_data_result_notified(
- uintptr_t lib_hndl, uintptr_t usr_data, uint64_t client_id,
+static int vty_mgmt_get_data_result_notified(
+ struct mgmt_fe_client *client, uintptr_t usr_data, uint64_t client_id,
uintptr_t session_id, uintptr_t session_ctx, uint64_t req_id,
bool success, Mgmtd__DatastoreId ds_id, Mgmtd__YangData **yang_data,
size_t num_data, int next_key, char *errmsg_if_any)
@@ -3538,7 +3576,7 @@ static enum mgmt_result vty_mgmt_get_data_result_notified(
vty_out(vty, "ERROR: GET_DATA request failed, Error: %s\n",
errmsg_if_any ? errmsg_if_any : "Unknown");
vty_mgmt_resume_response(vty, success);
- return MGMTD_INTERNAL_ERROR;
+ return -1;
}
MGMTD_FE_CLIENT_DBG("GET_DATA request succeeded, client 0x%" PRIx64
@@ -3559,10 +3597,10 @@ static enum mgmt_result vty_mgmt_get_data_result_notified(
vty_mgmt_resume_response(vty, success);
}
- return MGMTD_SUCCESS;
+ return 0;
}
-static struct mgmt_fe_client_params client_params = {
+static struct mgmt_fe_client_cbs mgmt_cbs = {
.client_connect_notify = vty_mgmt_server_connected,
.client_session_notify = vty_mgmt_session_notify,
.lock_ds_notify = vty_mgmt_ds_lock_notified,
@@ -3573,21 +3611,19 @@ static struct mgmt_fe_client_params client_params = {
void vty_init_mgmt_fe(void)
{
- if (!vty_master) {
- zlog_err("Always call vty_mgmt_init_fe() after vty_init()!!");
- return;
- }
+ char name[40];
- assert(!mgmt_lib_hndl);
- snprintf(client_params.name, sizeof(client_params.name), "%s-%lld",
- frr_get_progname(), (long long)getpid());
- mgmt_lib_hndl = mgmt_fe_client_lib_init(&client_params, vty_master);
- assert(mgmt_lib_hndl);
+ assert(vty_master);
+ assert(!mgmt_fe_client);
+ snprintf(name, sizeof(name), "vty-%s-%ld", frr_get_progname(),
+ (long)getpid());
+ mgmt_fe_client = mgmt_fe_client_create(name, &mgmt_cbs, 0, vty_master);
+ assert(mgmt_fe_client);
}
bool vty_mgmt_fe_enabled(void)
{
- return mgmt_lib_hndl && mgmt_fe_connected;
+ return mgmt_fe_client && mgmt_fe_connected;
}
bool vty_mgmt_should_process_cli_apply_changes(struct vty *vty)
@@ -3598,13 +3634,11 @@ bool vty_mgmt_should_process_cli_apply_changes(struct vty *vty)
int vty_mgmt_send_lockds_req(struct vty *vty, Mgmtd__DatastoreId ds_id,
bool lock)
{
- enum mgmt_result ret;
-
- if (mgmt_lib_hndl && vty->mgmt_session_id) {
+ if (mgmt_fe_client && vty->mgmt_session_id) {
vty->mgmt_req_id++;
- ret = mgmt_fe_lock_ds(mgmt_lib_hndl, vty->mgmt_session_id,
- vty->mgmt_req_id, ds_id, lock);
- if (ret != MGMTD_SUCCESS) {
+ if (mgmt_fe_send_lockds_req(mgmt_fe_client,
+ vty->mgmt_session_id,
+ vty->mgmt_req_id, ds_id, lock)) {
zlog_err("Failed sending %sLOCK-DS-REQ req-id %" PRIu64,
lock ? "" : "UN", vty->mgmt_req_id);
vty_out(vty, "Failed to send %sLOCK-DS-REQ to MGMTD!\n",
@@ -3612,13 +3646,13 @@ int vty_mgmt_send_lockds_req(struct vty *vty, Mgmtd__DatastoreId ds_id,
return -1;
}
- vty->mgmt_req_pending = true;
+ vty->mgmt_req_pending_cmd = "MESSAGE_LOCKDS_REQ";
}
return 0;
}
-int vty_mgmt_send_config_data(struct vty *vty)
+int vty_mgmt_send_config_data(struct vty *vty, bool implicit_commit)
{
Mgmtd__YangDataValue value[VTY_MAXCFGCHANGES];
Mgmtd__YangData cfg_data[VTY_MAXCFGCHANGES];
@@ -3626,7 +3660,6 @@ int vty_mgmt_send_config_data(struct vty *vty)
Mgmtd__YangCfgDataReq *cfgreq[VTY_MAXCFGCHANGES] = {0};
size_t indx;
int cnt;
- bool implicit_commit = false;
if (vty->type == VTY_FILE) {
/*
@@ -3641,7 +3674,7 @@ int vty_mgmt_send_config_data(struct vty *vty)
}
- if (mgmt_lib_hndl && vty->mgmt_client_id && !vty->mgmt_session_id) {
+ if (mgmt_fe_client && vty->mgmt_client_id && !vty->mgmt_session_id) {
/*
* We are connected to mgmtd but we do not yet have an
* established session. this means we need to send any changes
@@ -3652,7 +3685,7 @@ int vty_mgmt_send_config_data(struct vty *vty)
return 0;
}
- if (mgmt_lib_hndl && vty->mgmt_session_id) {
+ if (mgmt_fe_client && vty->mgmt_session_id) {
cnt = 0;
for (indx = 0; indx < vty->num_cfg_changes; indx++) {
mgmt_yang_data_init(&cfg_data[cnt]);
@@ -3700,9 +3733,8 @@ int vty_mgmt_send_config_data(struct vty *vty)
}
vty->mgmt_req_id++;
- implicit_commit = vty_needs_implicit_commit(vty);
- if (cnt && mgmt_fe_set_config_data(
- mgmt_lib_hndl, vty->mgmt_session_id,
+ if (cnt && mgmt_fe_send_setcfg_req(
+ mgmt_fe_client, vty->mgmt_session_id,
vty->mgmt_req_id, MGMTD_DS_CANDIDATE, cfgreq,
cnt, implicit_commit,
MGMTD_DS_RUNNING) != MGMTD_SUCCESS) {
@@ -3712,7 +3744,7 @@ int vty_mgmt_send_config_data(struct vty *vty)
return -1;
}
- vty->mgmt_req_pending = true;
+ vty->mgmt_req_pending_cmd = "MESSAGE_SETCFG_REQ";
}
return 0;
@@ -3720,22 +3752,19 @@ int vty_mgmt_send_config_data(struct vty *vty)
int vty_mgmt_send_commit_config(struct vty *vty, bool validate_only, bool abort)
{
- enum mgmt_result ret;
-
- if (mgmt_lib_hndl && vty->mgmt_session_id) {
+ if (mgmt_fe_client && vty->mgmt_session_id) {
vty->mgmt_req_id++;
- ret = mgmt_fe_commit_config_data(
- mgmt_lib_hndl, vty->mgmt_session_id, vty->mgmt_req_id,
- MGMTD_DS_CANDIDATE, MGMTD_DS_RUNNING, validate_only,
- abort);
- if (ret != MGMTD_SUCCESS) {
+ if (mgmt_fe_send_commitcfg_req(
+ mgmt_fe_client, vty->mgmt_session_id,
+ vty->mgmt_req_id, MGMTD_DS_CANDIDATE,
+ MGMTD_DS_RUNNING, validate_only, abort)) {
zlog_err("Failed sending COMMIT-REQ req-id %" PRIu64,
vty->mgmt_req_id);
vty_out(vty, "Failed to send COMMIT-REQ to MGMTD!\n");
return -1;
}
- vty->mgmt_req_pending = true;
+ vty->mgmt_req_pending_cmd = "MESSAGE_COMMCFG_REQ";
vty->mgmt_num_pending_setcfg = 0;
}
@@ -3745,7 +3774,6 @@ int vty_mgmt_send_commit_config(struct vty *vty, bool validate_only, bool abort)
int vty_mgmt_send_get_config(struct vty *vty, Mgmtd__DatastoreId datastore,
const char **xpath_list, int num_req)
{
- enum mgmt_result ret;
Mgmtd__YangData yang_data[VTY_MAXCFGCHANGES];
Mgmtd__YangGetDataReq get_req[VTY_MAXCFGCHANGES];
Mgmtd__YangGetDataReq *getreq[VTY_MAXCFGCHANGES];
@@ -3762,11 +3790,9 @@ int vty_mgmt_send_get_config(struct vty *vty, Mgmtd__DatastoreId datastore,
get_req[i].data = &yang_data[i];
getreq[i] = &get_req[i];
}
- ret = mgmt_fe_get_config_data(mgmt_lib_hndl, vty->mgmt_session_id,
- vty->mgmt_req_id, datastore, getreq,
- num_req);
-
- if (ret != MGMTD_SUCCESS) {
+ if (mgmt_fe_send_getcfg_req(mgmt_fe_client, vty->mgmt_session_id,
+ vty->mgmt_req_id, datastore, getreq,
+ num_req)) {
zlog_err(
"Failed to send GET-CONFIG to MGMTD for req-id %" PRIu64
".",
@@ -3775,7 +3801,7 @@ int vty_mgmt_send_get_config(struct vty *vty, Mgmtd__DatastoreId datastore,
return -1;
}
- vty->mgmt_req_pending = true;
+ vty->mgmt_req_pending_cmd = "MESSAGE_GETCFG_REQ";
return 0;
}
@@ -3783,7 +3809,6 @@ int vty_mgmt_send_get_config(struct vty *vty, Mgmtd__DatastoreId datastore,
int vty_mgmt_send_get_data(struct vty *vty, Mgmtd__DatastoreId datastore,
const char **xpath_list, int num_req)
{
- enum mgmt_result ret;
Mgmtd__YangData yang_data[VTY_MAXCFGCHANGES];
Mgmtd__YangGetDataReq get_req[VTY_MAXCFGCHANGES];
Mgmtd__YangGetDataReq *getreq[VTY_MAXCFGCHANGES];
@@ -3800,10 +3825,9 @@ int vty_mgmt_send_get_data(struct vty *vty, Mgmtd__DatastoreId datastore,
get_req[i].data = &yang_data[i];
getreq[i] = &get_req[i];
}
- ret = mgmt_fe_get_data(mgmt_lib_hndl, vty->mgmt_session_id,
- vty->mgmt_req_id, datastore, getreq, num_req);
-
- if (ret != MGMTD_SUCCESS) {
+ if (mgmt_fe_send_getdata_req(mgmt_fe_client, vty->mgmt_session_id,
+ vty->mgmt_req_id, datastore, getreq,
+ num_req)) {
zlog_err("Failed to send GET-DATA to MGMTD for req-id %" PRIu64
".",
vty->mgmt_req_id);
@@ -3811,7 +3835,7 @@ int vty_mgmt_send_get_data(struct vty *vty, Mgmtd__DatastoreId datastore,
return -1;
}
- vty->mgmt_req_pending = true;
+ vty->mgmt_req_pending_cmd = "MESSAGE_GETDATA_REQ";
return 0;
}
@@ -3862,9 +3886,9 @@ void vty_terminate(void)
{
struct vty *vty;
- if (mgmt_lib_hndl) {
- mgmt_fe_client_lib_destroy();
- mgmt_lib_hndl = 0;
+ if (mgmt_fe_client) {
+ mgmt_fe_client_destroy(mgmt_fe_client);
+ mgmt_fe_client = 0;
}
memset(vty_cwd, 0x00, sizeof(vty_cwd));
diff --git a/lib/vty.h b/lib/vty.h
index 28f27d0d47..3b651d20a2 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -147,7 +147,6 @@ struct vty {
/* Dynamic transaction information. */
bool pending_allowed;
bool pending_commit;
- bool no_implicit_commit;
char *pending_cmds_buf;
size_t pending_cmds_buflen;
size_t pending_cmds_bufpos;
@@ -229,7 +228,7 @@ struct vty {
/* set when we have sent mgmtd a *REQ command in response to some vty
* CLI command and we are waiting on the reply so we can respond to the
* vty user. */
- bool mgmt_req_pending;
+ const char *mgmt_req_pending_cmd;
bool mgmt_locked_candidate_ds;
};
@@ -408,7 +407,7 @@ extern bool vty_mgmt_fe_enabled(void);
extern bool vty_mgmt_should_process_cli_apply_changes(struct vty *vty);
extern bool mgmt_vty_read_configs(void);
-extern int vty_mgmt_send_config_data(struct vty *vty);
+extern int vty_mgmt_send_config_data(struct vty *vty, bool implicit_commit);
extern int vty_mgmt_send_commit_config(struct vty *vty, bool validate_only,
bool abort);
extern int vty_mgmt_send_get_config(struct vty *vty,
@@ -422,11 +421,7 @@ extern void vty_mgmt_resume_response(struct vty *vty, bool success);
static inline bool vty_needs_implicit_commit(struct vty *vty)
{
- return (frr_get_cli_mode() == FRR_CLI_CLASSIC
- ? ((vty->pending_allowed || vty->no_implicit_commit)
- ? false
- : true)
- : false);
+ return frr_get_cli_mode() == FRR_CLI_CLASSIC && !vty->pending_allowed;
}
#ifdef __cplusplus