forked from Mirror/frr
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 <iryzhov@nfware.com>
This commit is contained in:
parent
6103c6251a
commit
fdd834b8cc
|
@ -11,35 +11,6 @@
|
||||||
|
|
||||||
#ifndef FABRICD
|
#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,
|
static void isis_affinity_map_update(const char *affmap_name, uint16_t old_pos,
|
||||||
uint16_t new_pos)
|
uint16_t new_pos)
|
||||||
{
|
{
|
||||||
|
@ -90,7 +61,6 @@ void isis_affinity_map_init(void)
|
||||||
{
|
{
|
||||||
affinity_map_init();
|
affinity_map_init();
|
||||||
|
|
||||||
affinity_map_set_check_use_hook(isis_affinity_map_check_use);
|
|
||||||
affinity_map_set_update_hook(isis_affinity_map_update);
|
affinity_map_set_update_hook(isis_affinity_map_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ DEFINE_MTYPE_STATIC(LIB, AFFINITY_MAP_INDEX, "Affinity map index");
|
||||||
DEFINE_QOBJ_TYPE(affinity_maps);
|
DEFINE_QOBJ_TYPE(affinity_maps);
|
||||||
DEFINE_QOBJ_TYPE(affinity_map);
|
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)
|
static void affinity_map_free(struct affinity_map *map)
|
||||||
{
|
{
|
||||||
|
@ -121,13 +121,6 @@ char *affinity_map_name_get(int pos)
|
||||||
return NULL;
|
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)
|
bool affinity_map_check_update_hook(const char *affmap_name, uint16_t new_pos)
|
||||||
{
|
{
|
||||||
if (affinity_map_master.check_update_hook)
|
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);
|
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,
|
void affinity_map_set_check_update_hook(bool (*func)(const char *affmap_name,
|
||||||
uint16_t new_pos))
|
uint16_t new_pos))
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,7 +50,6 @@ DECLARE_QOBJ_TYPE(affinity_map);
|
||||||
struct affinity_maps {
|
struct affinity_maps {
|
||||||
struct list *maps;
|
struct list *maps;
|
||||||
|
|
||||||
bool (*check_use_hook)(const char *affmap_name);
|
|
||||||
bool (*check_update_hook)(const char *affmap_name, uint16_t new_pos);
|
bool (*check_update_hook)(const char *affmap_name, uint16_t new_pos);
|
||||||
void (*update_hook)(const char *affmap_name, uint16_t old_pos,
|
void (*update_hook)(const char *affmap_name, uint16_t old_pos,
|
||||||
uint16_t new_pos);
|
uint16_t new_pos);
|
||||||
|
@ -66,11 +65,9 @@ void affinity_map_unset(const char *name);
|
||||||
struct affinity_map *affinity_map_get(const char *name);
|
struct affinity_map *affinity_map_get(const char *name);
|
||||||
char *affinity_map_name_get(const int pos);
|
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);
|
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_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,
|
void affinity_map_set_check_update_hook(bool (*func)(const char *affmap_name,
|
||||||
uint16_t new_pos));
|
uint16_t new_pos));
|
||||||
void affinity_map_set_update_hook(void (*func)(const char *affmap_name,
|
void affinity_map_set_update_hook(void (*func)(const char *affmap_name,
|
||||||
|
|
|
@ -47,11 +47,6 @@ static int lib_affinity_map_destroy(struct nb_cb_destroy_args *args)
|
||||||
|
|
||||||
switch (args->event) {
|
switch (args->event) {
|
||||||
case NB_EV_VALIDATE:
|
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_PREPARE:
|
||||||
case NB_EV_ABORT:
|
case NB_EV_ABORT:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -53,6 +53,15 @@ module frr-affinity-map {
|
||||||
"Initial revision";
|
"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 lib {
|
||||||
container affinity-maps {
|
container affinity-maps {
|
||||||
description
|
description
|
||||||
|
|
|
@ -2011,7 +2011,7 @@ module frr-zebra {
|
||||||
case affinity {
|
case affinity {
|
||||||
container affinities {
|
container affinities {
|
||||||
leaf-list affinity {
|
leaf-list affinity {
|
||||||
type string;
|
type frr-affinity-map:affinity-map-ref;
|
||||||
max-elements "256";
|
max-elements "256";
|
||||||
description
|
description
|
||||||
"Array of Attribute Names";
|
"Array of Attribute Names";
|
||||||
|
|
|
@ -26,30 +26,6 @@
|
||||||
#include "zebra/redistribute.h"
|
#include "zebra/redistribute.h"
|
||||||
#include "zebra/zebra_affinitymap.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,
|
static bool zebra_affinity_map_check_update(const char *affmap_name,
|
||||||
uint16_t new_pos)
|
uint16_t new_pos)
|
||||||
{
|
{
|
||||||
|
@ -138,7 +114,6 @@ void zebra_affinity_map_init(void)
|
||||||
{
|
{
|
||||||
affinity_map_init();
|
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_check_update_hook(zebra_affinity_map_check_update);
|
||||||
affinity_map_set_update_hook(zebra_affinity_map_update);
|
affinity_map_set_update_hook(zebra_affinity_map_update);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue