diff options
author | Hiroki Shirokura <hiroki.shirokura@linecorp.com> | 2022-01-22 12:08:05 +0100 |
---|---|---|
committer | Louis Scalbert <louis.scalbert@6wind.com> | 2023-04-18 10:13:58 +0200 |
commit | 735fb37db1897f6393680c62d369e339146f004b (patch) | |
tree | 6737bd988d1a84e9ea93691100b7ed696028ff2c /lib/flex_algo.c | |
parent | isisd: add cli to configure algorithm-prefix-sid (diff) | |
download | frr-735fb37db1897f6393680c62d369e339146f004b.tar.xz frr-735fb37db1897f6393680c62d369e339146f004b.zip |
lib: add library for igp flexible-algorithm
Add a library to deal with Flexible Algorithm that will be common to
IS-IS and OSPF. The functions enables to deal with:
- Affinity-maps
- Extended Admin Group (RFC7308)
- Flex-Algo structures that contains the flex-algo configurations
Signed-off-by: Hiroki Shirokura <hiroki.shirokura@linecorp.com>
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Diffstat (limited to 'lib/flex_algo.c')
-rw-r--r-- | lib/flex_algo.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/lib/flex_algo.c b/lib/flex_algo.c new file mode 100644 index 000000000..bafbf8b77 --- /dev/null +++ b/lib/flex_algo.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/********************************************************************* + * Copyright 2022 Hiroki Shirokura, LINE Corporation + * Copyright 2022 Masakazu Asama + * Copyright 2022 6WIND S.A. + * + * flex_algo.c: Flexible Algorithm library + * + * Authors + * ------- + * Hiroki Shirokura + * Masakazu Asama + * Louis Scalbert + */ + +#include "zebra.h" + +#include "flex_algo.h" + +DEFINE_MTYPE_STATIC(LIB, FLEX_ALGO, "Flex-Algo Definition"); + +struct flex_algos *flex_algos_alloc(flex_algo_allocator_t allocator, + flex_algo_releaser_t releaser) +{ + struct flex_algos *flex_algos; + + flex_algos = XCALLOC(MTYPE_FLEX_ALGO, sizeof(*flex_algos)); + flex_algos->flex_algos = list_new(); + flex_algos->allocator = allocator; + flex_algos->releaser = releaser; + return flex_algos; +} + +struct flex_algo *flex_algo_alloc(struct flex_algos *flex_algos, + uint8_t algorithm, void *arg) +{ + struct flex_algo *fa; + + fa = XCALLOC(MTYPE_FLEX_ALGO, sizeof(*fa)); + fa->algorithm = algorithm; + if (flex_algos->allocator) + fa->data = flex_algos->allocator(arg); + admin_group_init(&fa->admin_group_exclude_any); + admin_group_init(&fa->admin_group_include_any); + admin_group_init(&fa->admin_group_include_all); + listnode_add(flex_algos->flex_algos, fa); + return fa; +} + +/** + * @brief Look up the local flex-algo object by its algorithm number. + * @param algorithm flex-algo algorithm number + * @param area area pointer of flex-algo + * @return local flex-algo object if exist, else NULL + */ +struct flex_algo *flex_algo_lookup(struct flex_algos *flex_algos, + uint8_t algorithm) +{ + struct listnode *node; + struct flex_algo *fa; + + for (ALL_LIST_ELEMENTS_RO(flex_algos->flex_algos, node, fa)) + if (fa->algorithm == algorithm) + return fa; + return NULL; +} + +/** + * @brief Compare two Flex-Algo Definitions (FAD) + * @param Flex algo 1 + * @param Flex algo 2 + * @return true if the definition is equal, else false + */ +bool flex_algo_definition_cmp(struct flex_algo *fa1, struct flex_algo *fa2) +{ + if (fa1->algorithm != fa2->algorithm) + return false; + if (fa1->calc_type != fa2->calc_type) + return false; + if (fa1->metric_type != fa2->metric_type) + return false; + + if (!admin_group_cmp(&fa1->admin_group_exclude_any, + &fa2->admin_group_exclude_any)) + return false; + if (!admin_group_cmp(&fa1->admin_group_include_all, + &fa2->admin_group_include_all)) + return false; + if (!admin_group_cmp(&fa1->admin_group_include_any, + &fa2->admin_group_include_any)) + return false; + + return true; +} + +void flex_algo_delete(struct flex_algos *flex_algos, uint8_t algorithm) +{ + struct listnode *node, *nnode; + struct flex_algo *fa; + + for (ALL_LIST_ELEMENTS(flex_algos->flex_algos, node, nnode, fa)) { + if (fa->algorithm != algorithm) + continue; + if (flex_algos->releaser) + flex_algos->releaser(fa->data); + admin_group_term(&fa->admin_group_exclude_any); + admin_group_term(&fa->admin_group_include_any); + admin_group_term(&fa->admin_group_include_all); + listnode_delete(flex_algos->flex_algos, fa); + XFREE(MTYPE_FLEX_ALGO, fa); + return; + } +} + +/** + * Check SR Algorithm is Flex-Algo + * according to RFC9350 section 4 + * + * @param algorithm SR Algorithm + */ +bool flex_algo_id_valid(uint16_t algorithm) +{ + return algorithm >= SR_ALGORITHM_FLEX_MIN && + algorithm <= SR_ALGORITHM_FLEX_MAX; +} + +char *flex_algo_metric_type_print(char *type_str, size_t sz, + enum flex_algo_metric_type metric_type) +{ + switch (metric_type) { + case MT_IGP: + snprintf(type_str, sz, "igp"); + break; + case MT_MIN_UNI_LINK_DELAY: + snprintf(type_str, sz, "delay"); + break; + case MT_TE_DEFAULT: + snprintf(type_str, sz, "te"); + break; + } + return type_str; +} |