From fdd834b8cc69b1b8c9bdfcfa1f033f35affb4c09 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Thu, 18 Jan 2024 23:27:56 +0200 Subject: lib: validate affinity-map reference using yang model Change the type of affinity leaf-list in frr-zebra to a leafref with "require-instance" property set to true. This change tells libyang to automatically check that affinity-map exists before usage and doesn't allow it to be deleted if it's referenced. It allows us to remove all the manual code that is doing the same thing. Signed-off-by: Igor Ryzhov --- lib/affinitymap.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'lib/affinitymap.c') diff --git a/lib/affinitymap.c b/lib/affinitymap.c index 17e1b2cc01..b748e74884 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, NULL}; static void affinity_map_free(struct affinity_map *map) { @@ -121,13 +121,6 @@ char *affinity_map_name_get(int pos) 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) @@ -153,12 +146,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)) { -- cgit v1.2.3 From 26bd685a87cd95b0a864580c5d8696eee203d929 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Thu, 18 Jan 2024 23:39:32 +0200 Subject: lib: make affinity-map value unique in the yang model It allows us to remove the code that does the same thing manually. Signed-off-by: Igor Ryzhov --- lib/affinitymap.c | 15 --------------- lib/affinitymap.h | 1 - lib/affinitymap_northbound.c | 8 -------- yang/frr-affinity-map.yang | 1 + 4 files changed, 1 insertion(+), 24 deletions(-) (limited to 'lib/affinitymap.c') diff --git a/lib/affinitymap.c b/lib/affinitymap.c index b748e74884..00f23c1ca3 100644 --- a/lib/affinitymap.c +++ b/lib/affinitymap.c @@ -106,21 +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_update_hook(const char *affmap_name, uint16_t new_pos) { if (affinity_map_master.check_update_hook) diff --git a/lib/affinitymap.h b/lib/affinitymap.h index 5ce233404f..8e0a798040 100644 --- a/lib/affinitymap.h +++ b/lib/affinitymap.h @@ -63,7 +63,6 @@ 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_update_hook(const char *affmap_name, uint16_t new_pos); void affinity_map_update_hook(const char *affmap_name, uint16_t new_pos); diff --git a/lib/affinitymap_northbound.c b/lib/affinitymap_northbound.c index bee2ebe861..1a1ff5f465 100644 --- a/lib/affinitymap_northbound.c +++ b/lib/affinitymap_northbound.c @@ -63,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( @@ -74,13 +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, diff --git a/yang/frr-affinity-map.yang b/yang/frr-affinity-map.yang index 992f5c7535..91b70ff22a 100644 --- a/yang/frr-affinity-map.yang +++ b/yang/frr-affinity-map.yang @@ -68,6 +68,7 @@ module frr-affinity-map { "Affinity Mapping Table"; list affinity-map { key "name"; + unique "value"; description "Affinity Mapping configuration"; leaf name { -- cgit v1.2.3 From 670e0c0737862e77f7baa042b2748345c13e7355 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Fri, 19 Jan 2024 01:40:21 +0200 Subject: lib: validate affinity-map bit position using the yang model When affinity mode is "standard", bit position cannot be greater than 31. Add a "must" statement to the YANG model to validate this, and remove our custom validation code that does the same. Signed-off-by: Igor Ryzhov --- lib/affinitymap.c | 16 +--------------- lib/affinitymap.h | 4 ---- lib/affinitymap_northbound.c | 7 ------- yang/frr-zebra.yang | 3 +++ zebra/zebra_affinitymap.c | 38 -------------------------------------- zebra/zebra_nb_config.c | 28 ---------------------------- 6 files changed, 4 insertions(+), 92 deletions(-) (limited to 'lib/affinitymap.c') diff --git a/lib/affinitymap.c b/lib/affinitymap.c index 00f23c1ca3..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}; +struct affinity_maps affinity_map_master = {NULL, NULL}; static void affinity_map_free(struct affinity_map *map) { @@ -106,14 +106,6 @@ struct affinity_map *affinity_map_get(const char *name) return NULL; } -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; @@ -131,12 +123,6 @@ void affinity_map_update_hook(const char *affmap_name, uint16_t new_pos) new_pos); } -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 8e0a798040..f5924ca3ef 100644 --- a/lib/affinitymap.h +++ b/lib/affinitymap.h @@ -50,7 +50,6 @@ DECLARE_QOBJ_TYPE(affinity_map); struct affinity_maps { struct list *maps; - 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,11 +63,8 @@ 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); -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_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 1a1ff5f465..30a9f373c2 100644 --- a/lib/affinitymap_northbound.c +++ b/lib/affinitymap_northbound.c @@ -73,13 +73,6 @@ static int lib_affinity_map_value_modify(struct nb_cb_modify_args *args) switch (args->event) { case NB_EV_VALIDATE: - 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; diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang index 68774a84fa..1168f05f40 100644 --- a/yang/frr-zebra.yang +++ b/yang/frr-zebra.yang @@ -2013,6 +2013,9 @@ module frr-zebra { leaf-list affinity { 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/zebra_affinitymap.c b/zebra/zebra_affinitymap.c index fabd3e677c..dd06000038 100644 --- a/zebra/zebra_affinitymap.c +++ b/zebra/zebra_affinitymap.c @@ -26,43 +26,6 @@ #include "zebra/redistribute.h" #include "zebra/zebra_affinitymap.h" -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) { @@ -114,6 +77,5 @@ void zebra_affinity_map_init(void) { affinity_map_init(); - 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; -- cgit v1.2.3