forked from Mirror/frr
lib: northbound/mgmtd: add backend model support
Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
parent
5f35096123
commit
5f2a927d7b
|
@ -99,12 +99,12 @@ struct mgmt_be_client {
|
||||||
struct nb_config *candidate_config;
|
struct nb_config *candidate_config;
|
||||||
struct nb_config *running_config;
|
struct nb_config *running_config;
|
||||||
|
|
||||||
unsigned long num_edit_nb_cfg;
|
uint64_t num_edit_nb_cfg;
|
||||||
unsigned long avg_edit_nb_cfg_tm;
|
uint64_t avg_edit_nb_cfg_tm;
|
||||||
unsigned long num_prep_nb_cfg;
|
uint64_t num_prep_nb_cfg;
|
||||||
unsigned long avg_prep_nb_cfg_tm;
|
uint64_t avg_prep_nb_cfg_tm;
|
||||||
unsigned long num_apply_nb_cfg;
|
uint64_t num_apply_nb_cfg;
|
||||||
unsigned long avg_apply_nb_cfg_tm;
|
uint64_t avg_apply_nb_cfg_tm;
|
||||||
|
|
||||||
struct mgmt_be_txns_head txn_head;
|
struct mgmt_be_txns_head txn_head;
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ struct mgmt_be_client {
|
||||||
|
|
||||||
struct debug mgmt_dbg_be_client = {
|
struct debug mgmt_dbg_be_client = {
|
||||||
.conf = "debug mgmt client backend",
|
.conf = "debug mgmt client backend",
|
||||||
.desc = "Management backend client operations"
|
.desc = "Management backend client operations",
|
||||||
};
|
};
|
||||||
|
|
||||||
/* NOTE: only one client per proc for now. */
|
/* NOTE: only one client per proc for now. */
|
||||||
|
@ -621,7 +621,7 @@ static int mgmt_be_txn_cfg_prepare(struct mgmt_be_txn_ctx *txn)
|
||||||
mgmt_be_send_cfgdata_create_reply(client_ctx, txn->txn_id,
|
mgmt_be_send_cfgdata_create_reply(client_ctx, txn->txn_id,
|
||||||
error ? false : true, error ? err_buf : NULL);
|
error ? false : true, error ? err_buf : NULL);
|
||||||
|
|
||||||
debug_be_client("Avg-nb-edit-duration %lu uSec, nb-prep-duration %lu (avg: %lu) uSec, batch size %u",
|
debug_be_client("Avg-nb-edit-duration %Lu uSec, nb-prep-duration %lu (avg: %Lu) uSec, batch size %u",
|
||||||
client_ctx->avg_edit_nb_cfg_tm, prep_nb_cfg_tm,
|
client_ctx->avg_edit_nb_cfg_tm, prep_nb_cfg_tm,
|
||||||
client_ctx->avg_prep_nb_cfg_tm, (uint32_t)num_processed);
|
client_ctx->avg_prep_nb_cfg_tm, (uint32_t)num_processed);
|
||||||
|
|
||||||
|
@ -770,10 +770,9 @@ static int mgmt_be_txn_proc_cfgapply(struct mgmt_be_txn_ctx *txn)
|
||||||
gettimeofday(&apply_nb_cfg_end, NULL);
|
gettimeofday(&apply_nb_cfg_end, NULL);
|
||||||
|
|
||||||
apply_nb_cfg_tm = timeval_elapsed(apply_nb_cfg_end, apply_nb_cfg_start);
|
apply_nb_cfg_tm = timeval_elapsed(apply_nb_cfg_end, apply_nb_cfg_start);
|
||||||
client_ctx->avg_apply_nb_cfg_tm = ((client_ctx->avg_apply_nb_cfg_tm *
|
client_ctx->avg_apply_nb_cfg_tm =
|
||||||
client_ctx->num_apply_nb_cfg) +
|
((client_ctx->avg_apply_nb_cfg_tm * client_ctx->num_apply_nb_cfg) + apply_nb_cfg_tm) /
|
||||||
apply_nb_cfg_tm) /
|
(client_ctx->num_apply_nb_cfg + 1);
|
||||||
(client_ctx->num_apply_nb_cfg + 1);
|
|
||||||
client_ctx->num_apply_nb_cfg++;
|
client_ctx->num_apply_nb_cfg++;
|
||||||
txn->nb_txn = NULL;
|
txn->nb_txn = NULL;
|
||||||
|
|
||||||
|
@ -789,8 +788,8 @@ static int mgmt_be_txn_proc_cfgapply(struct mgmt_be_txn_ctx *txn)
|
||||||
|
|
||||||
mgmt_be_send_apply_reply(client_ctx, txn->txn_id, true, NULL);
|
mgmt_be_send_apply_reply(client_ctx, txn->txn_id, true, NULL);
|
||||||
|
|
||||||
debug_be_client("Nb-apply-duration %lu (avg: %lu) uSec",
|
debug_be_client("Nb-apply-duration %lu (avg: %Lu) uSec", apply_nb_cfg_tm,
|
||||||
apply_nb_cfg_tm, client_ctx->avg_apply_nb_cfg_tm);
|
client_ctx->avg_apply_nb_cfg_tm);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1333,6 +1332,190 @@ DEFPY(debug_mgmt_client_be, debug_mgmt_client_be_cmd,
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath: /frr-backend:clients/client
|
||||||
|
*
|
||||||
|
* We only implement a list of one entry (for the this backend client) the
|
||||||
|
* results will be merged inside mgmtd.
|
||||||
|
*/
|
||||||
|
static const void *clients_client_get_next(struct nb_cb_get_next_args *args)
|
||||||
|
{
|
||||||
|
if (args->list_entry == NULL)
|
||||||
|
return __be_client;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clients_client_get_keys(struct nb_cb_get_keys_args *args)
|
||||||
|
{
|
||||||
|
args->keys->num = 1;
|
||||||
|
strlcpy(args->keys->key[0], __be_client->name, sizeof(args->keys->key[0]));
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const void *clients_client_lookup_entry(struct nb_cb_lookup_entry_args *args)
|
||||||
|
{
|
||||||
|
const char *name = args->keys->key[0];
|
||||||
|
|
||||||
|
if (!strcmp(name, __be_client->name))
|
||||||
|
return __be_client;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath: /frr-backend:clients/client/name
|
||||||
|
*/
|
||||||
|
static enum nb_error clients_client_name_get(const struct nb_node *nb_node,
|
||||||
|
const void *parent_list_entry, struct lyd_node *parent)
|
||||||
|
{
|
||||||
|
const struct lysc_node *snode = nb_node->snode;
|
||||||
|
LY_ERR err;
|
||||||
|
|
||||||
|
err = lyd_new_term(parent, snode->module, snode->name, __be_client->name, false, NULL);
|
||||||
|
if (err != LY_SUCCESS)
|
||||||
|
return NB_ERR_RESOURCE;
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath: /frr-backend:clients/client/state/candidate-config-version
|
||||||
|
*/
|
||||||
|
static enum nb_error clients_client_state_candidate_config_version_get(
|
||||||
|
const struct nb_node *nb_node, const void *parent_list_entry, struct lyd_node *parent)
|
||||||
|
{
|
||||||
|
const struct lysc_node *snode = nb_node->snode;
|
||||||
|
uint64_t value = __be_client->candidate_config->version;
|
||||||
|
|
||||||
|
if (lyd_new_term_bin(parent, snode->module, snode->name, &value, sizeof(value),
|
||||||
|
LYD_NEW_PATH_UPDATE, NULL))
|
||||||
|
return NB_ERR_RESOURCE;
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath: /frr-backend:clients/client/state/running-config-version
|
||||||
|
*/
|
||||||
|
static enum nb_error clients_client_state_running_config_version_get(const struct nb_node *nb_node,
|
||||||
|
const void *parent_list_entry,
|
||||||
|
struct lyd_node *parent)
|
||||||
|
{
|
||||||
|
const struct lysc_node *snode = nb_node->snode;
|
||||||
|
uint64_t value = __be_client->running_config->version;
|
||||||
|
|
||||||
|
if (lyd_new_term_bin(parent, snode->module, snode->name, &value, sizeof(value),
|
||||||
|
LYD_NEW_PATH_UPDATE, NULL))
|
||||||
|
return NB_ERR_RESOURCE;
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath: /frr-backend:clients/client/state/notify-selectors
|
||||||
|
*
|
||||||
|
* Is this better in northbound_notif.c? Let's decide when we add more to this module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static enum nb_error clients_client_state_notify_selectors_get(const struct nb_node *nb_node,
|
||||||
|
const void *parent_list_entry,
|
||||||
|
struct lyd_node *parent)
|
||||||
|
{
|
||||||
|
const struct lysc_node *snode = nb_node->snode;
|
||||||
|
const char **p;
|
||||||
|
LY_ERR err;
|
||||||
|
|
||||||
|
darr_foreach_p (nb_notif_filters, p) {
|
||||||
|
err = lyd_new_term(parent, snode->module, snode->name, *p, false, NULL);
|
||||||
|
if (err != LY_SUCCESS)
|
||||||
|
return NB_ERR_RESOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
const struct frr_yang_module_info frr_backend_info = {
|
||||||
|
.name = "frr-backend",
|
||||||
|
.nodes = {
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client",
|
||||||
|
.cbs = {
|
||||||
|
.get_next = clients_client_get_next,
|
||||||
|
.get_keys = clients_client_get_keys,
|
||||||
|
.lookup_entry = clients_client_lookup_entry,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client/name",
|
||||||
|
.cbs.get = clients_client_name_get,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client/state/candidate-config-version",
|
||||||
|
.cbs = {
|
||||||
|
.get = clients_client_state_candidate_config_version_get,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client/state/running-config-version",
|
||||||
|
.cbs = {
|
||||||
|
.get = clients_client_state_running_config_version_get,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client/state/edit-count",
|
||||||
|
.cbs = {
|
||||||
|
.get = nb_oper_uint64_get,
|
||||||
|
.get_elem = (void *)(intptr_t)offsetof(struct mgmt_be_client, num_edit_nb_cfg),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client/state/avg-edit-time",
|
||||||
|
.cbs = {
|
||||||
|
.get = nb_oper_uint64_get,
|
||||||
|
.get_elem = (void *)(intptr_t)offsetof(struct mgmt_be_client, avg_edit_nb_cfg_tm),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client/state/prep-count",
|
||||||
|
.cbs = {
|
||||||
|
.get = nb_oper_uint64_get,
|
||||||
|
.get_elem = (void *)(intptr_t)offsetof(struct mgmt_be_client, num_prep_nb_cfg),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client/state/avg-prep-time",
|
||||||
|
.cbs = {
|
||||||
|
.get = nb_oper_uint64_get,
|
||||||
|
.get_elem = (void *)(intptr_t)offsetof(struct mgmt_be_client, avg_prep_nb_cfg_tm),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client/state/apply-count",
|
||||||
|
.cbs = {
|
||||||
|
.get = nb_oper_uint64_get,
|
||||||
|
.get_elem = (void *)(intptr_t)offsetof(struct mgmt_be_client, num_apply_nb_cfg),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client/state/avg-apply-time",
|
||||||
|
.cbs = {
|
||||||
|
.get = nb_oper_uint64_get,
|
||||||
|
.get_elem = (void *)(intptr_t)offsetof(struct mgmt_be_client, avg_apply_nb_cfg_tm),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-backend:clients/client/state/notify-selectors",
|
||||||
|
.cbs.get = clients_client_state_notify_selectors_get,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = NULL,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
struct mgmt_be_client *mgmt_be_client_create(const char *client_name,
|
struct mgmt_be_client *mgmt_be_client_create(const char *client_name,
|
||||||
struct mgmt_be_client_cbs *cbs,
|
struct mgmt_be_client_cbs *cbs,
|
||||||
uintptr_t user_data,
|
uintptr_t user_data,
|
||||||
|
|
|
@ -85,6 +85,8 @@ struct mgmt_be_client_cbs {
|
||||||
|
|
||||||
extern struct debug mgmt_dbg_be_client;
|
extern struct debug mgmt_dbg_be_client;
|
||||||
|
|
||||||
|
extern const struct frr_yang_module_info frr_backend_info;
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
* API prototypes
|
* API prototypes
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
|
@ -836,6 +836,9 @@ extern struct debug nb_dbg_libyang;
|
||||||
/* Global running configuration. */
|
/* Global running configuration. */
|
||||||
extern struct nb_config *running_config;
|
extern struct nb_config *running_config;
|
||||||
|
|
||||||
|
/* Global notification filters */
|
||||||
|
extern const char **nb_notif_filters;
|
||||||
|
|
||||||
/* Wrappers for the northbound callbacks. */
|
/* Wrappers for the northbound callbacks. */
|
||||||
extern struct yang_data *nb_callback_has_new_get_elem(const struct nb_node *nb_node);
|
extern struct yang_data *nb_callback_has_new_get_elem(const struct nb_node *nb_node);
|
||||||
|
|
||||||
|
@ -1521,6 +1524,13 @@ extern void *nb_oper_walk_finish_arg(void *walk);
|
||||||
*/
|
*/
|
||||||
extern void *nb_oper_walk_cb_arg(void *walk);
|
extern void *nb_oper_walk_cb_arg(void *walk);
|
||||||
|
|
||||||
|
/* Generic getter functions */
|
||||||
|
extern enum nb_error nb_oper_uint32_get(const struct nb_node *nb_node,
|
||||||
|
const void *parent_list_entry, struct lyd_node *parent);
|
||||||
|
|
||||||
|
extern enum nb_error nb_oper_uint64_get(const struct nb_node *nb_node,
|
||||||
|
const void *parent_list_entry, struct lyd_node *parent);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate if the northbound callback operation is valid for the given node.
|
* Validate if the northbound callback operation is valid for the given node.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1918,6 +1918,87 @@ enum nb_error nb_oper_iterate_legacy(const char *xpath,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *__adjust_ptr(struct lysc_node_leaf *lsnode, const char *valuep, size_t *size)
|
||||||
|
{
|
||||||
|
switch (lsnode->type->basetype) {
|
||||||
|
case LY_TYPE_INT8:
|
||||||
|
case LY_TYPE_UINT8:
|
||||||
|
#ifdef BIG_ENDIAN
|
||||||
|
valuep += 7;
|
||||||
|
#endif
|
||||||
|
*size = 1;
|
||||||
|
break;
|
||||||
|
case LY_TYPE_INT16:
|
||||||
|
case LY_TYPE_UINT16:
|
||||||
|
#ifdef BIG_ENDIAN
|
||||||
|
valuep += 6;
|
||||||
|
#endif
|
||||||
|
*size = 2;
|
||||||
|
break;
|
||||||
|
case LY_TYPE_INT32:
|
||||||
|
case LY_TYPE_UINT32:
|
||||||
|
#ifdef BIG_ENDIAN
|
||||||
|
valuep += 4;
|
||||||
|
#endif
|
||||||
|
*size = 4;
|
||||||
|
break;
|
||||||
|
case LY_TYPE_INT64:
|
||||||
|
case LY_TYPE_UINT64:
|
||||||
|
*size = 8;
|
||||||
|
break;
|
||||||
|
case LY_TYPE_UNKNOWN:
|
||||||
|
case LY_TYPE_BINARY:
|
||||||
|
case LY_TYPE_STRING:
|
||||||
|
case LY_TYPE_BITS:
|
||||||
|
case LY_TYPE_BOOL:
|
||||||
|
case LY_TYPE_DEC64:
|
||||||
|
case LY_TYPE_EMPTY:
|
||||||
|
case LY_TYPE_ENUM:
|
||||||
|
case LY_TYPE_IDENT:
|
||||||
|
case LY_TYPE_INST:
|
||||||
|
case LY_TYPE_LEAFREF:
|
||||||
|
case LY_TYPE_UNION:
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
return valuep;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum nb_error nb_oper_uint64_get(const struct nb_node *nb_node, const void *parent_list_entry,
|
||||||
|
struct lyd_node *parent)
|
||||||
|
{
|
||||||
|
struct lysc_node_leaf *lsnode = (struct lysc_node_leaf *)nb_node->snode;
|
||||||
|
struct lysc_node *snode = &lsnode->node;
|
||||||
|
ssize_t offset = (ssize_t)nb_node->cbs.get_elem;
|
||||||
|
uint64_t ubigval = *(uint64_t *)((char *)parent_list_entry + offset);
|
||||||
|
const char *valuep;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
valuep = __adjust_ptr(lsnode, (const char *)&ubigval, &size);
|
||||||
|
if (lyd_new_term_bin(parent, snode->module, snode->name, valuep, size, LYD_NEW_PATH_UPDATE,
|
||||||
|
NULL))
|
||||||
|
return NB_ERR_RESOURCE;
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum nb_error nb_oper_uint32_get(const struct nb_node *nb_node, const void *parent_list_entry,
|
||||||
|
struct lyd_node *parent)
|
||||||
|
{
|
||||||
|
struct lysc_node_leaf *lsnode = (struct lysc_node_leaf *)nb_node->snode;
|
||||||
|
struct lysc_node *snode = &lsnode->node;
|
||||||
|
ssize_t offset = (ssize_t)nb_node->cbs.get_elem;
|
||||||
|
uint64_t ubigval = *(uint64_t *)((char *)parent_list_entry + offset);
|
||||||
|
const char *valuep;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
valuep = __adjust_ptr(lsnode, (const char *)&ubigval, &size);
|
||||||
|
if (lyd_new_term_bin(parent, snode->module, snode->name, valuep, size, LYD_NEW_PATH_UPDATE,
|
||||||
|
NULL))
|
||||||
|
return NB_ERR_RESOURCE;
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void nb_oper_init(struct event_loop *loop)
|
void nb_oper_init(struct event_loop *loop)
|
||||||
{
|
{
|
||||||
event_loop = loop;
|
event_loop = loop;
|
||||||
|
|
|
@ -145,6 +145,7 @@ lib_libfrr_la_SOURCES = \
|
||||||
|
|
||||||
nodist_lib_libfrr_la_SOURCES = \
|
nodist_lib_libfrr_la_SOURCES = \
|
||||||
yang/frr-affinity-map.yang.c \
|
yang/frr-affinity-map.yang.c \
|
||||||
|
yang/frr-backend.yang.c \
|
||||||
yang/frr-filter.yang.c \
|
yang/frr-filter.yang.c \
|
||||||
yang/frr-if-rmap.yang.c \
|
yang/frr-if-rmap.yang.c \
|
||||||
yang/frr-interface.yang.c \
|
yang/frr-interface.yang.c \
|
||||||
|
|
|
@ -77,6 +77,7 @@ static const char *const zebra_config_xpaths[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const zebra_oper_xpaths[] = {
|
static const char *const zebra_oper_xpaths[] = {
|
||||||
|
"/frr-backend:clients",
|
||||||
"/frr-interface:lib/interface",
|
"/frr-interface:lib/interface",
|
||||||
"/frr-vrf:lib/vrf/frr-zebra:zebra",
|
"/frr-vrf:lib/vrf/frr-zebra:zebra",
|
||||||
"/frr-zebra:zebra",
|
"/frr-zebra:zebra",
|
||||||
|
@ -94,6 +95,7 @@ static const char *const ripd_config_xpaths[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
static const char *const ripd_oper_xpaths[] = {
|
static const char *const ripd_oper_xpaths[] = {
|
||||||
|
"/frr-backend:clients",
|
||||||
"/frr-ripd:ripd",
|
"/frr-ripd:ripd",
|
||||||
"/ietf-key-chain:key-chains",
|
"/ietf-key-chain:key-chains",
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -114,6 +116,7 @@ static const char *const ripngd_config_xpaths[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
static const char *const ripngd_oper_xpaths[] = {
|
static const char *const ripngd_oper_xpaths[] = {
|
||||||
|
"/frr-backend:clients",
|
||||||
"/frr-ripngd:ripngd",
|
"/frr-ripngd:ripngd",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
@ -130,6 +133,11 @@ static const char *const staticd_config_xpaths[] = {
|
||||||
"/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd",
|
"/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *const staticd_oper_xpaths[] = {
|
||||||
|
"/frr-backend:clients",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char *const *be_client_config_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {
|
static const char *const *be_client_config_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {
|
||||||
|
@ -151,6 +159,9 @@ static const char *const *be_client_oper_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_RIPNGD
|
#ifdef HAVE_RIPNGD
|
||||||
[MGMTD_BE_CLIENT_ID_RIPNGD] = ripngd_oper_xpaths,
|
[MGMTD_BE_CLIENT_ID_RIPNGD] = ripngd_oper_xpaths,
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STATICD
|
||||||
|
[MGMTD_BE_CLIENT_ID_STATICD] = staticd_oper_xpaths,
|
||||||
#endif
|
#endif
|
||||||
[MGMTD_BE_CLIENT_ID_ZEBRA] = zebra_oper_xpaths,
|
[MGMTD_BE_CLIENT_ID_ZEBRA] = zebra_oper_xpaths,
|
||||||
};
|
};
|
||||||
|
|
|
@ -159,6 +159,12 @@ const struct frr_yang_module_info ietf_netconf_with_defaults_info = {
|
||||||
* clients into mgmtd. The modules are used by libyang in order to support
|
* clients into mgmtd. The modules are used by libyang in order to support
|
||||||
* parsing binary data returns from the backend.
|
* parsing binary data returns from the backend.
|
||||||
*/
|
*/
|
||||||
|
const struct frr_yang_module_info frr_backend_client_info = {
|
||||||
|
.name = "frr-backend",
|
||||||
|
.ignore_cfg_cbs = true,
|
||||||
|
.nodes = { { .xpath = NULL } },
|
||||||
|
};
|
||||||
|
|
||||||
const struct frr_yang_module_info zebra_route_map_info = {
|
const struct frr_yang_module_info zebra_route_map_info = {
|
||||||
.name = "frr-zebra-route-map",
|
.name = "frr-zebra-route-map",
|
||||||
.ignore_cfg_cbs = true,
|
.ignore_cfg_cbs = true,
|
||||||
|
@ -183,6 +189,7 @@ static const struct frr_yang_module_info *const mgmt_yang_modules[] = {
|
||||||
/*
|
/*
|
||||||
* YANG module info used by backend clients get added here.
|
* YANG module info used by backend clients get added here.
|
||||||
*/
|
*/
|
||||||
|
&frr_backend_client_info,
|
||||||
|
|
||||||
&frr_zebra_cli_info,
|
&frr_zebra_cli_info,
|
||||||
&zebra_route_map_info,
|
&zebra_route_map_info,
|
||||||
|
|
|
@ -127,6 +127,7 @@ static struct frr_signal_t ripd_signals[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct frr_yang_module_info *const ripd_yang_modules[] = {
|
static const struct frr_yang_module_info *const ripd_yang_modules[] = {
|
||||||
|
&frr_backend_info,
|
||||||
&frr_filter_info,
|
&frr_filter_info,
|
||||||
&frr_interface_info,
|
&frr_interface_info,
|
||||||
&frr_ripd_info,
|
&frr_ripd_info,
|
||||||
|
|
|
@ -120,6 +120,7 @@ struct frr_signal_t ripng_signals[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct frr_yang_module_info *const ripngd_yang_modules[] = {
|
static const struct frr_yang_module_info *const ripngd_yang_modules[] = {
|
||||||
|
&frr_backend_info,
|
||||||
&frr_filter_info,
|
&frr_filter_info,
|
||||||
&frr_interface_info,
|
&frr_interface_info,
|
||||||
&frr_ripngd_info,
|
&frr_ripngd_info,
|
||||||
|
|
|
@ -107,6 +107,7 @@ struct frr_signal_t static_signals[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct frr_yang_module_info *const staticd_yang_modules[] = {
|
static const struct frr_yang_module_info *const staticd_yang_modules[] = {
|
||||||
|
&frr_backend_info,
|
||||||
&frr_interface_info,
|
&frr_interface_info,
|
||||||
&frr_vrf_info,
|
&frr_vrf_info,
|
||||||
&frr_routing_info,
|
&frr_routing_info,
|
||||||
|
|
102
yang/frr-backend.yang
Normal file
102
yang/frr-backend.yang
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
module frr-backend {
|
||||||
|
yang-version 1.1;
|
||||||
|
namespace "http://frrouting.org/yang/oper";
|
||||||
|
prefix frr-backend;
|
||||||
|
|
||||||
|
organization
|
||||||
|
"FRRouting";
|
||||||
|
contact
|
||||||
|
"FRR Users List: <mailto:frog@lists.frrouting.org>
|
||||||
|
FRR Development List: <mailto:dev@lists.frrouting.org>";
|
||||||
|
description
|
||||||
|
"This module defines a model for FRR backend management.
|
||||||
|
|
||||||
|
Copyright (c) 2024, LabN Consulting, L.L.C.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.";
|
||||||
|
|
||||||
|
revision 2024-12-29 {
|
||||||
|
description "Initial revision";
|
||||||
|
reference "FRR source code";
|
||||||
|
}
|
||||||
|
|
||||||
|
container clients {
|
||||||
|
config false;
|
||||||
|
description "The backend clients";
|
||||||
|
|
||||||
|
list client {
|
||||||
|
key name;
|
||||||
|
description "A backend client";
|
||||||
|
|
||||||
|
leaf name {
|
||||||
|
type string;
|
||||||
|
description "Name of the backend client";
|
||||||
|
}
|
||||||
|
|
||||||
|
container state {
|
||||||
|
description "FRR backend operational state";
|
||||||
|
|
||||||
|
leaf candidate-config-version {
|
||||||
|
type uint64;
|
||||||
|
description "Local candidate config version.";
|
||||||
|
}
|
||||||
|
leaf running-config-version {
|
||||||
|
type uint64;
|
||||||
|
description "Local running config version.";
|
||||||
|
}
|
||||||
|
leaf edit-count {
|
||||||
|
type uint64;
|
||||||
|
description "Number of config edits handled.";
|
||||||
|
}
|
||||||
|
leaf avg-edit-time {
|
||||||
|
type uint64;
|
||||||
|
description "Average edit time in microseconds.";
|
||||||
|
}
|
||||||
|
leaf prep-count {
|
||||||
|
type uint64;
|
||||||
|
description "Number of config preps handled.";
|
||||||
|
}
|
||||||
|
leaf avg-prep-time {
|
||||||
|
type uint64;
|
||||||
|
description "Average prep time in microseconds.";
|
||||||
|
}
|
||||||
|
leaf apply-count {
|
||||||
|
type uint64;
|
||||||
|
description "Number of config applies handled.";
|
||||||
|
}
|
||||||
|
leaf avg-apply-time {
|
||||||
|
type uint64;
|
||||||
|
description "Average apply time in microseconds.";
|
||||||
|
}
|
||||||
|
leaf-list notify-selectors {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"List of paths identifying which state to send change
|
||||||
|
notifications for.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ EXTRA_DIST += yang/embedmodel.py
|
||||||
# without problems, as seen in libfrr.
|
# without problems, as seen in libfrr.
|
||||||
|
|
||||||
dist_yangmodels_DATA += yang/frr-affinity-map.yang
|
dist_yangmodels_DATA += yang/frr-affinity-map.yang
|
||||||
|
dist_yangmodels_DATA += yang/frr-backend.yang
|
||||||
dist_yangmodels_DATA += yang/frr-filter.yang
|
dist_yangmodels_DATA += yang/frr-filter.yang
|
||||||
dist_yangmodels_DATA += yang/frr-module-translator.yang
|
dist_yangmodels_DATA += yang/frr-module-translator.yang
|
||||||
dist_yangmodels_DATA += yang/frr-nexthop.yang
|
dist_yangmodels_DATA += yang/frr-nexthop.yang
|
||||||
|
|
|
@ -287,6 +287,7 @@ struct frr_signal_t zebra_signals[] = {
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
static const struct frr_yang_module_info *const zebra_yang_modules[] = {
|
static const struct frr_yang_module_info *const zebra_yang_modules[] = {
|
||||||
|
&frr_backend_info,
|
||||||
&frr_filter_info,
|
&frr_filter_info,
|
||||||
&frr_interface_info,
|
&frr_interface_info,
|
||||||
&frr_route_map_info,
|
&frr_route_map_info,
|
||||||
|
|
Loading…
Reference in a new issue