diff options
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, } }, { @@ -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(¤t_time, <); + gmtime_r(&session->time_connected, <); + 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 */ |
