summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/user/basic.rst14
-rw-r--r--doc/user/bgp.rst5
-rw-r--r--doc/user/pathd.rst2
-rw-r--r--isisd/isis_affinitymap.c30
-rw-r--r--lib/.gitignore1
-rw-r--r--lib/affinitymap.c44
-rw-r--r--lib/affinitymap.h8
-rw-r--r--lib/affinitymap_northbound.c26
-rw-r--r--lib/if.c2
-rw-r--r--lib/log_vty.c67
-rw-r--r--lib/mgmt_be_client.c2
-rw-r--r--lib/northbound.c63
-rw-r--r--lib/northbound.h25
-rw-r--r--lib/northbound_cli.c6
-rw-r--r--lib/northbound_confd.c2
-rw-r--r--lib/northbound_sysrepo.c2
-rw-r--r--lib/subdir.am10
-rw-r--r--mgmtd/mgmt_be_adapter.c64
-rw-r--r--mgmtd/mgmt_be_adapter.h4
-rw-r--r--mgmtd/mgmt_txn.c4
-rw-r--r--pathd/path_pcep_cli.c295
-rw-r--r--pceplib/pcep_session_logic_counters.c193
-rw-r--r--pceplib/pcep_utils_counters.c10
-rw-r--r--pceplib/pcep_utils_counters.h27
-rw-r--r--pceplib/test/pcep_utils_counters_test.c24
-rw-r--r--tests/topotests/bgp_evpn_mh/test_evpn_mh.py2
-rw-r--r--vtysh/.gitignore1
-rw-r--r--vtysh/subdir.am10
-rw-r--r--vtysh/vtysh.c2
-rw-r--r--yang/frr-affinity-map.yang11
-rw-r--r--yang/frr-zebra.yang5
-rw-r--r--zebra/interface.c54
-rw-r--r--zebra/zebra_affinitymap.c90
-rw-r--r--zebra/zebra_nb_config.c28
-rw-r--r--zebra/zebra_nhg.c3
-rw-r--r--zebra/zebra_nhg.h2
36 files changed, 649 insertions, 489 deletions
diff --git a/doc/user/basic.rst b/doc/user/basic.rst
index 4fd4f5f7c4..55b836e3b8 100644
--- a/doc/user/basic.rst
+++ b/doc/user/basic.rst
@@ -129,6 +129,20 @@ Basic Config Commands
deprecated ``log trap`` command) will be used. The ``no`` form of the command
disables logging to a file.
+.. clicmd:: log daemon DAEMON file [FILENAME [LEVEL]]
+
+ Configure file logging for a single FRR daemon. If you want to log
+ into a file, please specify ``filename`` as in this example:
+
+ ::
+
+ log daemon bgpd file /var/log/frr/bgpd.log informational
+
+ If the optional second argument specifying the logging level is not present,
+ the default logging level (typically debugging, but can be changed using the
+ deprecated ``log trap`` command) will be used. The ``no`` form of the command
+ disables logging to a file for a single FRR daemon.
+
.. clicmd:: log syslog [LEVEL]
Enable logging output to syslog. If the optional second argument specifying
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 11bd676740..232abfd745 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -1604,7 +1604,10 @@ Configuring Peers
Configure an unnumbered BGP peer. ``PEER`` should be an interface name. The
session will be established via IPv6 link locals. Use ``internal`` for iBGP
- and ``external`` for eBGP sessions, or specify an ASN if you wish.
+ and ``external`` for eBGP sessions, or specify an ASN if you wish. Finally
+ this connection type is meant for point to point connections. If you are
+ on an ethernet segment and attempt to use this with more than one bgp
+ neighbor, only one neighbor will come up, due to how this feature works.
.. clicmd:: neighbor PEER next-hop-self [force]
diff --git a/doc/user/pathd.rst b/doc/user/pathd.rst
index ba4c209a0d..2519ac4912 100644
--- a/doc/user/pathd.rst
+++ b/doc/user/pathd.rst
@@ -534,7 +534,7 @@ retrieved via PCEP a random number based name is generated.
Display PCC information.
-.. clicmd:: show sr-te pcep session [NAME]
+.. clicmd:: show sr-te pcep session [NAME] [json]
Display the information of a PCEP session, if not name is specified all the
sessions will be displayed.
diff --git a/isisd/isis_affinitymap.c b/isisd/isis_affinitymap.c
index 41bad0a7d9..595091db27 100644
--- a/isisd/isis_affinitymap.c
+++ b/isisd/isis_affinitymap.c
@@ -11,35 +11,6 @@
#ifndef FABRICD
-static bool isis_affinity_map_check_use(const char *affmap_name)
-{
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
- struct isis_area *area;
- struct listnode *area_node, *fa_node;
- struct flex_algo *fa;
- struct affinity_map *map;
- uint16_t pos;
-
- if (!isis)
- return false;
-
- map = affinity_map_get(affmap_name);
- pos = map->bit_position;
-
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, area_node, area)) {
- for (ALL_LIST_ELEMENTS_RO(area->flex_algos->flex_algos, fa_node,
- fa)) {
- if (admin_group_get(&fa->admin_group_exclude_any,
- pos) ||
- admin_group_get(&fa->admin_group_include_any,
- pos) ||
- admin_group_get(&fa->admin_group_include_all, pos))
- return true;
- }
- }
- return false;
-}
-
static void isis_affinity_map_update(const char *affmap_name, uint16_t old_pos,
uint16_t new_pos)
{
@@ -90,7 +61,6 @@ void isis_affinity_map_init(void)
{
affinity_map_init();
- affinity_map_set_check_use_hook(isis_affinity_map_check_use);
affinity_map_set_update_hook(isis_affinity_map_update);
}
diff --git a/lib/.gitignore b/lib/.gitignore
index 6176b30f8d..5d38469ca2 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -11,3 +11,4 @@
/grammar_sandbox
/clippy
/defun_lex.c
+vtysh_daemons.h
diff --git a/lib/affinitymap.c b/lib/affinitymap.c
index 17e1b2cc01..e53d54a443 100644
--- a/lib/affinitymap.c
+++ b/lib/affinitymap.c
@@ -47,7 +47,7 @@ DEFINE_MTYPE_STATIC(LIB, AFFINITY_MAP_INDEX, "Affinity map index");
DEFINE_QOBJ_TYPE(affinity_maps);
DEFINE_QOBJ_TYPE(affinity_map);
-struct affinity_maps affinity_map_master = {NULL, NULL, NULL, NULL};
+struct affinity_maps affinity_map_master = {NULL, NULL};
static void affinity_map_free(struct affinity_map *map)
{
@@ -106,36 +106,6 @@ struct affinity_map *affinity_map_get(const char *name)
return NULL;
}
-
-char *affinity_map_name_get(int pos)
-{
- struct listnode *node;
- struct affinity_map *map;
-
- if (!affinity_map_master.maps)
- return NULL;
-
- for (ALL_LIST_ELEMENTS_RO(affinity_map_master.maps, node, map))
- if (map->bit_position == pos)
- return map->name;
- return NULL;
-}
-
-bool affinity_map_check_use_hook(const char *affmap_name)
-{
- if (affinity_map_master.check_use_hook)
- return (*affinity_map_master.check_use_hook)(affmap_name);
- return false;
-}
-
-bool affinity_map_check_update_hook(const char *affmap_name, uint16_t new_pos)
-{
- if (affinity_map_master.check_update_hook)
- return (*affinity_map_master.check_update_hook)(affmap_name,
- new_pos);
- return true;
-}
-
void affinity_map_update_hook(const char *affmap_name, uint16_t new_pos)
{
struct affinity_map *map;
@@ -153,18 +123,6 @@ void affinity_map_update_hook(const char *affmap_name, uint16_t new_pos)
new_pos);
}
-
-void affinity_map_set_check_use_hook(bool (*func)(const char *affmap_name))
-{
- affinity_map_master.check_use_hook = func;
-}
-
-void affinity_map_set_check_update_hook(bool (*func)(const char *affmap_name,
- uint16_t new_pos))
-{
- affinity_map_master.check_update_hook = func;
-}
-
void affinity_map_set_update_hook(void (*func)(const char *affmap_name,
uint16_t old_pos,
uint16_t new_pos))
diff --git a/lib/affinitymap.h b/lib/affinitymap.h
index 19edf5a269..f5924ca3ef 100644
--- a/lib/affinitymap.h
+++ b/lib/affinitymap.h
@@ -50,8 +50,6 @@ DECLARE_QOBJ_TYPE(affinity_map);
struct affinity_maps {
struct list *maps;
- bool (*check_use_hook)(const char *affmap_name);
- bool (*check_update_hook)(const char *affmap_name, uint16_t new_pos);
void (*update_hook)(const char *affmap_name, uint16_t old_pos,
uint16_t new_pos);
@@ -64,15 +62,9 @@ extern const struct frr_yang_module_info frr_affinity_map_info;
void affinity_map_set(const char *name, int pos);
void affinity_map_unset(const char *name);
struct affinity_map *affinity_map_get(const char *name);
-char *affinity_map_name_get(const int pos);
-bool affinity_map_check_use_hook(const char *affmap_name);
-bool affinity_map_check_update_hook(const char *affmap_name, uint16_t new_pos);
void affinity_map_update_hook(const char *affmap_name, uint16_t new_pos);
-void affinity_map_set_check_use_hook(bool (*func)(const char *affmap_name));
-void affinity_map_set_check_update_hook(bool (*func)(const char *affmap_name,
- uint16_t new_pos));
void affinity_map_set_update_hook(void (*func)(const char *affmap_name,
uint16_t old_pos,
uint16_t new_pos));
diff --git a/lib/affinitymap_northbound.c b/lib/affinitymap_northbound.c
index 331075f5c1..9daccc2800 100644
--- a/lib/affinitymap_northbound.c
+++ b/lib/affinitymap_northbound.c
@@ -47,11 +47,6 @@ static int lib_affinity_map_destroy(struct nb_cb_destroy_args *args)
switch (args->event) {
case NB_EV_VALIDATE:
- if (!affinity_map_check_use_hook(name))
- break;
- snprintf(args->errmsg, args->errmsg_len,
- "affinity-map %s is used", name);
- return NB_ERR_VALIDATION;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
@@ -68,7 +63,6 @@ static int lib_affinity_map_destroy(struct nb_cb_destroy_args *args)
static int lib_affinity_map_value_modify(struct nb_cb_modify_args *args)
{
const char *name;
- char *map_name;
uint16_t pos;
name = yang_dnode_get_string(
@@ -79,20 +73,6 @@ static int lib_affinity_map_value_modify(struct nb_cb_modify_args *args)
switch (args->event) {
case NB_EV_VALIDATE:
- map_name = affinity_map_name_get(pos);
- if (map_name &&
- strncmp(map_name, name, AFFINITY_NAME_SIZE) != 0) {
- snprintf(args->errmsg, args->errmsg_len,
- "bit-position is used by %s.", map_name);
- return NB_ERR_VALIDATION;
- }
- if (!affinity_map_check_update_hook(name, pos)) {
- snprintf(
- args->errmsg, args->errmsg_len,
- "affinity-map new bit-position > 31 but is used with standard admin-groups");
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
@@ -105,11 +85,6 @@ static int lib_affinity_map_value_modify(struct nb_cb_modify_args *args)
return NB_OK;
}
-static int lib_affinity_map_value_destroy(struct nb_cb_destroy_args *args)
-{
- return NB_OK;
-}
-
/* clang-format off */
const struct frr_yang_module_info frr_affinity_map_info = {
.name = "frr-affinity-map",
@@ -126,7 +101,6 @@ const struct frr_yang_module_info frr_affinity_map_info = {
.xpath = "/frr-affinity-map:lib/affinity-maps/affinity-map/value",
.cbs = {
.modify = lib_affinity_map_value_modify,
- .destroy = lib_affinity_map_value_destroy,
}
},
{
diff --git a/lib/if.c b/lib/if.c
index 1328e21874..1a8195de67 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -1135,7 +1135,7 @@ struct if_link_params *if_link_params_enable(struct interface *ifp)
iflp->unrsv_bw[i] = iflp->default_bw;
/* Update Link parameters status */
- iflp->lp_status = LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
+ iflp->lp_status = LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW | LP_EXTEND_ADM_GRP;
/* Set TE metric equal to standard metric only if it is set */
if (ifp->metric != 0) {
diff --git a/lib/log_vty.c b/lib/log_vty.c
index fc298533ae..1ce25196da 100644
--- a/lib/log_vty.c
+++ b/lib/log_vty.c
@@ -15,6 +15,7 @@
#include "lib/lib_errors.h"
#include "lib/printfrr.h"
#include "lib/systemd.h"
+#include "lib/vtysh_daemons.h"
#include "lib/log_vty_clippy.c"
@@ -459,6 +460,70 @@ DEFUN (clear_log_cmdline,
return CMD_SUCCESS;
}
+/* Per-daemon log file config */
+DEFUN (config_log_dmn_file,
+ config_log_dmn_file_cmd,
+ "log daemon " DAEMONS_LIST " file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
+ "Logging control\n"
+ "Specific daemon\n"
+ DAEMONS_STR
+ "Logging to file\n"
+ "Logging filename\n"
+ LOG_LEVEL_DESC)
+{
+ int level = log_default_lvl;
+ int idx = 0;
+ const char *d_str;
+ const char *filename;
+ const char *levelarg = NULL;
+
+ d_str = argv[2]->text;
+
+ /* Ignore if not for this daemon */
+ if (!strmatch(d_str, frr_get_progname()))
+ return CMD_SUCCESS;
+
+ if (argv_find(argv, argc, "file", &idx))
+ filename = argv[idx + 1]->arg;
+ else
+ return CMD_SUCCESS;
+
+ if (argc > 5)
+ levelarg = argv[5]->text;
+
+ if (levelarg) {
+ level = log_level_match(levelarg);
+ if (level == ZLOG_DISABLED)
+ return CMD_ERR_NO_MATCH;
+ }
+ return set_log_file(&zt_file, vty, filename, level);
+}
+
+/* Per-daemon no log file */
+DEFUN (no_config_log_dmn_file,
+ no_config_log_dmn_file_cmd,
+ "no log daemon " DAEMONS_LIST " file [FILENAME [LEVEL]]",
+ NO_STR
+ "Logging control\n"
+ "Specific daemon\n"
+ DAEMONS_STR
+ "Cancel logging to file\n"
+ "Logging file name\n"
+ "Logging level\n")
+{
+ const char *d_str;
+
+ d_str = argv[3]->text;
+
+ /* Ignore if not for this daemon */
+ if (!strmatch(d_str, frr_get_progname()))
+ return CMD_SUCCESS;
+
+ zt_file.prio_min = ZLOG_DISABLED;
+ zlog_file_set_other(&zt_file);
+ return CMD_SUCCESS;
+}
+
DEFPY (config_log_file,
config_log_file_cmd,
"log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
@@ -904,6 +969,8 @@ void log_cmd_init(void)
install_element(CONFIG_NODE, &config_log_monitor_cmd);
install_element(CONFIG_NODE, &no_config_log_monitor_cmd);
install_element(CONFIG_NODE, &config_log_file_cmd);
+ install_element(CONFIG_NODE, &config_log_dmn_file_cmd);
+ install_element(CONFIG_NODE, &no_config_log_dmn_file_cmd);
install_element(CONFIG_NODE, &no_config_log_file_cmd);
install_element(CONFIG_NODE, &config_log_syslog_cmd);
install_element(CONFIG_NODE, &no_config_log_syslog_cmd);
diff --git a/lib/mgmt_be_client.c b/lib/mgmt_be_client.c
index 16aea249a4..d50dd03fdc 100644
--- a/lib/mgmt_be_client.c
+++ b/lib/mgmt_be_client.c
@@ -449,7 +449,7 @@ static int mgmt_be_txn_cfg_prepare(struct mgmt_be_txn_ctx *txn)
client_ctx->candidate_config,
txn_req->req.set_cfg.cfg_changes,
(size_t)txn_req->req.set_cfg.num_cfg_changes,
- NULL, err_buf, sizeof(err_buf), &error);
+ NULL, true, err_buf, sizeof(err_buf), &error);
if (error) {
err_buf[sizeof(err_buf) - 1] = 0;
MGMTD_BE_CLIENT_ERR(
diff --git a/lib/northbound.c b/lib/northbound.c
index 42e4ebbcc9..a831fc58b2 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -157,12 +157,21 @@ void nb_nodes_delete(void)
struct nb_node *nb_node_find(const char *path)
{
const struct lysc_node *snode;
+ uint32_t llopts;
/*
* Use libyang to find the schema node associated to the path and get
- * the northbound node from there (snode private pointer).
+ * the northbound node from there (snode private pointer). We need to
+ * disable logging temporarily to avoid libyang from logging an error
+ * message when the node is not found.
*/
+ llopts = ly_log_options(LY_LOSTORE);
+ llopts &= ~LY_LOLOG;
+ ly_temp_log_options(&llopts);
+
snode = yang_find_snode(ly_native_ctx, path, 0);
+
+ ly_temp_log_options(NULL);
if (!snode)
return NULL;
@@ -408,10 +417,9 @@ static inline int nb_config_cb_compare(const struct nb_config_cb *a,
}
RB_GENERATE(nb_config_cbs, nb_config_cb, entry, nb_config_cb_compare);
-static void nb_config_diff_add_change(struct nb_config_cbs *changes,
- enum nb_cb_operation operation,
- uint32_t *seq,
- const struct lyd_node *dnode)
+void nb_config_diff_add_change(struct nb_config_cbs *changes,
+ enum nb_cb_operation operation, uint32_t *seq,
+ const struct lyd_node *dnode)
{
struct nb_config_change *change;
@@ -685,20 +693,25 @@ static int dnode_create(struct nb_config *candidate, const char *xpath,
return NB_OK;
}
-int nb_candidate_edit(struct nb_config *candidate,
- const struct nb_node *nb_node,
+int nb_candidate_edit(struct nb_config *candidate, const struct nb_node *nb_node,
enum nb_operation operation, const char *xpath,
- const struct yang_data *previous,
+ bool in_backend, const struct yang_data *previous,
const struct yang_data *data)
{
- struct lyd_node *dnode, *dep_dnode, *old_dnode, *parent;
+ struct lyd_node *dnode, *dep_dnode, *old_dnode;
char xpath_edit[XPATH_MAXLEN];
char dep_xpath[XPATH_MAXLEN];
+ struct lyd_node *parent = NULL;
uint32_t options = 0;
LY_ERR err;
- /* Use special notation for leaf-lists (RFC 6020, section 9.13.5). */
- if (nb_node->snode->nodetype == LYS_LEAFLIST)
+ /*
+ * Use special notation for leaf-lists (RFC 6020, section 9.13.5).
+ * if we are in a backend client this notation was already applied
+ * by mgmtd before sending to us.
+ */
+ if (!in_backend && nb_node->snode->nodetype == LYS_LEAFLIST &&
+ (operation == NB_OP_DESTROY || operation == NB_OP_DELETE))
snprintf(xpath_edit, sizeof(xpath_edit), "%s[.='%s']", xpath,
data->value);
else
@@ -829,10 +842,12 @@ bool nb_is_operation_allowed(struct nb_node *nb_node, enum nb_operation oper)
return true;
}
-void nb_candidate_edit_config_changes(
- struct nb_config *candidate_config, struct nb_cfg_change cfg_changes[],
- size_t num_cfg_changes, const char *xpath_base, char *err_buf,
- int err_bufsize, bool *error)
+void nb_candidate_edit_config_changes(struct nb_config *candidate_config,
+ struct nb_cfg_change cfg_changes[],
+ size_t num_cfg_changes,
+ const char *xpath_base, bool in_backend,
+ char *err_buf, int err_bufsize,
+ bool *error)
{
if (error)
*error = false;
@@ -861,10 +876,17 @@ void nb_candidate_edit_config_changes(
/* Find the northbound node associated to the data path. */
nb_node = nb_node_find(xpath);
if (!nb_node) {
- flog_warn(EC_LIB_YANG_UNKNOWN_DATA_PATH,
- "%s: unknown data path: %s", __func__, xpath);
- if (error)
- *error = true;
+ if (in_backend)
+ DEBUGD(&nb_dbg_cbs_config,
+ "%s: ignoring non-handled path: %s",
+ __func__, xpath);
+ else {
+ flog_warn(EC_LIB_YANG_UNKNOWN_DATA_PATH,
+ "%s: unknown data path: %s", __func__,
+ xpath);
+ if (error)
+ *error = true;
+ }
continue;
}
/* Find if the node to be edited is not a key node */
@@ -886,7 +908,8 @@ void nb_candidate_edit_config_changes(
* configuration.
*/
ret = nb_candidate_edit(candidate_config, nb_node,
- change->operation, xpath, NULL, data);
+ change->operation, xpath, in_backend,
+ NULL, data);
yang_data_free(data);
if (ret != NB_OK) {
flog_warn(
diff --git a/lib/northbound.h b/lib/northbound.h
index 4f9ab565d9..0a6bc88921 100644
--- a/lib/northbound.h
+++ b/lib/northbound.h
@@ -950,6 +950,9 @@ extern bool nb_is_operation_allowed(struct nb_node *nb_node,
* xpath
* XPath of the configuration node being edited.
*
+ * in_backend
+ * Specify whether the changes are being applied in the backend or not.
+ *
* previous
* Previous value of the configuration node. Should be used only when the
* operation is NB_OP_MOVE, otherwise this parameter is ignored.
@@ -964,7 +967,7 @@ extern bool nb_is_operation_allowed(struct nb_node *nb_node,
extern int nb_candidate_edit(struct nb_config *candidate,
const struct nb_node *nb_node,
enum nb_operation operation, const char *xpath,
- const struct yang_data *previous,
+ bool in_backend, const struct yang_data *previous,
const struct yang_data *data);
/*
@@ -1009,6 +1012,9 @@ extern bool nb_candidate_needs_update(const struct nb_config *candidate);
* xpath_base
* Base xpath for config.
*
+ * in_backend
+ * Specify whether the changes are being applied in the backend or not.
+ *
* err_buf
* Buffer to store human-readable error message in case of error.
*
@@ -1018,11 +1024,18 @@ extern bool nb_candidate_needs_update(const struct nb_config *candidate);
* error
* TRUE on error, FALSE on success
*/
-extern void nb_candidate_edit_config_changes(
- struct nb_config *candidate_config, struct nb_cfg_change cfg_changes[],
- size_t num_cfg_changes, const char *xpath_base, char *err_buf,
- int err_bufsize, bool *error);
-
+extern void nb_candidate_edit_config_changes(struct nb_config *candidate_config,
+ struct nb_cfg_change cfg_changes[],
+ size_t num_cfg_changes,
+ const char *xpath_base,
+ bool in_backend, char *err_buf,
+ int err_bufsize, bool *error);
+
+
+extern void nb_config_diff_add_change(struct nb_config_cbs *changes,
+ enum nb_cb_operation operation,
+ uint32_t *seq,
+ const struct lyd_node *dnode);
/*
* Delete candidate configuration changes.
*
diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c
index 92d4ffb2ba..0358a0f377 100644
--- a/lib/northbound_cli.c
+++ b/lib/northbound_cli.c
@@ -146,9 +146,9 @@ static int nb_cli_apply_changes_internal(struct vty *vty,
VTY_CHECK_XPATH;
- nb_candidate_edit_config_changes(
- vty->candidate_config, vty->cfg_changes, vty->num_cfg_changes,
- xpath_base, buf, sizeof(buf), &error);
+ nb_candidate_edit_config_changes(vty->candidate_config, vty->cfg_changes,
+ vty->num_cfg_changes, xpath_base,
+ false, buf, sizeof(buf), &error);
if (error) {
/*
* Failure to edit the candidate configuration should never
diff --git a/lib/northbound_confd.c b/lib/northbound_confd.c
index 8503d18002..c866b0afb4 100644
--- a/lib/northbound_confd.c
+++ b/lib/northbound_confd.c
@@ -256,7 +256,7 @@ frr_confd_cdb_diff_iter(confd_hkeypath_t *kp, enum cdb_iter_op cdb_op,
/* Edit the candidate configuration. */
data = yang_data_new(xpath, value_str);
ret = nb_candidate_edit(iter_args->candidate, nb_node, nb_op, xpath,
- NULL, data);
+ false, NULL, data);
yang_data_free(data);
if (ret != NB_OK) {
flog_warn(
diff --git a/lib/northbound_sysrepo.c b/lib/northbound_sysrepo.c
index 198d96e381..050477af91 100644
--- a/lib/northbound_sysrepo.c
+++ b/lib/northbound_sysrepo.c
@@ -219,7 +219,7 @@ static int frr_sr_process_change(struct nb_config *candidate,
sr_val_to_buff(sr_data, value_str, sizeof(value_str));
data = yang_data_new(xpath, value_str);
- ret = nb_candidate_edit(candidate, nb_node, nb_op, xpath, NULL, data);
+ ret = nb_candidate_edit(candidate, nb_node, nb_op, xpath, false, NULL, data);
yang_data_free(data);
if (ret != NB_OK) {
flog_warn(
diff --git a/lib/subdir.am b/lib/subdir.am
index 4f203c0c84..6893049c7e 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -540,12 +540,22 @@ EXTRA_DIST += \
BUILT_SOURCES += \
lib/gitversion.h \
lib/route_types.h \
+ lib/vtysh_daemons.h \
# end
## force route_types.h
$(lib_clippy_OBJECTS): lib/route_types.h
$(lib_libfrr_la_OBJECTS): lib/route_types.h
+# force lib_daemons.h
+$(lib_libfrr_la_OBJECTS): lib/vtysh_daemons.h
+
+CLEANFILES += lib/vtysh_daemons.h
+lib/vtysh_daemons.h:
+ @$(MKDIR_P) lib
+ $(PERL) $(top_srcdir)/vtysh/daemons.pl $(vtysh_daemons) > lib/vtysh_daemons.h
+
+
AM_YFLAGS = -d -Dapi.prefix=@BISON_OPENBRACE@cmd_yy@BISON_CLOSEBRACE@ @BISON_VERBOSE@
lib/command_lex.h: lib/command_lex.c
diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c
index 2be70901a8..c8f52a101c 100644
--- a/mgmtd/mgmt_be_adapter.c
+++ b/mgmtd/mgmt_be_adapter.c
@@ -598,20 +598,6 @@ struct mgmt_be_get_adapter_config_params {
};
/*
- * Callback to store the change a node in the datastore if it should be sync'd
- * to the adapter (i.e., if the adapter is subscribed to it).
- */
-static void mgmt_be_iter_and_get_cfg(const char *xpath, struct lyd_node *node,
- struct nb_node *nb_node, void *ctx)
-{
- struct mgmt_be_get_adapter_config_params *parms = ctx;
- struct mgmt_be_client_adapter *adapter = parms->adapter;
-
- if (be_is_client_interested(xpath, adapter->id, true))
- nb_config_diff_created(node, &parms->seq, parms->cfg_chgs);
-}
-
-/*
* Initialize a BE client over a new connection
*/
static void mgmt_be_adapter_conn_init(struct event *thread)
@@ -769,32 +755,32 @@ void mgmt_be_adapter_toggle_client_debug(bool set)
* Get a full set of changes for all the config that an adapter is subscribed to
* receive.
*/
-int mgmt_be_get_adapter_config(struct mgmt_be_client_adapter *adapter,
- struct nb_config_cbs **cfg_chgs)
-{
- struct mgmt_be_get_adapter_config_params parms;
- struct nb_config *cfg_root = mgmt_ds_get_nb_config(mm->running_ds);
-
- assert(cfg_chgs);
-
- /*
- * TODO: we should consider making this an assertable condition and
- * guaranteeing it be true when this function is called. B/c what is
- * going to happen if there are some changes being sent, and we don't
- * gather a new snapshot, what new changes that came after the previous
- * snapshot will then be lost?
- */
- if (RB_EMPTY(nb_config_cbs, &adapter->cfg_chgs)) {
- parms.adapter = adapter;
- parms.cfg_chgs = &adapter->cfg_chgs;
- parms.seq = 0;
-
- mgmt_ds_iter_data(MGMTD_DS_RUNNING, cfg_root, "",
- mgmt_be_iter_and_get_cfg, (void *)&parms);
+void mgmt_be_get_adapter_config(struct mgmt_be_client_adapter *adapter,
+ struct nb_config_cbs **changes)
+{
+ const struct lyd_node *root, *dnode;
+ uint32_t seq = 0;
+ char *xpath;
+
+ /* We can't be in the middle of sending other chgs when here. */
+ assert(RB_EMPTY(nb_config_cbs, &adapter->cfg_chgs));
+
+ *changes = &adapter->cfg_chgs;
+ LY_LIST_FOR (running_config->dnode, root) {
+ LYD_TREE_DFS_BEGIN (root, dnode) {
+ if (lysc_is_key(dnode->schema))
+ goto walk_cont;
+
+ xpath = lyd_path(dnode, LYD_PATH_STD, NULL, 0);
+ if (be_is_client_interested(xpath, adapter->id, true))
+ nb_config_diff_add_change(*changes, NB_CB_CREATE, &seq, dnode);
+ else
+ LYD_TREE_DFS_continue = 1; /* skip any subtree */
+ free(xpath);
+ walk_cont:
+ LYD_TREE_DFS_END(root, dnode);
+ }
}
-
- *cfg_chgs = &adapter->cfg_chgs;
- return 0;
}
uint64_t mgmt_be_interested_clients(const char *xpath, bool config)
diff --git a/mgmtd/mgmt_be_adapter.h b/mgmtd/mgmt_be_adapter.h
index 96e807f6c4..3407d4c6a7 100644
--- a/mgmtd/mgmt_be_adapter.h
+++ b/mgmtd/mgmt_be_adapter.h
@@ -157,8 +157,8 @@ extern const char *mgmt_be_client_id2name(enum mgmt_be_client_id id);
extern void mgmt_be_adapter_toggle_client_debug(bool set);
/* Fetch backend adapter config. */
-extern int mgmt_be_get_adapter_config(struct mgmt_be_client_adapter *adapter,
- struct nb_config_cbs **cfg_chgs);
+extern void mgmt_be_get_adapter_config(struct mgmt_be_client_adapter *adapter,
+ struct nb_config_cbs **changes);
/* Create/destroy a transaction. */
extern int mgmt_be_send_txn_req(struct mgmt_be_client_adapter *adapter,
diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c
index 842e13cf11..b4b67b4551 100644
--- a/mgmtd/mgmt_txn.c
+++ b/mgmtd/mgmt_txn.c
@@ -587,8 +587,8 @@ static void mgmt_txn_process_set_cfg(struct event *thread)
txn_req->req.set_cfg->cfg_changes,
(size_t)txn_req->req.set_cfg
->num_cfg_changes,
- NULL, err_buf, sizeof(err_buf),
- &error);
+ NULL, false, err_buf,
+ sizeof(err_buf), &error);
if (error) {
mgmt_fe_send_set_cfg_reply(txn->session_id, txn->txn_id,
txn_req->req.set_cfg->ds_id,
diff --git a/pathd/path_pcep_cli.c b/pathd/path_pcep_cli.c
index e0926ea62d..47a811d144 100644
--- a/pathd/path_pcep_cli.c
+++ b/pathd/path_pcep_cli.c
@@ -43,6 +43,8 @@
#define DEFAULT_TIMER_SESSION_TIMEOUT_INTERVAL 30
#define DEFAULT_DELEGATION_TIMEOUT_INTERVAL 10
+#define BUFFER_PCC_PCE_SIZE 1024
+
/* CLI Function declarations */
static int pcep_cli_debug_config_write(struct vty *vty);
static int pcep_cli_debug_set_all(uint32_t flags, bool set);
@@ -73,6 +75,9 @@ static void print_pcep_capabilities(char *buf, size_t buf_len,
pcep_configuration *config);
static void print_pcep_session(struct vty *vty, struct pce_opts *pce_opts,
struct pcep_pcc_info *pcc_info);
+static void print_pcep_session_json(struct vty *vty, struct pce_opts *pce_opts,
+ struct pcep_pcc_info *pcc_info,
+ json_object *json);
static bool pcep_cli_pcc_has_pce(const char *pce_name);
static void pcep_cli_add_pce_connection(struct pce_opts *pce_opts);
static void pcep_cli_remove_pce_connection(struct pce_opts *pce_opts);
@@ -1187,10 +1192,188 @@ static void print_pcep_capabilities(char *buf, size_t buf_len,
}
/* Internal util function to print a pcep session */
+static void print_pcep_session_json(struct vty *vty, struct pce_opts *pce_opts,
+ struct pcep_pcc_info *pcc_info,
+ json_object *json)
+{
+ char buf[BUFFER_PCC_PCE_SIZE] = {};
+ int index = 0;
+ pcep_session *session;
+ struct pcep_config_group_opts *config_opts;
+ struct counters_group *group;
+
+ /* PCE IP */
+ if (IS_IPADDR_V4(&pce_opts->addr))
+ json_object_string_addf(json, "pceAddress", "%pI4",
+ &pce_opts->addr.ipaddr_v4);
+ else if (IS_IPADDR_V6(&pce_opts->addr))
+ json_object_string_addf(json, "pceAddress", "%pI6",
+ &pce_opts->addr.ipaddr_v6);
+ json_object_int_add(json, "pcePort", pce_opts->port);
+
+ /* PCC IP */
+ if (IS_IPADDR_V4(&pcc_info->pcc_addr))
+ json_object_string_addf(json, "pccAddress", "%pI4",
+ &pcc_info->pcc_addr.ipaddr_v4);
+ else if (IS_IPADDR_V6(&pcc_info->pcc_addr))
+ json_object_string_addf(json, "pccAddress", "%pI6",
+ &pcc_info->pcc_addr.ipaddr_v6);
+
+ json_object_int_add(json, "pccPort", pcc_info->pcc_port);
+ json_object_int_add(json, "pccMsd", pcc_info->msd);
+
+ if (pcc_info->status == PCEP_PCC_OPERATING)
+ json_object_string_add(json, "sessionStatus", "UP");
+ else
+ json_object_string_add(json, "sessionStatus",
+ pcc_status_name(pcc_info->status));
+
+ json_object_boolean_add(json, "bestMultiPce",
+ pcc_info->is_best_multi_pce);
+ json_object_int_add(json, "precedence",
+ pcc_info->precedence > 0 ? pcc_info->precedence
+ : DEFAULT_PCE_PRECEDENCE);
+ json_object_string_add(json, "confidence",
+ pcc_info->previous_best ? "low" : "normal");
+
+ /* PCEPlib pcep session values, get a thread safe copy of the counters
+ */
+ session = pcep_ctrl_get_pcep_session(pcep_g->fpt, pcc_info->pcc_id);
+
+ /* Config Options values */
+ config_opts = &pce_opts->config_opts;
+ json_object_int_add(json, "keepaliveConfig",
+ config_opts->keep_alive_seconds);
+ json_object_int_add(json, "deadTimerConfig",
+ config_opts->dead_timer_seconds);
+ json_object_int_add(json, "pccPcepRequestTimerConfig",
+ config_opts->pcep_request_time_seconds);
+ json_object_int_add(json, "sessionTimeoutIntervalSec",
+ config_opts->session_timeout_inteval_seconds);
+ json_object_int_add(json, "delegationTimeout",
+ config_opts->delegation_timeout_seconds);
+ json_object_boolean_add(json, "tcpMd5Authentication",
+ (strlen(config_opts->tcp_md5_auth) > 0));
+ if (strlen(config_opts->tcp_md5_auth) > 0)
+ json_object_string_add(json, "tcpMd5AuthenticationString",
+ config_opts->tcp_md5_auth);
+ json_object_boolean_add(json, "draft07", !!config_opts->draft07);
+ json_object_boolean_add(json, "draft16AndRfc8408",
+ !config_opts->draft07);
+
+ json_object_int_add(json, "nextPcRequestId", pcc_info->next_reqid);
+ /* original identifier used by the PCC for LSP instantiation */
+ json_object_int_add(json, "nextPLspId", pcc_info->next_plspid);
+
+ if (session != NULL) {
+ json_object_int_add(json, "sessionKeepalivePceNegotiatedSec",
+ session->pcc_config
+ .keep_alive_pce_negotiated_timer_seconds);
+ json_object_int_add(json, "sessionDeadTimerPceNegotiatedSec",
+ session->pcc_config
+ .dead_timer_pce_negotiated_seconds);
+ if (pcc_info->status == PCEP_PCC_SYNCHRONIZING ||
+ pcc_info->status == PCEP_PCC_OPERATING) {
+ time_t current_time = time(NULL);
+ struct tm lt = { 0 };
+ /* Just for the timezone */
+ localtime_r(&current_time, &lt);
+ gmtime_r(&session->time_connected, &lt);
+ json_object_int_add(json, "sessionConnectionDurationSec",
+ (uint32_t)(current_time -
+ session->time_connected));
+ json_object_string_addf(json,
+ "sessionConnectionStartTimeUTC",
+ "%d-%02d-%02d %02d:%02d:%02d",
+ lt.tm_year + 1900, lt.tm_mon + 1,
+ lt.tm_mday, lt.tm_hour,
+ lt.tm_min, lt.tm_sec);
+ }
+
+ /* PCC capabilities */
+ buf[0] = '\0';
+
+ if (config_opts->pce_initiated)
+ index += csnprintfrr(buf, sizeof(buf), "%s",
+ PCEP_CLI_CAP_PCC_PCE_INITIATED);
+ else
+ index += csnprintfrr(buf, sizeof(buf), "%s",
+ PCEP_CLI_CAP_PCC_INITIATED);
+ print_pcep_capabilities(buf, sizeof(buf) - index,
+ &session->pcc_config);
+ json_object_string_add(json, "pccCapabilities", buf);
+
+ /* PCE capabilities */
+ buf[0] = '\0';
+ print_pcep_capabilities(buf, sizeof(buf), &session->pce_config);
+ if (buf[0] != '\0')
+ json_object_string_add(json, "pceCapabilities", buf);
+ XFREE(MTYPE_PCEP, session);
+ } else {
+ json_object_string_add(json, "warningSession",
+ "Detailed session information not available.");
+ }
+
+ /* Message Counters, get a thread safe copy of the counters */
+ group = pcep_ctrl_get_counters(pcep_g->fpt, pcc_info->pcc_id);
+
+ if (group != NULL) {
+ struct counters_subgroup *rx_msgs =
+ find_subgroup(group, COUNTER_SUBGROUP_ID_RX_MSG);
+ struct counters_subgroup *tx_msgs =
+ find_subgroup(group, COUNTER_SUBGROUP_ID_TX_MSG);
+ json_object *json_counter;
+ struct counter *tx_counter, *rx_counter;
+
+ if (rx_msgs != NULL) {
+ json_counter = json_object_new_object();
+ for (int i = 0; i < rx_msgs->max_counters; i++) {
+ rx_counter = rx_msgs->counters[i];
+
+ if (rx_counter &&
+ rx_counter->counter_name_json[0] != '\0')
+ json_object_int_add(
+ json_counter,
+ rx_counter->counter_name_json,
+ rx_counter->counter_value);
+ }
+ json_object_int_add(json_counter, "total",
+ subgroup_counters_total(rx_msgs));
+ json_object_object_add(json, "messageStatisticsReceived",
+ json_counter);
+ }
+ if (tx_msgs != NULL) {
+ json_counter = json_object_new_object();
+ for (int i = 0; i < tx_msgs->max_counters; i++) {
+ tx_counter = tx_msgs->counters[i];
+
+ if (tx_counter &&
+ tx_counter->counter_name_json[0] != '\0')
+ json_object_int_add(
+ json_counter,
+ tx_counter->counter_name_json,
+ tx_counter->counter_value);
+ }
+ json_object_int_add(json_counter, "total",
+ subgroup_counters_total(tx_msgs));
+ json_object_object_add(json, "messageStatisticsSent",
+ json_counter);
+ }
+ pcep_lib_free_counters(group);
+ } else {
+ json_object_string_add(json, "messageStatisticsWarning",
+ "Counters not available.");
+ }
+
+ XFREE(MTYPE_PCEP, pcc_info);
+}
+
+/* Internal util function to print a pcep session */
static void print_pcep_session(struct vty *vty, struct pce_opts *pce_opts,
struct pcep_pcc_info *pcc_info)
{
char buf[1024];
+
buf[0] = '\0';
vty_out(vty, "\nPCE %s\n", pce_opts->pce_name);
@@ -1241,6 +1424,7 @@ static void print_pcep_session(struct vty *vty, struct pce_opts *pce_opts,
/* Config Options values */
struct pcep_config_group_opts *config_opts = &pce_opts->config_opts;
+
if (session != NULL) {
vty_out(vty, " Timer: KeepAlive config %d, pce-negotiated %d\n",
config_opts->keep_alive_seconds,
@@ -1356,34 +1540,66 @@ static void print_pcep_session(struct vty *vty, struct pce_opts *pce_opts,
}
static int path_pcep_cli_show_srte_pcep_session(struct vty *vty,
- const char *pcc_peer)
+ const char *pcc_peer, bool uj)
{
struct pce_opts_cli *pce_opts_cli;
struct pcep_pcc_info *pcc_info;
+ json_object *json = NULL;
+
+ if (uj)
+ json = json_object_new_object();
/* Only show 1 PCEP session */
if (pcc_peer != NULL) {
+ if (json)
+ json_object_string_add(json, "pceName", pcc_peer);
pce_opts_cli = pcep_cli_find_pce(pcc_peer);
if (pce_opts_cli == NULL) {
- vty_out(vty, "%% PCE [%s] does not exist.\n", pcc_peer);
+ if (json) {
+ json_object_string_addf(json, "warning",
+ "PCE [%s] does not exist.",
+ pcc_peer);
+ vty_json(vty, json);
+ } else
+ vty_out(vty, "%% PCE [%s] does not exist.\n",
+ pcc_peer);
return CMD_WARNING;
}
if (!pcep_cli_pcc_has_pce(pcc_peer)) {
- vty_out(vty, "%% PCC is not connected to PCE [%s].\n",
- pcc_peer);
+ if (json) {
+ json_object_string_addf(json, "warning",
+ "PCC is not connected to PCE [%s].",
+ pcc_peer);
+ vty_json(vty, json);
+ } else
+ vty_out(vty,
+ "%% PCC is not connected to PCE [%s].\n",
+ pcc_peer);
return CMD_WARNING;
}
pcc_info = pcep_ctrl_get_pcc_info(pcep_g->fpt, pcc_peer);
if (pcc_info == NULL) {
- vty_out(vty,
- "%% Cannot retrieve PCEP session info for PCE [%s]\n",
- pcc_peer);
+ if (json) {
+ json_object_string_addf(json, "warning",
+ "Cannot retrieve PCEP session info for PCE [%s].",
+ pcc_peer);
+ vty_json(vty, json);
+ } else
+ vty_out(vty,
+ "%% Cannot retrieve PCEP session info for PCE [%s]\n",
+ pcc_peer);
return CMD_WARNING;
}
- print_pcep_session(vty, &pce_opts_cli->pce_opts, pcc_info);
+ if (json) {
+ print_pcep_session_json(vty, &pce_opts_cli->pce_opts,
+ pcc_info, json);
+ vty_json(vty, json);
+ } else
+ print_pcep_session(vty, &pce_opts_cli->pce_opts,
+ pcc_info);
return CMD_SUCCESS;
}
@@ -1392,29 +1608,56 @@ static int path_pcep_cli_show_srte_pcep_session(struct vty *vty,
struct pce_opts *pce_opts;
int num_pcep_sessions_conf = 0;
int num_pcep_sessions_conn = 0;
+ json_object *json_array = NULL, *json_entry = NULL;
+
+ if (json)
+ json_array = json_object_new_array();
for (int i = 0; i < MAX_PCC; i++) {
pce_opts = pce_connections_g.connections[i];
if (pce_opts == NULL) {
continue;
}
+ if (json) {
+ json_entry = json_object_new_object();
+ json_object_string_add(json_entry, "pceName",
+ pce_opts->pce_name);
+ }
pcc_info =
pcep_ctrl_get_pcc_info(pcep_g->fpt, pce_opts->pce_name);
if (pcc_info == NULL) {
- vty_out(vty,
- "%% Cannot retrieve PCEP session info for PCE [%s]\n",
- pce_opts->pce_name);
+ if (json_entry) {
+ json_object_string_addf(json_entry, "warning",
+ "Cannot retrieve PCEP session info for PCE [%s].",
+ pce_opts->pce_name);
+ json_object_array_add(json_array, json_entry);
+ } else
+ vty_out(vty,
+ "%% Cannot retrieve PCEP session info for PCE [%s]\n",
+ pce_opts->pce_name);
continue;
}
num_pcep_sessions_conn +=
pcc_info->status == PCEP_PCC_OPERATING ? 1 : 0;
num_pcep_sessions_conf++;
- print_pcep_session(vty, pce_opts, pcc_info);
- }
-
- vty_out(vty, "PCEP Sessions => Configured %d ; Connected %d\n",
- num_pcep_sessions_conf, num_pcep_sessions_conn);
+ if (json_entry) {
+ print_pcep_session_json(vty, pce_opts, pcc_info,
+ json_entry);
+ json_object_array_add(json_array, json_entry);
+ } else
+ print_pcep_session(vty, pce_opts, pcc_info);
+ }
+ if (json) {
+ json_object_object_add(json, "pcepSessions", json_array);
+ json_object_int_add(json, "pcepSessionsConfigured",
+ num_pcep_sessions_conf);
+ json_object_int_add(json, "pcepSessionsConnected",
+ num_pcep_sessions_conn);
+ vty_json(vty, json);
+ } else
+ vty_out(vty, "PCEP Sessions => Configured %d ; Connected %d\n",
+ num_pcep_sessions_conf, num_pcep_sessions_conn);
return CMD_SUCCESS;
}
@@ -2091,14 +2334,27 @@ DEFPY(pcep_cli_show_srte_pcc,
DEFPY(pcep_cli_show_srte_pcep_session,
pcep_cli_show_srte_pcep_session_cmd,
- "show sr-te pcep session [WORD]$pce",
+ "show sr-te pcep session WORD$pce [json$uj]",
SHOW_STR
"SR-TE info\n"
"PCEP info\n"
"Show PCEP Session information\n"
- "PCE name\n")
+ "PCE name\n"
+ JSON_STR)
+{
+ return path_pcep_cli_show_srte_pcep_session(vty, pce, !!uj);
+}
+
+DEFPY(pcep_cli_show_srte_pcep_sessions,
+ pcep_cli_show_srte_pcep_sessions_cmd,
+ "show sr-te pcep session [json$uj]",
+ SHOW_STR
+ "SR-TE info\n"
+ "PCEP info\n"
+ "Show PCEP Session information\n"
+ JSON_STR)
{
- return path_pcep_cli_show_srte_pcep_session(vty, pce);
+ return path_pcep_cli_show_srte_pcep_session(vty, NULL, !!uj);
}
DEFPY(pcep_cli_clear_srte_pcep_session,
@@ -2172,5 +2428,6 @@ void pcep_cli_init(void)
install_element(ENABLE_NODE, &pcep_cli_show_srte_pcep_pce_config_cmd);
install_element(ENABLE_NODE, &pcep_cli_show_srte_pcep_pce_cmd);
install_element(ENABLE_NODE, &pcep_cli_show_srte_pcep_session_cmd);
+ install_element(ENABLE_NODE, &pcep_cli_show_srte_pcep_sessions_cmd);
install_element(ENABLE_NODE, &pcep_cli_clear_srte_pcep_session_cmd);
}
diff --git a/pceplib/pcep_session_logic_counters.c b/pceplib/pcep_session_logic_counters.c
index 6f6f2a0df4..b12b8ab0e0 100644
--- a/pceplib/pcep_session_logic_counters.c
+++ b/pceplib/pcep_session_logic_counters.c
@@ -36,30 +36,30 @@ void create_session_counters(pcep_session *session)
struct counters_subgroup *rx_msg_subgroup = create_counters_subgroup(
"RX Message counters", COUNTER_SUBGROUP_ID_RX_MSG,
PCEP_TYPE_MAX + 1);
- create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_OPEN,
- "Message Open");
+ create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_OPEN, "Message Open",
+ "messageOpen");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_KEEPALIVE,
- "Message KeepAlive");
+ "Message KeepAlive", "messageKeepalive");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_PCREQ,
- "Message PcReq");
+ "Message PcReq", "messagePcReq");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_PCREP,
- "Message PcRep");
+ "Message PcRep", "messagePcRep");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_PCNOTF,
- "Message Notify");
+ "Message Notify", "messageNotify");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_ERROR,
- "Message Error");
+ "Message Error", "messageError");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_CLOSE,
- "Message Close");
+ "Message Close", "messageClose");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_REPORT,
- "Message Report");
+ "Message Report", "messageReport");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_UPDATE,
- "Message Update");
+ "Message Update", "messageUpdate");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_INITIATE,
- "Message Initiate");
+ "Message Initiate", "messageInitiate");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_START_TLS,
- "Message StartTls");
+ "Message StartTls", "messageStartTls");
create_subgroup_counter(rx_msg_subgroup, PCEP_TYPE_MAX,
- "Message Erroneous");
+ "Message Erroneous", "messageErroneous");
struct counters_subgroup *tx_msg_subgroup =
clone_counters_subgroup(rx_msg_subgroup, "TX Message counters",
@@ -74,59 +74,61 @@ void create_session_counters(pcep_session *session)
struct counters_subgroup *rx_obj_subgroup = create_counters_subgroup(
"RX Object counters", COUNTER_SUBGROUP_ID_RX_OBJ, 100);
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_OPEN,
- "Object Open");
- create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_RP,
- "Object RP");
+ "Object Open", "objectOpen");
+ create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_RP, "Object RP",
+ "objectRP");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_NOPATH,
- "Object Nopath");
- create_subgroup_counter(
- rx_obj_subgroup,
- ((PCEP_OBJ_CLASS_ENDPOINTS << 4) | PCEP_OBJ_TYPE_ENDPOINT_IPV4),
- "Object Endpoint IPv4");
- create_subgroup_counter(
- rx_obj_subgroup,
- ((PCEP_OBJ_CLASS_ENDPOINTS << 4) | PCEP_OBJ_TYPE_ENDPOINT_IPV6),
- "Object Endpoint IPv6");
+ "Object Nopath", "objectNopath");
+ create_subgroup_counter(rx_obj_subgroup,
+ ((PCEP_OBJ_CLASS_ENDPOINTS << 4) |
+ PCEP_OBJ_TYPE_ENDPOINT_IPV4),
+ "Object Endpoint IPv4", "objectEndpointIPv4");
+ create_subgroup_counter(rx_obj_subgroup,
+ ((PCEP_OBJ_CLASS_ENDPOINTS << 4) |
+ PCEP_OBJ_TYPE_ENDPOINT_IPV6),
+ "Object Endpoint IPv6", "objectEndpointIPv6");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_BANDWIDTH,
- "Object Bandwidth");
+ "Object Bandwidth", "objectBandwidth");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_METRIC,
- "Object Metric");
+ "Object Metric", "objectMetric");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_ERO,
- "Object ERO");
+ "Object ERO", "objectERO");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_RRO,
- "Object RRO");
+ "Object RRO", "objectRRO");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_LSPA,
- "Object LSPA");
+ "Object LSPA", "objectLSPA");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_IRO,
- "Object IRO");
+ "Object IRO", "objectIRO");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_SVEC,
- "Object SVEC");
+ "Object SVEC", "objectSVEC");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_NOTF,
- "Object Notify");
+ "Object Notify", "objectNotify");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_ERROR,
- "Object Error");
+ "Object Error", "objectError");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_CLOSE,
- "Object Close");
+ "Object Close", "objectClose");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_LSP,
- "Object LSP");
+ "Object LSP", "objectLSP");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_SRP,
- "Object SRP");
+ "Object SRP", "objectSRP");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_VENDOR_INFO,
- "Object Vendor Info");
+ "Object Vendor Info", "objectVendorInfo");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_INTER_LAYER,
- "Object Inter-Layer");
+ "Object Inter-Layer", "objectInterLayer");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_SWITCH_LAYER,
- "Object Switch-Layer");
+ "Object Switch-Layer", "objectSwitchLayer");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_REQ_ADAP_CAP,
- "Object Requested Adap-Cap");
+ "Object Requested Adap-Cap",
+ "objectRequestedAdapCap");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_SERVER_IND,
- "Object Server-Indication");
+ "Object Server-Indication",
+ "objectServerIndication");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_ASSOCIATION,
- "Object Association");
+ "Object Association", "objectAssociation");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_MAX,
- "Object Unknown");
+ "Object Unknown", "objectUnknown");
create_subgroup_counter(rx_obj_subgroup, PCEP_OBJ_CLASS_MAX + 1,
- "Object Erroneous");
+ "Object Erroneous", "objectErroneous");
struct counters_subgroup *tx_obj_subgroup =
clone_counters_subgroup(rx_obj_subgroup, "TX Object counters",
@@ -139,21 +141,22 @@ void create_session_counters(pcep_session *session)
"RX RO Sub-Object counters", COUNTER_SUBGROUP_ID_RX_SUBOBJ,
RO_SUBOBJ_UNKNOWN + 2);
create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_IPV4,
- "RO Sub-Object IPv4");
+ "RO Sub-Object IPv4", "ROSubObjectIPv4");
create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_IPV6,
- "RO Sub-Object IPv6");
+ "RO Sub-Object IPv6", "ROSubObjectIPv6");
create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_LABEL,
- "RO Sub-Object Label");
+ "RO Sub-Object Label", "ROSubObjectLabel");
create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_UNNUM,
- "RO Sub-Object Unnum");
+ "RO Sub-Object Unnum", "ROSubObjectUnnum");
create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_ASN,
- "RO Sub-Object ASN");
+ "RO Sub-Object ASN", "ROSubObjectASN");
create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_TYPE_SR,
- "RO Sub-Object SR");
+ "RO Sub-Object SR", "ROSubObjectSR");
create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_UNKNOWN,
- "RO Sub-Object Unknown");
+ "RO Sub-Object Unknown", "ROSubObjectUnknown");
create_subgroup_counter(rx_subobj_subgroup, RO_SUBOBJ_UNKNOWN + 1,
- "RO Sub-Object Erroneous");
+ "RO Sub-Object Erroneous",
+ "ROSubObjectErroneous");
struct counters_subgroup *tx_subobj_subgroup = clone_counters_subgroup(
rx_subobj_subgroup, "TX RO Sub-Object counters",
@@ -168,28 +171,36 @@ void create_session_counters(pcep_session *session)
PCEP_SR_SUBOBJ_NAI_UNKNOWN + 1);
create_subgroup_counter(rx_subobj_sr_nai_subgroup,
PCEP_SR_SUBOBJ_NAI_ABSENT,
- "RO Sub-Object SR NAI absent");
+ "RO Sub-Object SR NAI absent",
+ "ROSubObjectSRNAIAbsent");
create_subgroup_counter(rx_subobj_sr_nai_subgroup,
PCEP_SR_SUBOBJ_NAI_IPV4_NODE,
- "RO Sub-Object SR NAI IPv4 Node");
+ "RO Sub-Object SR NAI IPv4 Node",
+ "ROSubObjectSRNAIIPv4Node");
create_subgroup_counter(rx_subobj_sr_nai_subgroup,
PCEP_SR_SUBOBJ_NAI_IPV6_NODE,
- "RO Sub-Object SR NAI IPv6 Node");
+ "RO Sub-Object SR NAI IPv6 Node",
+ "ROSubObjectSRNAIIPv6Node");
create_subgroup_counter(rx_subobj_sr_nai_subgroup,
PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY,
- "RO Sub-Object SR NAI IPv4 Adj");
+ "RO Sub-Object SR NAI IPv4 Adj",
+ "ROSubObjectSRNAIIPv4Adj");
create_subgroup_counter(rx_subobj_sr_nai_subgroup,
PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY,
- "RO Sub-Object SR NAI IPv6 Adj");
+ "RO Sub-Object SR NAI IPv6 Adj",
+ "ROSubObjectSRNAIIPv6Adj");
create_subgroup_counter(rx_subobj_sr_nai_subgroup,
PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY,
- "RO Sub-Object SR NAI Unnumbered IPv4 Adj");
+ "RO Sub-Object SR NAI Unnumbered IPv4 Adj",
+ "ROSubObjectSRNAIUnnumberedIPv4Adj");
create_subgroup_counter(rx_subobj_sr_nai_subgroup,
PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY,
- "RO Sub-Object SR NAI Link Local IPv6 Adj");
+ "RO Sub-Object SR NAI Link Local IPv6 Adj",
+ "ROSubObjectSRNAILinkLocalIPv6Adj");
create_subgroup_counter(rx_subobj_sr_nai_subgroup,
PCEP_SR_SUBOBJ_NAI_UNKNOWN,
- "RO Sub-Object SR NAI Unknown");
+ "RO Sub-Object SR NAI Unknown",
+ "ROSubObjectSRNAIUnknown");
struct counters_subgroup *tx_subobj_sr_nai_subgroup =
clone_counters_subgroup(rx_subobj_sr_nai_subgroup,
@@ -204,56 +215,60 @@ void create_session_counters(pcep_session *session)
PCEP_OBJ_TLV_TYPE_UNKNOWN + 1);
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR,
- "TLV No Path Vector");
+ "TLV No Path Vector", "TLVNoPathVector");
create_subgroup_counter(rx_tlv_subgroup, PCEP_OBJ_TLV_TYPE_VENDOR_INFO,
- "TLV Vendor Info");
+ "TLV Vendor Info", "TLVVendorInfo");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY,
- "TLV Stateful PCE Capability");
+ "TLV Stateful PCE Capability",
+ "TLVStatefulPCCapability");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME,
- "TLV Symbolic Path Name");
+ "TLV Symbolic Path Name", "TLVSymbolicPathName");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS,
- "TLV IPv4 LSP Identifier");
+ "TLV IPv4 LSP Identifier",
+ "TLVIPv4LSPIdentifier");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS,
- "TLV IPv6 LSP Identifier");
+ "TLV IPv6 LSP Identifier",
+ "TLVIPv6LSPIdentifier");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE,
- "TLV LSP Error Code");
+ "TLV LSP Error Code", "TLVLSPErrorCode");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC,
- "TLV RSVP Error Spec");
+ "TLV RSVP Error Spec", "TLVRSVPErrorSpec");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION,
- "TLV LSP DB Version");
+ "TLV LSP DB Version", "TLVLSPDBVersion");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID,
- "TLV Speaker Entity ID");
+ "TLV Speaker Entity ID", "TLVSpeakerEntityId");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY,
- "TLV SR PCE Capability");
+ "TLV SR PCE Capability", "TLVSRPCECapability");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE,
- "TLV Path Setup Type");
+ "TLV Path Setup Type", "TLVPathSetupType");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY,
- "TLV Path Setup Type Capability");
+ "TLV Path Setup Type Capability",
+ "TLVPathSetupTypeCapability");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID,
- "TLV SR Policy PolId");
+ "TLV SR Policy PolId", "TLVSRPolicyPolId");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME,
- "TLV SR Policy PolName");
+ "TLV SR Policy PolName", "TLVSRPolicyPolName");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID,
- "TLV SR Policy CpathId");
+ "TLV SR Policy CpathId", "TLVSRPolicyCpathId");
create_subgroup_counter(rx_tlv_subgroup,
PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE,
- "TLV SR Policy CpathRef");
+ "TLV SR Policy CpathRef", "TLVSRPolicyCpathRef");
create_subgroup_counter(rx_tlv_subgroup, PCEP_OBJ_TLV_TYPE_UNKNOWN,
- "TLV Unknown");
+ "TLV Unknown", "TLVUnknown");
struct counters_subgroup *tx_tlv_subgroup = clone_counters_subgroup(
rx_tlv_subgroup, "TX TLV counters", COUNTER_SUBGROUP_ID_TX_TLV);
@@ -265,28 +280,32 @@ void create_session_counters(pcep_session *session)
"Events counters", COUNTER_SUBGROUP_ID_EVENT, MAX_COUNTERS);
create_subgroup_counter(events_subgroup,
PCEP_EVENT_COUNTER_ID_PCC_CONNECT,
- "PCC connect");
+ "PCC connect", "PCCConnect");
create_subgroup_counter(events_subgroup,
PCEP_EVENT_COUNTER_ID_PCE_CONNECT,
- "PCE connect");
+ "PCE connect", "PCEConnect");
create_subgroup_counter(events_subgroup,
PCEP_EVENT_COUNTER_ID_PCC_DISCONNECT,
- "PCC disconnect");
+ "PCC disconnect", "PCCDisconnect");
create_subgroup_counter(events_subgroup,
PCEP_EVENT_COUNTER_ID_PCE_DISCONNECT,
- "PCE disconnect");
+ "PCE disconnect", "PCEDisconnect");
create_subgroup_counter(events_subgroup,
PCEP_EVENT_COUNTER_ID_TIMER_KEEPALIVE,
- "Timer KeepAlive expired");
+ "Timer KeepAlive expired",
+ "timerKeepAliveExpired");
create_subgroup_counter(events_subgroup,
PCEP_EVENT_COUNTER_ID_TIMER_DEADTIMER,
- "Timer DeadTimer expired");
+ "Timer DeadTimer expired",
+ "timerDeadTimerExpired");
create_subgroup_counter(events_subgroup,
PCEP_EVENT_COUNTER_ID_TIMER_OPENKEEPWAIT,
- "Timer OpenKeepWait expired");
+ "Timer OpenKeepWait expired",
+ "timerOpenKeepWaitExpired");
create_subgroup_counter(events_subgroup,
PCEP_EVENT_COUNTER_ID_TIMER_OPENKEEPALIVE,
- "Timer OpenKeepAlive expired");
+ "Timer OpenKeepAlive expired",
+ "timerOpenKeepAliveExpired");
/*
* Create the parent counters group
diff --git a/pceplib/pcep_utils_counters.c b/pceplib/pcep_utils_counters.c
index badef9351a..1ab341c69c 100644
--- a/pceplib/pcep_utils_counters.c
+++ b/pceplib/pcep_utils_counters.c
@@ -139,7 +139,8 @@ clone_counters_subgroup(struct counters_subgroup *subgroup,
if (counter != NULL) {
create_subgroup_counter(cloned_subgroup,
counter->counter_id,
- counter->counter_name);
+ counter->counter_name,
+ counter->counter_name_json);
}
}
@@ -180,7 +181,8 @@ bool add_counters_subgroup(struct counters_group *group,
}
bool create_subgroup_counter(struct counters_subgroup *subgroup,
- uint32_t counter_id, const char *counter_name)
+ uint32_t counter_id, const char *counter_name,
+ const char *counter_name_json)
{
if (subgroup == NULL) {
pcep_log(
@@ -212,7 +214,9 @@ bool create_subgroup_counter(struct counters_subgroup *subgroup,
counter->counter_id = counter_id;
strlcpy(counter->counter_name, counter_name,
sizeof(counter->counter_name));
-
+ if (counter_name_json)
+ strlcpy(counter->counter_name_json, counter_name_json,
+ sizeof(counter->counter_name_json));
subgroup->num_counters++;
subgroup->counters[counter->counter_id] = counter;
diff --git a/pceplib/pcep_utils_counters.h b/pceplib/pcep_utils_counters.h
index 755c94eb0c..dfae02fb2e 100644
--- a/pceplib/pcep_utils_counters.h
+++ b/pceplib/pcep_utils_counters.h
@@ -55,18 +55,18 @@ extern "C" {
* *events_subgroup = create_counters_subgroup("events counters", 4);
*
* Use message_id: PCEP_TYPE_OPEN=1
- * create_subgroup_counter(rx_subgroup, 1, "Message Open");
- * create_subgroup_counter(rx_subgroup, 2, "Message KeepAlive");
- * create_subgroup_counter(rx_subgroup, 3, "Message PcReq");
+ * create_subgroup_counter(rx_subgroup, 1, "Message Open", "messageOpen");
+ * create_subgroup_counter(rx_subgroup, 2, "Message KeepAlive", "messageKeepAlive");
+ * create_subgroup_counter(rx_subgroup, 3, "Message PcReq", "messagePcReq");
*
- * create_subgroup_counter(tx_subgroup, 1, "Message Open");
- * create_subgroup_counter(tx_subgroup, 2, "Message KeepAlive");
- * create_subgroup_counter(tx_subgroup, 3, "Message PcReq");
+ * create_subgroup_counter(tx_subgroup, 1, "Message Open", "messageOpen");
+ * create_subgroup_counter(tx_subgroup, 2, "Message KeepAlive", "messageKeepAlive");
+ * create_subgroup_counter(tx_subgroup, 3, "Message PcReq", "messagePcReq");
*
- * create_subgroup_counter(events_subgroup, 1, "PCC Connect");
- * create_subgroup_counter(events_subgroup, 2, "PCE Connect");
- * create_subgroup_counter(events_subgroup, 3, "PCC Disconnect");
- * create_subgroup_counter(events_subgroup, 4, "PCE Disconnect");
+ * create_subgroup_counter(events_subgroup, 1, "PCC Connect", "PCConnect");
+ * create_subgroup_counter(events_subgroup, 2, "PCE Connect", "PCEConnect");
+ * create_subgroup_counter(events_subgroup, 3, "PCC Disconnect", "PCCDisconnect");
+ * create_subgroup_counter(events_subgroup, 4, "PCE Disconnect", "PCEDisconnect");
*
* struct counters_group *cntrs_group = create_counters_group("PCEP Counters",
* 3); add_counters_subgroup(cntrs_group, rx_subgroup);
@@ -81,6 +81,7 @@ extern "C" {
struct counter {
uint16_t counter_id;
char counter_name[MAX_COUNTER_STR_LENGTH];
+ char counter_name_json[MAX_COUNTER_STR_LENGTH];
uint32_t counter_value;
};
@@ -142,13 +143,15 @@ clone_counters_subgroup(struct counters_subgroup *subgroup,
const char *subgroup_name, uint16_t subgroup_id);
/*
- * Create a counter in a subgroup with the given counter_id and counter_name.
+ * Create a counter in a subgroup with the given counter_id and counter_name
+ * and counter_name_json.
* The counter_id is 0-based.
* Return true on success or false if subgroup is NULL, counter_id >=
* MAX_COUNTERS, or if counter_name is NULL.
*/
bool create_subgroup_counter(struct counters_subgroup *subgroup,
- uint32_t counter_id, const char *counter_name);
+ uint32_t counter_id, const char *counter_name,
+ const char *couter_name_json);
/*
* Delete the counters_group and recursively delete all subgroups and their
diff --git a/pceplib/test/pcep_utils_counters_test.c b/pceplib/test/pcep_utils_counters_test.c
index 2cad9a6443..d3d5197b53 100644
--- a/pceplib/test/pcep_utils_counters_test.c
+++ b/pceplib/test/pcep_utils_counters_test.c
@@ -106,17 +106,19 @@ void test_create_subgroup_counter()
{
uint16_t counter_id = 1;
char counter_name[] = "my counter";
+ char counter_name_json[] = "myCounter";
struct counters_subgroup *subgroup =
create_counters_subgroup("subgroup", 1, 2);
- CU_ASSERT_FALSE(
- create_subgroup_counter(NULL, counter_id, counter_name));
+ CU_ASSERT_FALSE(create_subgroup_counter(NULL, counter_id, counter_name,
+ counter_name_json));
CU_ASSERT_FALSE(create_subgroup_counter(subgroup, counter_id + 1,
counter_name));
- CU_ASSERT_FALSE(create_subgroup_counter(subgroup, counter_id, NULL));
+ CU_ASSERT_FALSE(
+ create_subgroup_counter(subgroup, counter_id, NULL, NULL));
CU_ASSERT_EQUAL(subgroup->num_counters, 0);
- CU_ASSERT_TRUE(
- create_subgroup_counter(subgroup, counter_id, counter_name));
+ CU_ASSERT_TRUE(create_subgroup_counter(subgroup, counter_id,
+ counter_name, counter_name_json));
CU_ASSERT_EQUAL(subgroup->num_counters, 1);
delete_counters_subgroup(subgroup);
@@ -146,7 +148,7 @@ void test_reset_group_counters()
struct counters_group *group = create_counters_group("group", 10);
struct counters_subgroup *subgroup =
create_counters_subgroup("subgroup", subgroup_id, 10);
- create_subgroup_counter(subgroup, counter_id, "counter");
+ create_subgroup_counter(subgroup, counter_id, "counter", "counter");
add_counters_subgroup(group, subgroup);
struct counter *counter = subgroup->counters[counter_id];
@@ -164,7 +166,7 @@ void test_reset_subgroup_counters()
uint16_t counter_id = 1;
struct counters_subgroup *subgroup =
create_counters_subgroup("subgroup", 1, 10);
- create_subgroup_counter(subgroup, counter_id, "counter");
+ create_subgroup_counter(subgroup, counter_id, "counter", "counter");
struct counter *counter = subgroup->counters[counter_id];
counter->counter_value = 100;
@@ -183,7 +185,7 @@ void test_increment_counter()
struct counters_group *group = create_counters_group("group", 10);
struct counters_subgroup *subgroup =
create_counters_subgroup("subgroup", subgroup_id, 10);
- create_subgroup_counter(subgroup, counter_id, "counter");
+ create_subgroup_counter(subgroup, counter_id, "counter", "counter");
add_counters_subgroup(group, subgroup);
struct counter *counter = subgroup->counters[counter_id];
@@ -205,7 +207,7 @@ void test_increment_subgroup_counter()
uint32_t counter_value = 100;
struct counters_subgroup *subgroup =
create_counters_subgroup("subgroup", 1, 10);
- create_subgroup_counter(subgroup, counter_id, "counter");
+ create_subgroup_counter(subgroup, counter_id, "counter", "counter");
struct counter *counter = subgroup->counters[counter_id];
counter->counter_value = counter_value;
@@ -225,7 +227,7 @@ void test_dump_counters_group_to_log()
struct counters_group *group = create_counters_group("group", 10);
struct counters_subgroup *subgroup =
create_counters_subgroup("subgroup", subgroup_id, 10);
- create_subgroup_counter(subgroup, counter_id, "counter");
+ create_subgroup_counter(subgroup, counter_id, "counter", "counter");
add_counters_subgroup(group, subgroup);
CU_ASSERT_FALSE(dump_counters_group_to_log(NULL));
@@ -240,7 +242,7 @@ void test_dump_counters_subgroup_to_log()
uint16_t counter_id = 1;
struct counters_subgroup *subgroup =
create_counters_subgroup("subgroup", subgroup_id, 10);
- create_subgroup_counter(subgroup, counter_id, "counter");
+ create_subgroup_counter(subgroup, counter_id, "counter", "counter");
CU_ASSERT_FALSE(dump_counters_subgroup_to_log(NULL));
CU_ASSERT_TRUE(dump_counters_subgroup_to_log(subgroup));
diff --git a/tests/topotests/bgp_evpn_mh/test_evpn_mh.py b/tests/topotests/bgp_evpn_mh/test_evpn_mh.py
index ec5227809e..945c0383e7 100644
--- a/tests/topotests/bgp_evpn_mh/test_evpn_mh.py
+++ b/tests/topotests/bgp_evpn_mh/test_evpn_mh.py
@@ -264,7 +264,7 @@ def config_bridge(node):
node.run("ip link set dev bridge type bridge mcast_snooping 0")
node.run("ip link set dev bridge type bridge vlan_stats_enabled 1")
node.run("ip link set dev bridge up")
- node.run("/sbin/bridge vlan add vid 1000 dev bridge")
+ node.run("/sbin/bridge vlan add vid 1000 dev bridge self")
def config_vxlan(node, node_ip):
diff --git a/vtysh/.gitignore b/vtysh/.gitignore
index 09e90e51d2..a6c3d4abc6 100644
--- a/vtysh/.gitignore
+++ b/vtysh/.gitignore
@@ -1,6 +1,5 @@
vtysh
vtysh_cmd.c
-vtysh_daemons.h
# does not exist anymore - remove 2023-10-04 or so
extract.pl
diff --git a/vtysh/subdir.am b/vtysh/subdir.am
index a1b81f598a..2eae16d629 100644
--- a/vtysh/subdir.am
+++ b/vtysh/subdir.am
@@ -29,13 +29,3 @@ noinst_HEADERS += \
vtysh_vtysh_LDADD = lib/libfrr.la $(LIBCAP) $(LIBREADLINE) $(LIBS) $(LIBPAM)
EXTRA_DIST += vtysh/daemons.pl
-
-BUILT_SOURCES += vtysh/vtysh_daemons.h
-
-# force vtysh_daemons.h
-$(vtysh_vtysh_OBJECTS): vtysh/vtysh_daemons.h
-
-CLEANFILES += vtysh/vtysh_daemons.h
-vtysh/vtysh_daemons.h:
- @$(MKDIR_P) vtysh
- $(PERL) $(top_srcdir)/vtysh/daemons.pl $(vtysh_daemons) > vtysh/vtysh_daemons.h
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 28768801f2..3109f1510d 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -31,7 +31,7 @@
#include "network.h"
#include "filter.h"
#include "vtysh/vtysh.h"
-#include "vtysh/vtysh_daemons.h"
+#include "lib/vtysh_daemons.h"
#include "log.h"
#include "vrf.h"
#include "libfrr.h"
diff --git a/yang/frr-affinity-map.yang b/yang/frr-affinity-map.yang
index c4377e6246..f1d9e44738 100644
--- a/yang/frr-affinity-map.yang
+++ b/yang/frr-affinity-map.yang
@@ -53,12 +53,22 @@ module frr-affinity-map {
"Initial revision";
}
+ typedef affinity-map-ref {
+ type leafref {
+ path "/frr-affinity-map:lib/frr-affinity-map:affinity-maps/frr-affinity-map:affinity-map/frr-affinity-map:name";
+ require-instance true;
+ }
+ description
+ "Reference to an affinity map";
+ }
+
container lib {
container affinity-maps {
description
"Affinity Mapping Table";
list affinity-map {
key "name";
+ unique "value";
description
"Affinity Mapping configuration";
leaf name {
@@ -69,6 +79,7 @@ module frr-affinity-map {
"Affinity Name";
}
leaf value {
+ mandatory true;
type uint16 {
range "0..1023";
}
diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang
index 3c6e45126a..1168f05f40 100644
--- a/yang/frr-zebra.yang
+++ b/yang/frr-zebra.yang
@@ -2011,8 +2011,11 @@ module frr-zebra {
case affinity {
container affinities {
leaf-list affinity {
- type string;
+ type frr-affinity-map:affinity-map-ref;
max-elements "256";
+ must '../../affinity-mode != "standard" or /frr-affinity-map:lib/frr-affinity-map:affinity-maps/frr-affinity-map:affinity-map[frr-affinity-map:name=current()]/frr-affinity-map:value < 32' {
+ error-message "Affinity bit-position must be less than 32 when used with standard affinity mode";
+ }
description
"Array of Attribute Names";
}
diff --git a/zebra/interface.c b/zebra/interface.c
index f38e150d73..4c6fc8c36a 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -171,18 +171,13 @@ static int if_zebra_new_hook(struct interface *ifp)
return 0;
}
-static void if_nhg_dependents_check_valid(struct nhg_hash_entry *nhe)
-{
- zebra_nhg_check_valid(nhe);
-}
-
static void if_down_nhg_dependents(const struct interface *ifp)
{
struct nhg_connected *rb_node_dep = NULL;
struct zebra_if *zif = (struct zebra_if *)ifp->info;
frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep)
- if_nhg_dependents_check_valid(rb_node_dep->nhe);
+ zebra_nhg_check_valid(rb_node_dep->nhe);
}
static void if_nhg_dependents_release(const struct interface *ifp)
@@ -192,7 +187,7 @@ static void if_nhg_dependents_release(const struct interface *ifp)
frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep) {
rb_node_dep->nhe->ifp = NULL; /* Null it out */
- if_nhg_dependents_check_valid(rb_node_dep->nhe);
+ zebra_nhg_check_valid(rb_node_dep->nhe);
}
}
@@ -4256,23 +4251,10 @@ DEFPY_YANG(link_params_admin_grp, link_params_admin_grp_cmd,
"Administrative group membership\n"
"32-bit Hexadecimal value (e.g. 0xa1)\n")
{
- char xpath[XPATH_MAXLEN];
int idx_bitpattern = 1;
unsigned long value;
char value_str[11];
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- snprintf(
- xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities",
- ifp->name);
- if (yang_dnode_exists(running_config->dnode, xpath)) {
- vty_out(vty,
- "cannot use the admin-grp command when affinity is set\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) {
vty_out(vty, "link_params_admin_grp: fscanf: %s\n",
safe_strerror(errno));
@@ -4738,19 +4720,6 @@ DEFPY_YANG(link_params_affinity, link_params_affinity_cmd,
"Interface affinities\n"
"Affinity names\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- char xpath[XPATH_MAXLEN];
-
- snprintf(
- xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/legacy-admin-group",
- ifp->name);
- if (yang_dnode_exists(running_config->dnode, xpath)) {
- vty_out(vty,
- "cannot use the affinity command when admin-grp is set\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
return ag_change(vty, argc, argv,
"./frr-zebra:zebra/link-params/affinities/affinity",
no, no ? 2 : 1);
@@ -4764,8 +4733,8 @@ DEFPY_YANG(link_params_affinity, link_params_affinity_cmd,
DEFPY_YANG(link_params_affinity_mode, link_params_affinity_mode_cmd,
"affinity-mode <standard|extended|both>$affmode",
"Interface affinity mode\n"
- "Standard Admin-Group only RFC3630,5305,5329 (default)\n"
- "Extended Admin-Group only RFC7308\n"
+ "Standard Admin-Group only RFC3630,5305,5329\n"
+ "Extended Admin-Group only RFC7308 (default)\n"
"Standard and extended Admin-Group format\n")
{
const char *xpath = "./frr-zebra:zebra/link-params/affinity-mode";
@@ -4779,13 +4748,13 @@ DEFPY_YANG(no_link_params_affinity_mode, no_link_params_affinity_mode_cmd,
"no affinity-mode [<standard|extended|both>]",
NO_STR
"Interface affinity mode\n"
- "Standard Admin-Group only RFC3630,5305,5329 (default)\n"
- "Extended Admin-Group only RFC7308\n"
+ "Standard Admin-Group only RFC3630,5305,5329\n"
+ "Extended Admin-Group only RFC7308 (default)\n"
"Standard and extended Admin-Group format\n")
{
const char *xpath = "./frr-zebra:zebra/link-params/affinity-mode";
- nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "standard");
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "extended");
return nb_cli_apply_changes(vty, NULL);
}
@@ -4801,11 +4770,8 @@ static int ag_iter_cb(const struct lyd_node *dnode, void *arg)
void cli_show_legacy_admin_group(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults)
{
- if (!yang_dnode_exists(dnode, "legacy-admin-group"))
- return;
-
- vty_out(vty, " admin-group 0x%x\n",
- yang_dnode_get_uint32(dnode, "legacy-admin-group"));
+ vty_out(vty, " admin-grp 0x%x\n",
+ yang_dnode_get_uint32(dnode, NULL));
}
void cli_show_affinity_mode(struct vty *vty, const struct lyd_node *dnode,
@@ -4817,6 +4783,8 @@ void cli_show_affinity_mode(struct vty *vty, const struct lyd_node *dnode,
vty_out(vty, " affinity-mode standard\n");
else if (affinity_mode == AFFINITY_MODE_BOTH)
vty_out(vty, " affinity-mode both\n");
+ else if (affinity_mode == AFFINITY_MODE_EXTENDED && show_defaults)
+ vty_out(vty, " affinity-mode extended\n");
}
void cli_show_affinity(struct vty *vty, const struct lyd_node *dnode,
diff --git a/zebra/zebra_affinitymap.c b/zebra/zebra_affinitymap.c
index ae0f9a8a35..79bc78a7dc 100644
--- a/zebra/zebra_affinitymap.c
+++ b/zebra/zebra_affinitymap.c
@@ -26,102 +26,26 @@
#include "zebra/redistribute.h"
#include "zebra/zebra_affinitymap.h"
-static bool zebra_affinity_map_check_use(const char *affmap_name)
-{
- char xpath[XPATH_MAXLEN];
- struct interface *ifp;
- struct vrf *vrf;
-
- RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
- FOR_ALL_INTERFACES (vrf, ifp) {
- snprintf(xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']",
- ifp->name);
- if (!yang_dnode_exists(running_config->dnode, xpath))
- continue;
- snprintf(
- xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities[affinity='%s']",
- ifp->name, affmap_name);
- if (yang_dnode_exists(running_config->dnode, xpath))
- return true;
- }
- }
- return false;
-}
-
-static bool zebra_affinity_map_check_update(const char *affmap_name,
- uint16_t new_pos)
-{
- char xpath[XPATH_MAXLEN];
- struct interface *ifp;
- struct vrf *vrf;
-
- /* check whether the affinity-map new bit position is upper than 31
- * but is used on an interface on which affinity-mode is standard.
- * Return false if the change is not possible.
- */
- if (new_pos < 32)
- return true;
-
- RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
- FOR_ALL_INTERFACES (vrf, ifp) {
- snprintf(xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']",
- ifp->name);
- if (!yang_dnode_exists(running_config->dnode, xpath))
- continue;
- snprintf(
- xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities[affinity='%s']",
- ifp->name, affmap_name);
- if (!yang_dnode_exists(running_config->dnode, xpath))
- continue;
- if (yang_dnode_get_enum(
- running_config->dnode,
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinity-mode",
- ifp->name) == AFFINITY_MODE_STANDARD)
- return false;
- }
- }
- return true;
-}
-
static void zebra_affinity_map_update(const char *affmap_name, uint16_t old_pos,
uint16_t new_pos)
{
struct if_link_params *iflp;
- enum affinity_mode aff_mode;
- char xpath[XPATH_MAXLEN];
struct interface *ifp;
struct vrf *vrf;
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
FOR_ALL_INTERFACES (vrf, ifp) {
- snprintf(xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']",
- ifp->name);
- if (!yang_dnode_exists(running_config->dnode, xpath))
- continue;
- snprintf(
- xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities[affinity='%s']",
- ifp->name, affmap_name);
- if (!yang_dnode_exists(running_config->dnode, xpath))
- continue;
- aff_mode = yang_dnode_get_enum(
- running_config->dnode,
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinity-mode",
- ifp->name);
iflp = if_link_params_get(ifp);
- if (aff_mode == AFFINITY_MODE_EXTENDED ||
- aff_mode == AFFINITY_MODE_BOTH) {
+ if (!iflp)
+ continue;
+ if (IS_PARAM_SET(iflp, LP_EXTEND_ADM_GRP) &&
+ admin_group_get(&iflp->ext_admin_grp, old_pos)) {
admin_group_unset(&iflp->ext_admin_grp,
old_pos);
admin_group_set(&iflp->ext_admin_grp, new_pos);
}
- if (aff_mode == AFFINITY_MODE_STANDARD ||
- aff_mode == AFFINITY_MODE_BOTH) {
+ if (IS_PARAM_SET(iflp, LP_ADM_GRP) &&
+ (iflp->admin_grp & (1 << old_pos))) {
iflp->admin_grp &= ~(1 << old_pos);
if (new_pos < 32)
iflp->admin_grp |= 1 << new_pos;
@@ -138,7 +62,5 @@ void zebra_affinity_map_init(void)
{
affinity_map_init();
- affinity_map_set_check_use_hook(zebra_affinity_map_check_use);
- affinity_map_set_check_update_hook(zebra_affinity_map_check_update);
affinity_map_set_update_hook(zebra_affinity_map_update);
}
diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c
index 50caaa819e..98c241b2a1 100644
--- a/zebra/zebra_nb_config.c
+++ b/zebra/zebra_nb_config.c
@@ -1270,20 +1270,6 @@ int lib_interface_zebra_affinity_create(struct nb_cb_create_args *args)
switch (args->event) {
case NB_EV_VALIDATE:
- if (!affmap) {
- snprintf(args->errmsg, args->errmsg_len,
- "affinity-map %s not found.", affname);
- return NB_ERR_VALIDATION;
- }
- if (affinity_mode == AFFINITY_MODE_STANDARD &&
- affmap->bit_position > 31) {
- snprintf(
- args->errmsg, args->errmsg_len,
- "affinity %s bit-position %d is not compatible with affinity-mode standard (bit-position > 31).",
- affname, affmap->bit_position);
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
@@ -1331,12 +1317,6 @@ int lib_interface_zebra_affinity_destroy(struct nb_cb_destroy_args *args)
switch (args->event) {
case NB_EV_VALIDATE:
- if (!affmap) {
- snprintf(args->errmsg, args->errmsg_len,
- "affinity-map %s not found.", affname);
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
@@ -1386,14 +1366,6 @@ int lib_interface_zebra_affinity_mode_modify(struct nb_cb_modify_args *args)
switch (args->event) {
case NB_EV_VALIDATE:
- if (affinity_mode == AFFINITY_MODE_STANDARD &&
- admin_group_nb_words(&iflp->ext_admin_grp) > 1) {
- snprintf(
- args->errmsg, args->errmsg_len,
- "affinity-mode standard cannot be set when a bit-position > 31 is set.");
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index 93758cca20..9e3aa8bc5c 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -1082,11 +1082,10 @@ void zebra_nhg_check_valid(struct nhg_hash_entry *nhe)
frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
if (CHECK_FLAG(rb_node_dep->nhe->flags, NEXTHOP_GROUP_VALID)) {
valid = true;
- goto done;
+ break;
}
}
-done:
if (valid)
zebra_nhg_set_valid(nhe);
else
diff --git a/zebra/zebra_nhg.h b/zebra/zebra_nhg.h
index 6179be3442..4eddecb73d 100644
--- a/zebra/zebra_nhg.h
+++ b/zebra/zebra_nhg.h
@@ -143,7 +143,7 @@ struct nhg_hash_entry {
/*
* Track FPM installation status..
*/
-#define NEXTHOP_GROUP_FPM (1 << 6)
+#define NEXTHOP_GROUP_FPM (1 << 7)
};
/* Upper 4 bits of the NHG are reserved for indicating the NHG type */