mgmtd: cleanup BE xpath subscription and matching code

Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
Christian Hopps 2023-05-20 04:25:47 -04:00
parent 52a50ca1d7
commit 0327be91d1
5 changed files with 264 additions and 244 deletions

View File

@ -40,14 +40,24 @@
* Please see xpath_map_reg[] in lib/mgmt_be_client.c * Please see xpath_map_reg[] in lib/mgmt_be_client.c
* for the actual map * for the actual map
*/ */
struct mgmt_be_xpath_map_reg { struct mgmt_be_xpath_map_init {
const char *xpath_regexp; /* Longest matching regular expression */ const char *xpath_regexp;
enum mgmt_be_client_id *be_clients; /* clients to notify */ uint subscr_info[MGMTD_BE_CLIENT_ID_MAX];
}; };
struct mgmt_be_xpath_regexp_map { struct mgmt_be_xpath_map {
const char *xpath_regexp; char *xpath_regexp;
struct mgmt_be_client_subscr_info be_subscrs; uint subscr_info[MGMTD_BE_CLIENT_ID_MAX];
};
struct mgmt_be_client_xpath {
const char *xpath;
uint subscribed;
};
struct mgmt_be_client_xpath_map {
struct mgmt_be_client_xpath *xpaths;
uint nxpaths;
}; };
struct mgmt_be_get_adapter_config_params { struct mgmt_be_get_adapter_config_params {
@ -66,38 +76,81 @@ struct mgmt_be_get_adapter_config_params {
* handle real-time mapping of YANG xpaths to one or * handle real-time mapping of YANG xpaths to one or
* more interested backend client adapters. * more interested backend client adapters.
*/ */
static const struct mgmt_be_xpath_map_reg xpath_static_map_reg[] = { static const struct mgmt_be_xpath_map_init mgmt_xpath_map_init[] = {
{.xpath_regexp = "/frr-vrf:lib/*", {
.be_clients = .xpath_regexp = "/frr-vrf:lib/*",
(enum mgmt_be_client_id[]){ .subscr_info =
{
#if HAVE_STATICD #if HAVE_STATICD
MGMTD_BE_CLIENT_ID_STATICD, [MGMTD_BE_CLIENT_ID_STATICD] =
MGMT_SUBSCR_VALIDATE_CFG |
MGMT_SUBSCR_NOTIFY_CFG,
#endif #endif
MGMTD_BE_CLIENT_ID_MAX}}, },
{.xpath_regexp = "/frr-interface:lib/*", },
.be_clients = {
(enum mgmt_be_client_id[]){ .xpath_regexp = "/frr-interface:lib/*",
.subscr_info =
{
#if HAVE_STATICD #if HAVE_STATICD
MGMTD_BE_CLIENT_ID_STATICD, [MGMTD_BE_CLIENT_ID_STATICD] =
MGMT_SUBSCR_VALIDATE_CFG |
MGMT_SUBSCR_NOTIFY_CFG,
#endif #endif
MGMTD_BE_CLIENT_ID_MAX}}, },
{.xpath_regexp = },
"/frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/*",
.be_clients = {
(enum mgmt_be_client_id[]){ .xpath_regexp =
"/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/*",
.subscr_info =
{
#if HAVE_STATICD #if HAVE_STATICD
MGMTD_BE_CLIENT_ID_STATICD, [MGMTD_BE_CLIENT_ID_STATICD] =
MGMT_SUBSCR_VALIDATE_CFG |
MGMT_SUBSCR_NOTIFY_CFG,
#endif
},
},
};
/*
* Each client gets their own map, but also union all the strings into the
* above map as well.
*/
#if HAVE_STATICD
static struct mgmt_be_client_xpath staticd_xpaths[] = {
{
.xpath = "/frr-vrf:lib/*",
.subscribed = MGMT_SUBSCR_VALIDATE_CFG | MGMT_SUBSCR_NOTIFY_CFG,
},
{
.xpath = "/frr-interface:lib/*",
.subscribed = MGMT_SUBSCR_VALIDATE_CFG | MGMT_SUBSCR_NOTIFY_CFG,
},
{
.xpath =
"/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/*",
.subscribed = MGMT_SUBSCR_VALIDATE_CFG | MGMT_SUBSCR_NOTIFY_CFG,
},
};
#endif
static struct mgmt_be_client_xpath_map
mgmt_client_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {
#ifdef HAVE_STATICD
[MGMTD_BE_CLIENT_ID_STATICD] = {staticd_xpaths,
array_size(staticd_xpaths)},
#endif #endif
MGMTD_BE_CLIENT_ID_MAX}},
}; };
#define MGMTD_BE_MAX_NUM_XPATH_MAP 256 #define MGMTD_BE_MAX_NUM_XPATH_MAP 256
/* We really want to have a better ADT than one with O(n) comparisons */ /* We would like to have a better ADT than one with O(n)
static struct mgmt_be_xpath_regexp_map comparisons */
mgmt_xpath_map[MGMTD_BE_MAX_NUM_XPATH_MAP]; static struct mgmt_be_xpath_map *mgmt_xpath_map;
static int mgmt_num_xpath_maps; static uint mgmt_num_xpath_maps;
static struct event_loop *mgmt_loop; static struct event_loop *mgmt_loop;
static struct msg_server mgmt_be_server = {.fd = -1}; static struct msg_server mgmt_be_server = {.fd = -1};
@ -111,6 +164,9 @@ static struct mgmt_be_client_adapter
static void static void
mgmt_be_adapter_sched_init_event(struct mgmt_be_client_adapter *adapter); mgmt_be_adapter_sched_init_event(struct mgmt_be_client_adapter *adapter);
static uint mgmt_be_get_subscr_for_xpath_and_client(
const char *xpath, enum mgmt_be_client_id client_id, uint subscr_mask);
static struct mgmt_be_client_adapter * static struct mgmt_be_client_adapter *
mgmt_be_find_adapter_by_fd(int conn_fd) mgmt_be_find_adapter_by_fd(int conn_fd)
{ {
@ -139,41 +195,32 @@ mgmt_be_find_adapter_by_name(const char *name)
static void mgmt_be_xpath_map_init(void) static void mgmt_be_xpath_map_init(void)
{ {
int indx, num_xpath_maps; uint i;
uint16_t indx1;
enum mgmt_be_client_id id;
MGMTD_BE_ADAPTER_DBG("Init XPath Maps"); MGMTD_BE_ADAPTER_DBG("Init XPath Maps");
num_xpath_maps = (int)array_size(xpath_static_map_reg); mgmt_num_xpath_maps = array_size(mgmt_xpath_map_init);
for (indx = 0; indx < num_xpath_maps; indx++) { mgmt_xpath_map =
calloc(1, sizeof(*mgmt_xpath_map) * mgmt_num_xpath_maps);
for (i = 0; i < mgmt_num_xpath_maps; i++) {
MGMTD_BE_ADAPTER_DBG(" - XPATH: '%s'", MGMTD_BE_ADAPTER_DBG(" - XPATH: '%s'",
xpath_static_map_reg[indx].xpath_regexp); mgmt_xpath_map_init[i].xpath_regexp);
mgmt_xpath_map[indx].xpath_regexp = mgmt_xpath_map[i].xpath_regexp = XSTRDUP(
xpath_static_map_reg[indx].xpath_regexp; MTYPE_MGMTD_XPATH, mgmt_xpath_map_init[i].xpath_regexp);
for (indx1 = 0;; indx1++) { memcpy(mgmt_xpath_map[i].subscr_info,
id = xpath_static_map_reg[indx].be_clients[indx1]; mgmt_xpath_map_init[i].subscr_info,
if (id == MGMTD_BE_CLIENT_ID_MAX) sizeof(mgmt_xpath_map_init[i].subscr_info));
break;
MGMTD_BE_ADAPTER_DBG(" -- Client: %s Id: %u",
mgmt_be_client_id2name(id),
id);
if (id < MGMTD_BE_CLIENT_ID_MAX) {
mgmt_xpath_map[indx]
.be_subscrs.xpath_subscr[id]
.validate_config = 1;
mgmt_xpath_map[indx]
.be_subscrs.xpath_subscr[id]
.notify_config = 1;
mgmt_xpath_map[indx]
.be_subscrs.xpath_subscr[id]
.own_oper_data = 1;
}
} }
MGMTD_BE_ADAPTER_DBG("Total XPath Maps: %u", mgmt_num_xpath_maps);
} }
mgmt_num_xpath_maps = indx; static void mgmt_be_xpath_map_cleanup(void)
MGMTD_BE_ADAPTER_DBG("Total XPath Maps: %u", mgmt_num_xpath_maps); {
uint i;
for (i = 0; i < mgmt_num_xpath_maps; i++)
XFREE(MTYPE_MGMTD_XPATH, mgmt_xpath_map[i].xpath_regexp);
free(mgmt_xpath_map);
} }
static int mgmt_be_eval_regexp_match(const char *xpath_regexp, static int mgmt_be_eval_regexp_match(const char *xpath_regexp,
@ -606,27 +653,14 @@ static void mgmt_be_iter_and_get_cfg(struct mgmt_ds_ctx *ds_ctx,
const char *xpath, struct lyd_node *node, const char *xpath, struct lyd_node *node,
struct nb_node *nb_node, void *ctx) struct nb_node *nb_node, void *ctx)
{ {
struct mgmt_be_client_subscr_info subscr_info; struct mgmt_be_get_adapter_config_params *parms = ctx;
struct mgmt_be_get_adapter_config_params *parms; struct mgmt_be_client_adapter *adapter = parms->adapter;
struct mgmt_be_client_adapter *adapter; uint subscr;
struct nb_config_cbs *root;
uint32_t *seq;
if (mgmt_be_get_subscr_info_for_xpath(xpath, &subscr_info) != 0) { subscr = mgmt_be_get_subscr_for_xpath_and_client(
MGMTD_BE_ADAPTER_ERR( xpath, adapter->id, MGMT_SUBSCR_NOTIFY_CFG);
"ERROR: Failed to get subscriber for '%s'", xpath); if (subscr)
return; nb_config_diff_created(node, &parms->seq, parms->cfg_chgs);
}
parms = (struct mgmt_be_get_adapter_config_params *)ctx;
adapter = parms->adapter;
if (!subscr_info.xpath_subscr[adapter->id].subscribed)
return;
root = parms->cfg_chgs;
seq = &parms->seq;
nb_config_diff_created(node, seq, root);
} }
/* /*
@ -703,10 +737,6 @@ void mgmt_be_adapter_init(struct event_loop *tm)
assert(!mgmt_loop); assert(!mgmt_loop);
mgmt_loop = tm; mgmt_loop = tm;
memset(mgmt_xpath_map, 0, sizeof(mgmt_xpath_map));
mgmt_num_xpath_maps = 0;
memset(mgmt_be_adapters_by_id, 0, sizeof(mgmt_be_adapters_by_id));
mgmt_be_adapters_init(&mgmt_be_adapters); mgmt_be_adapters_init(&mgmt_be_adapters);
mgmt_be_xpath_map_init(); mgmt_be_xpath_map_init();
@ -729,6 +759,7 @@ void mgmt_be_adapter_destroy(void)
FOREACH_ADAPTER_IN_LIST (adapter) { FOREACH_ADAPTER_IN_LIST (adapter) {
mgmt_be_adapter_delete(adapter); mgmt_be_adapter_delete(adapter);
} }
mgmt_be_xpath_map_cleanup();
} }
/* /*
@ -837,67 +868,74 @@ mgmt_be_send_cfg_apply_req(struct mgmt_be_client_adapter *adapter,
return mgmt_be_send_cfgapply_req(adapter, txn_id); return mgmt_be_send_cfgapply_req(adapter, txn_id);
} }
/* void mgmt_be_get_subscr_info_for_xpath(
* This function maps a YANG dtata Xpath to one or more
* Backend Clients that should be contacted for various purposes.
*/
int mgmt_be_get_subscr_info_for_xpath(
const char *xpath, struct mgmt_be_client_subscr_info *subscr_info) const char *xpath, struct mgmt_be_client_subscr_info *subscr_info)
{ {
int indx, match, max_match = 0, num_reg;
enum mgmt_be_client_id id; enum mgmt_be_client_id id;
struct mgmt_be_client_subscr_info uint i;
*reg_maps[array_size(mgmt_xpath_map)] = {0};
bool root_xp = false;
if (!subscr_info)
return -1;
num_reg = 0;
memset(subscr_info, 0, sizeof(*subscr_info)); memset(subscr_info, 0, sizeof(*subscr_info));
if (strlen(xpath) <= 2 && xpath[0] == '/'
&& (!xpath[1] || xpath[1] == '*')) {
root_xp = true;
}
MGMTD_BE_ADAPTER_DBG("XPATH: '%s'", xpath); MGMTD_BE_ADAPTER_DBG("XPATH: '%s'", xpath);
for (indx = 0; indx < mgmt_num_xpath_maps; indx++) { for (i = 0; i < mgmt_num_xpath_maps; i++) {
/* if (!mgmt_be_eval_regexp_match(mgmt_xpath_map[i].xpath_regexp,
* For Xpaths: '/' and '/ *' all xpath maps should match xpath))
* the given xpath.
*/
if (!root_xp) {
match = mgmt_be_eval_regexp_match(
mgmt_xpath_map[indx].xpath_regexp, xpath);
if (!match || match < max_match)
continue; continue;
if (match > max_match) {
num_reg = 0;
max_match = match;
}
}
reg_maps[num_reg] = &mgmt_xpath_map[indx].be_subscrs;
num_reg++;
}
for (indx = 0; indx < num_reg; indx++) {
FOREACH_MGMTD_BE_CLIENT_ID (id) { FOREACH_MGMTD_BE_CLIENT_ID (id) {
if (reg_maps[indx]->xpath_subscr[id].subscribed) { subscr_info->xpath_subscr[id] |=
MGMTD_BE_ADAPTER_DBG( mgmt_xpath_map[i].subscr_info[id];
"Cient: %s", }
mgmt_be_client_id2name(id)); }
memcpy(&subscr_info->xpath_subscr[id],
&reg_maps[indx]->xpath_subscr[id], if (DEBUG_MODE_CHECK(&mgmt_debug_be, DEBUG_MODE_ALL)) {
sizeof(subscr_info->xpath_subscr[id])); FOREACH_MGMTD_BE_CLIENT_ID (id) {
if (!subscr_info->xpath_subscr[id])
continue;
MGMTD_BE_ADAPTER_DBG("Cient: %s: subscribed: 0x%x",
mgmt_be_client_id2name(id),
subscr_info->xpath_subscr[id]);
} }
} }
} }
return 0; /**
* Return the subscription info bits for a given `xpath` for a given
* `client_id`.
*
* Args:
* xpath - the xpath to check for subscription information.
* client_id - the BE client being checked for.
* subscr_mask - The subscr bits the caller is interested in seeing
* if set.
*
* Returns:
* The subscription info bits.
*/
static uint mgmt_be_get_subscr_for_xpath_and_client(
const char *xpath, enum mgmt_be_client_id client_id, uint subscr_mask)
{
struct mgmt_be_client_xpath_map *map;
uint subscr = 0;
uint i;
assert(client_id < MGMTD_BE_CLIENT_ID_MAX);
MGMTD_BE_ADAPTER_DBG("Checking client: %s for xpath: '%s'",
mgmt_be_client_id2name(client_id), xpath);
map = &mgmt_client_xpaths[client_id];
for (i = 0; i < map->nxpaths; i++) {
if (!mgmt_be_eval_regexp_match(map->xpaths[i].xpath, xpath))
continue;
MGMTD_BE_ADAPTER_DBG("xpath: %s: matched: %s",
map->xpaths[i].xpath, xpath);
subscr |= map->xpaths[i].subscribed;
if ((subscr & subscr_mask) == subscr_mask)
break;
}
MGMTD_BE_ADAPTER_DBG("client: %s: subscribed: 0x%x",
mgmt_be_client_id2name(client_id), subscr);
return subscr;
} }
void mgmt_be_adapter_status_write(struct vty *vty) void mgmt_be_adapter_status_write(struct vty *vty)
@ -926,9 +964,10 @@ void mgmt_be_adapter_status_write(struct vty *vty)
void mgmt_be_xpath_register_write(struct vty *vty) void mgmt_be_xpath_register_write(struct vty *vty)
{ {
int indx; uint indx;
enum mgmt_be_client_id id; enum mgmt_be_client_id id;
struct mgmt_be_client_adapter *adapter; struct mgmt_be_client_adapter *adapter;
uint info;
vty_out(vty, "MGMTD Backend XPath Registry\n"); vty_out(vty, "MGMTD Backend XPath Registry\n");
@ -936,36 +975,18 @@ void mgmt_be_xpath_register_write(struct vty *vty)
vty_out(vty, " - XPATH: '%s'\n", vty_out(vty, " - XPATH: '%s'\n",
mgmt_xpath_map[indx].xpath_regexp); mgmt_xpath_map[indx].xpath_regexp);
FOREACH_MGMTD_BE_CLIENT_ID (id) { FOREACH_MGMTD_BE_CLIENT_ID (id) {
if (mgmt_xpath_map[indx] info = mgmt_xpath_map[indx].subscr_info[id];
.be_subscrs.xpath_subscr[id] if (!info)
.subscribed) { continue;
vty_out(vty, vty_out(vty,
" -- Client: '%s' \t Validate:%s, Notify:%s, Own:%s\n", " -- Client: '%s'\tValidate:%d, Notify:%d, Own:%d\n",
mgmt_be_client_id2name(id), mgmt_be_client_id2name(id),
mgmt_xpath_map[indx] (info & MGMT_SUBSCR_VALIDATE_CFG) != 0,
.be_subscrs (info & MGMT_SUBSCR_NOTIFY_CFG) != 0,
.xpath_subscr[id] (info & MGMT_SUBSCR_OPER_OWN) != 0);
.validate_config
? "T"
: "F",
mgmt_xpath_map[indx]
.be_subscrs
.xpath_subscr[id]
.notify_config
? "T"
: "F",
mgmt_xpath_map[indx]
.be_subscrs
.xpath_subscr[id]
.own_oper_data
? "T"
: "F");
adapter = mgmt_be_get_adapter_by_id(id); adapter = mgmt_be_get_adapter_by_id(id);
if (adapter) { if (adapter)
vty_out(vty, " -- Adapter: %p\n", vty_out(vty, " -- Adapter: %p\n", adapter);
adapter);
}
}
} }
} }
@ -977,28 +998,23 @@ void mgmt_be_xpath_subscr_info_write(struct vty *vty, const char *xpath)
struct mgmt_be_client_subscr_info subscr; struct mgmt_be_client_subscr_info subscr;
enum mgmt_be_client_id id; enum mgmt_be_client_id id;
struct mgmt_be_client_adapter *adapter; struct mgmt_be_client_adapter *adapter;
uint info;
if (mgmt_be_get_subscr_info_for_xpath(xpath, &subscr) != 0) { mgmt_be_get_subscr_info_for_xpath(xpath, &subscr);
vty_out(vty, "ERROR: Failed to get subscriber for '%s'\n",
xpath);
return;
}
vty_out(vty, "XPath: '%s'\n", xpath); vty_out(vty, "XPath: '%s'\n", xpath);
FOREACH_MGMTD_BE_CLIENT_ID (id) { FOREACH_MGMTD_BE_CLIENT_ID (id) {
if (subscr.xpath_subscr[id].subscribed) { info = subscr.xpath_subscr[id];
if (!info)
continue;
vty_out(vty, vty_out(vty,
" -- Client: '%s' \t Validate:%s, Notify:%s, Own:%s\n", " -- Client: '%s'\tValidate:%d, Notify:%d, Own:%d\n",
mgmt_be_client_id2name(id), mgmt_be_client_id2name(id),
subscr.xpath_subscr[id].validate_config ? "T" (info & MGMT_SUBSCR_VALIDATE_CFG) != 0,
: "F", (info & MGMT_SUBSCR_NOTIFY_CFG) != 0,
subscr.xpath_subscr[id].notify_config ? "T" (info & MGMT_SUBSCR_OPER_OWN) != 0);
: "F",
subscr.xpath_subscr[id].own_oper_data ? "T"
: "F");
adapter = mgmt_be_get_adapter_by_id(id); adapter = mgmt_be_get_adapter_by_id(id);
if (adapter) if (adapter)
vty_out(vty, " -- Adapter: %p\n", adapter); vty_out(vty, " -- Adapter: %p\n", adapter);
} }
} }
}

View File

@ -69,17 +69,20 @@ struct mgmt_be_client_adapter {
DECLARE_LIST(mgmt_be_adapters, struct mgmt_be_client_adapter, list_linkage); DECLARE_LIST(mgmt_be_adapters, struct mgmt_be_client_adapter, list_linkage);
union mgmt_be_xpath_subscr_info { /*
uint8_t subscribed; * MGMT_SUBSCR_xxx - flags for subscription types for xpaths registrations
struct { *
uint8_t validate_config : 1; * MGMT_SUBSCR_VALIDATE_CFG :: the client should be asked to validate config
uint8_t notify_config : 1; * MGMT_SUBSCR_NOTIFY_CFG :: the client should be notified of config changes
uint8_t own_oper_data : 1; * MGMT_SUBSCR_OPER_OWN :: the client owns the given oeprational state
}; */
}; #define MGMT_SUBSCR_VALIDATE_CFG 0x1
#define MGMT_SUBSCR_NOTIFY_CFG 0x2
#define MGMT_SUBSCR_OPER_OWN 0x4
#define MGMT_SUBSCR_ALL 0x7
struct mgmt_be_client_subscr_info { struct mgmt_be_client_subscr_info {
union mgmt_be_xpath_subscr_info xpath_subscr[MGMTD_BE_CLIENT_ID_MAX]; uint xpath_subscr[MGMTD_BE_CLIENT_ID_MAX];
}; };
/* Initialise backend adapter module. */ /* Initialise backend adapter module. */
@ -194,11 +197,17 @@ extern void mgmt_be_adapter_status_write(struct vty *vty);
*/ */
extern void mgmt_be_xpath_register_write(struct vty *vty); extern void mgmt_be_xpath_register_write(struct vty *vty);
/* /**
* Maps a YANG dtata Xpath to one or more * Lookup the clients which are subscribed to a given `xpath`
* backend clients that should be contacted for various purposes. * and the way they are subscribed.
*
* Args:
* xpath - the xpath to check for subscription information.
* subscr_info - An array of uint indexed by client id
* each eleemnt holds the subscription info
* for that client.
*/ */
extern int mgmt_be_get_subscr_info_for_xpath( extern void mgmt_be_get_subscr_info_for_xpath(
const char *xpath, struct mgmt_be_client_subscr_info *subscr_info); const char *xpath, struct mgmt_be_client_subscr_info *subscr_info);
/* /*

View File

@ -19,14 +19,15 @@
DEFINE_MGROUP(MGMTD, "mgmt"); DEFINE_MGROUP(MGMTD, "mgmt");
DEFINE_MTYPE(MGMTD, MGMTD, "instance"); DEFINE_MTYPE(MGMTD, MGMTD, "instance");
DEFINE_MTYPE(MGMTD, MGMTD_XPATH, "xpath regex");
DEFINE_MTYPE(MGMTD, MGMTD_BE_ADPATER, "backend adapter"); DEFINE_MTYPE(MGMTD, MGMTD_BE_ADPATER, "backend adapter");
DEFINE_MTYPE(MGMTD, MGMTD_FE_ADPATER, "Frontend adapter"); DEFINE_MTYPE(MGMTD, MGMTD_FE_ADPATER, "frontend adapter");
DEFINE_MTYPE(MGMTD, MGMTD_FE_SESSION, "Frontend Client Session"); DEFINE_MTYPE(MGMTD, MGMTD_FE_SESSION, "frontend session");
DEFINE_MTYPE(MGMTD, MGMTD_TXN, "Trnsction"); DEFINE_MTYPE(MGMTD, MGMTD_TXN, "txn");
DEFINE_MTYPE(MGMTD, MGMTD_TXN_REQ, "Trnsction Requests"); DEFINE_MTYPE(MGMTD, MGMTD_TXN_REQ, "txn request");
DEFINE_MTYPE(MGMTD, MGMTD_TXN_SETCFG_REQ, "Trnsction Set-Config Requests"); DEFINE_MTYPE(MGMTD, MGMTD_TXN_SETCFG_REQ, "txn set-config requests");
DEFINE_MTYPE(MGMTD, MGMTD_TXN_COMMCFG_REQ, "Trnsction Commit-Config Requests"); DEFINE_MTYPE(MGMTD, MGMTD_TXN_COMMCFG_REQ, "txn commit-config requests");
DEFINE_MTYPE(MGMTD, MGMTD_TXN_GETDATA_REQ, "Trnsction Get-Data Requests"); DEFINE_MTYPE(MGMTD, MGMTD_TXN_GETDATA_REQ, "txn get-data requests");
DEFINE_MTYPE(MGMTD, MGMTD_TXN_GETDATA_REPLY, "Trnsction Get-Data Replies"); DEFINE_MTYPE(MGMTD, MGMTD_TXN_GETDATA_REPLY, "txn get-data replies");
DEFINE_MTYPE(MGMTD, MGMTD_TXN_CFG_BATCH, "Trnsction Gonfig Batches"); DEFINE_MTYPE(MGMTD, MGMTD_TXN_CFG_BATCH, "txn config batches");
DEFINE_MTYPE(MGMTD, MGMTD_CMT_INFO, "info for tracking commits"); DEFINE_MTYPE(MGMTD, MGMTD_CMT_INFO, "commit info");

View File

@ -13,6 +13,7 @@
DECLARE_MGROUP(MGMTD); DECLARE_MGROUP(MGMTD);
DECLARE_MTYPE(MGMTD); DECLARE_MTYPE(MGMTD);
DECLARE_MTYPE(MGMTD_XPATH);
DECLARE_MTYPE(MGMTD_BE_ADPATER); DECLARE_MTYPE(MGMTD_BE_ADPATER);
DECLARE_MTYPE(MGMTD_FE_ADPATER); DECLARE_MTYPE(MGMTD_FE_ADPATER);
DECLARE_MTYPE(MGMTD_FE_SESSION); DECLARE_MTYPE(MGMTD_FE_SESSION);

View File

@ -81,8 +81,7 @@ struct mgmt_txn_be_cfg_batch {
uint64_t batch_id; uint64_t batch_id;
enum mgmt_be_client_id be_id; enum mgmt_be_client_id be_id;
struct mgmt_be_client_adapter *be_adapter; struct mgmt_be_client_adapter *be_adapter;
union mgmt_be_xpath_subscr_info uint xp_subscr[MGMTD_MAX_CFG_CHANGES_IN_BATCH];
xp_subscr[MGMTD_MAX_CFG_CHANGES_IN_BATCH];
Mgmtd__YangCfgDataReq cfg_data[MGMTD_MAX_CFG_CHANGES_IN_BATCH]; Mgmtd__YangCfgDataReq cfg_data[MGMTD_MAX_CFG_CHANGES_IN_BATCH];
Mgmtd__YangCfgDataReq * cfg_datap[MGMTD_MAX_CFG_CHANGES_IN_BATCH]; Mgmtd__YangCfgDataReq * cfg_datap[MGMTD_MAX_CFG_CHANGES_IN_BATCH];
Mgmtd__YangData data[MGMTD_MAX_CFG_CHANGES_IN_BATCH]; Mgmtd__YangData data[MGMTD_MAX_CFG_CHANGES_IN_BATCH];
@ -532,14 +531,13 @@ static void mgmt_txn_req_free(struct mgmt_txn_req **txn_req)
* Send TXN_DELETE to cleanup state for this * Send TXN_DELETE to cleanup state for this
* transaction on backend * transaction on backend
*/ */
if ((*txn_req)->req.commit_cfg.curr_phase if ((*txn_req)->req.commit_cfg.curr_phase >=
>= MGMTD_COMMIT_PHASE_TXN_CREATE MGMTD_COMMIT_PHASE_TXN_CREATE &&
&& (*txn_req)->req.commit_cfg.curr_phase (*txn_req)->req.commit_cfg.curr_phase <
< MGMTD_COMMIT_PHASE_TXN_DELETE MGMTD_COMMIT_PHASE_TXN_DELETE &&
&& (*txn_req) (*txn_req)
->req.commit_cfg.subscr_info ->req.commit_cfg.subscr_info
.xpath_subscr[id] .xpath_subscr[id]) {
.subscribed) {
adapter = mgmt_be_get_adapter_by_id(id); adapter = mgmt_be_get_adapter_by_id(id);
if (adapter) if (adapter)
mgmt_txn_send_be_txn_delete( mgmt_txn_send_be_txn_delete(
@ -916,7 +914,7 @@ mgmt_try_move_commit_to_next_phase(struct mgmt_txn_ctx *txn,
* Check if all clients has moved to next phase or not. * Check if all clients has moved to next phase or not.
*/ */
FOREACH_MGMTD_BE_CLIENT_ID (id) { FOREACH_MGMTD_BE_CLIENT_ID (id) {
if (cmtcfg_req->subscr_info.xpath_subscr[id].subscribed && if (cmtcfg_req->subscr_info.xpath_subscr[id] &&
mgmt_txn_batches_count(&cmtcfg_req->curr_batches[id])) { mgmt_txn_batches_count(&cmtcfg_req->curr_batches[id])) {
/* /*
* There's atleast once client who hasn't moved to * There's atleast once client who hasn't moved to
@ -1034,22 +1032,15 @@ static int mgmt_txn_create_config_batches(struct mgmt_txn_req *txn_req,
MGMTD_TXN_DBG("XPATH: %s, Value: '%s'", xpath, MGMTD_TXN_DBG("XPATH: %s, Value: '%s'", xpath,
value ? value : "NIL"); value ? value : "NIL");
if (mgmt_be_get_subscr_info_for_xpath(xpath, &subscr_info) mgmt_be_get_subscr_info_for_xpath(xpath, &subscr_info);
!= 0) {
snprintf(err_buf, sizeof(err_buf),
"No backend module found for XPATH: '%s",
xpath);
(void)mgmt_txn_send_commit_cfg_reply(
txn_req->txn, MGMTD_INTERNAL_ERROR, err_buf);
goto mgmt_txn_create_config_batches_failed;
}
xpath_len = strlen(xpath) + 1; xpath_len = strlen(xpath) + 1;
value_len = strlen(value) + 1; value_len = strlen(value) + 1;
found_validator = false; found_validator = false;
FOREACH_MGMTD_BE_CLIENT_ID (id) { FOREACH_MGMTD_BE_CLIENT_ID (id) {
if (!subscr_info.xpath_subscr[id].validate_config if (!(subscr_info.xpath_subscr[id] &
&& !subscr_info.xpath_subscr[id].notify_config) (MGMT_SUBSCR_VALIDATE_CFG |
MGMT_SUBSCR_NOTIFY_CFG)))
continue; continue;
adapter = mgmt_be_get_adapter_by_id(id); adapter = mgmt_be_get_adapter_by_id(id);
@ -1103,17 +1094,19 @@ static int mgmt_txn_create_config_batches(struct mgmt_txn_req *txn_req,
.encoded_str_val = value; .encoded_str_val = value;
value = NULL; value = NULL;
if (subscr_info.xpath_subscr[id].validate_config) if (subscr_info.xpath_subscr[id] &
MGMT_SUBSCR_VALIDATE_CFG)
found_validator = true; found_validator = true;
cmtcfg_req->subscr_info.xpath_subscr[id].subscribed |= cmtcfg_req->subscr_info.xpath_subscr[id] |=
subscr_info.xpath_subscr[id].subscribed; subscr_info.xpath_subscr[id];
MGMTD_TXN_DBG( MGMTD_TXN_DBG(" -- %s, {V:%d, N:%d}, batch-id: %" PRIu64
" -- %s, {V:%d, N:%d}, batch-id: %" PRIu64
" item:%d", " item:%d",
adapter->name, adapter->name,
subscr_info.xpath_subscr[id].validate_config, (subscr_info.xpath_subscr[id] &
subscr_info.xpath_subscr[id].notify_config, MGMT_SUBSCR_VALIDATE_CFG) != 0,
(subscr_info.xpath_subscr[id] &
MGMT_SUBSCR_NOTIFY_CFG) != 0,
cfg_btch->batch_id, cfg_btch->batch_id,
(int)cfg_btch->num_cfg_data); (int)cfg_btch->num_cfg_data);
@ -1350,7 +1343,7 @@ static int mgmt_txn_send_be_txn_create(struct mgmt_txn_ctx *txn)
cmtcfg_req = &txn->commit_cfg_req->req.commit_cfg; cmtcfg_req = &txn->commit_cfg_req->req.commit_cfg;
FOREACH_MGMTD_BE_CLIENT_ID (id) { FOREACH_MGMTD_BE_CLIENT_ID (id) {
if (cmtcfg_req->subscr_info.xpath_subscr[id].subscribed) { if (cmtcfg_req->subscr_info.xpath_subscr[id]) {
adapter = mgmt_be_get_adapter_by_id(id); adapter = mgmt_be_get_adapter_by_id(id);
if (mgmt_be_create_txn(adapter, txn->txn_id) if (mgmt_be_create_txn(adapter, txn->txn_id)
!= 0) { != 0) {
@ -1398,7 +1391,7 @@ mgmt_txn_send_be_cfg_data(struct mgmt_txn_ctx *txn,
assert(txn->type == MGMTD_TXN_TYPE_CONFIG && txn->commit_cfg_req); assert(txn->type == MGMTD_TXN_TYPE_CONFIG && txn->commit_cfg_req);
cmtcfg_req = &txn->commit_cfg_req->req.commit_cfg; cmtcfg_req = &txn->commit_cfg_req->req.commit_cfg;
assert(cmtcfg_req->subscr_info.xpath_subscr[adapter->id].subscribed); assert(cmtcfg_req->subscr_info.xpath_subscr[adapter->id]);
indx = 0; indx = 0;
num_batches = num_batches =
@ -1451,7 +1444,7 @@ mgmt_txn_send_be_txn_delete(struct mgmt_txn_ctx *txn,
assert(txn->type == MGMTD_TXN_TYPE_CONFIG && txn->commit_cfg_req); assert(txn->type == MGMTD_TXN_TYPE_CONFIG && txn->commit_cfg_req);
cmtcfg_req = &txn->commit_cfg_req->req.commit_cfg; cmtcfg_req = &txn->commit_cfg_req->req.commit_cfg;
if (cmtcfg_req->subscr_info.xpath_subscr[adapter->id].subscribed) { if (cmtcfg_req->subscr_info.xpath_subscr[adapter->id]) {
adapter = mgmt_be_get_adapter_by_id(adapter->id); adapter = mgmt_be_get_adapter_by_id(adapter->id);
(void)mgmt_be_destroy_txn(adapter, txn->txn_id); (void)mgmt_be_destroy_txn(adapter, txn->txn_id);
@ -1519,7 +1512,8 @@ static int mgmt_txn_send_be_cfg_apply(struct mgmt_txn_ctx *txn)
} }
FOREACH_MGMTD_BE_CLIENT_ID (id) { FOREACH_MGMTD_BE_CLIENT_ID (id) {
if (cmtcfg_req->subscr_info.xpath_subscr[id].notify_config) { if (cmtcfg_req->subscr_info.xpath_subscr[id] &
MGMT_SUBSCR_NOTIFY_CFG) {
adapter = mgmt_be_get_adapter_by_id(id); adapter = mgmt_be_get_adapter_by_id(id);
if (!adapter) if (!adapter)
return -1; return -1;
@ -2489,10 +2483,9 @@ int mgmt_txn_notify_be_adapter_conn(struct mgmt_be_client_adapter *adapter,
? &txn->commit_cfg_req ? &txn->commit_cfg_req
->req.commit_cfg ->req.commit_cfg
: NULL; : NULL;
if (cmtcfg_req if (cmtcfg_req &&
&& cmtcfg_req->subscr_info cmtcfg_req->subscr_info
.xpath_subscr[adapter->id] .xpath_subscr[adapter->id]) {
.subscribed) {
mgmt_txn_send_commit_cfg_reply( mgmt_txn_send_commit_cfg_reply(
txn, MGMTD_INTERNAL_ERROR, txn, MGMTD_INTERNAL_ERROR,
"Backend daemon disconnected while processing commit!"); "Backend daemon disconnected while processing commit!");