mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 12:18:12 +00:00
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>
This commit is contained in:
parent
67409447ff
commit
735fb37db1
142
lib/flex_algo.c
Normal file
142
lib/flex_algo.c
Normal file
@ -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;
|
||||
}
|
121
lib/flex_algo.h
Normal file
121
lib/flex_algo.h
Normal file
@ -0,0 +1,121 @@
|
||||
// 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.h: Flexible Algorithm library
|
||||
*
|
||||
* Authors
|
||||
* -------
|
||||
* Hiroki Shirokura
|
||||
* Masakazu Asama
|
||||
* Louis Scalbert
|
||||
*/
|
||||
|
||||
#ifndef _FRR_FLEX_ALGO_H
|
||||
#define _FRR_FLEX_ALGO_H
|
||||
|
||||
#include "admin_group.h"
|
||||
#include "linklist.h"
|
||||
#include "prefix.h"
|
||||
#include "segment_routing.h"
|
||||
|
||||
#define FLEX_ALGO_PRIO_DEFAULT 128
|
||||
|
||||
#define CALC_TYPE_SPF 0
|
||||
|
||||
/* flex-algo definition flags */
|
||||
|
||||
/* M-flag (aka. prefix-metric)
|
||||
* Flex-Algorithm specific prefix and ASBR metric MUST be used
|
||||
*/
|
||||
#define FAD_FLAG_M 0x80
|
||||
|
||||
/*
|
||||
* Metric Type values from RFC9350 section 5.1
|
||||
*/
|
||||
enum flex_algo_metric_type {
|
||||
MT_IGP = 0,
|
||||
MT_MIN_UNI_LINK_DELAY = 1,
|
||||
MT_TE_DEFAULT = 2,
|
||||
};
|
||||
|
||||
|
||||
/* Flex-Algo data about a given algorithm.
|
||||
* It includes the definition and some local data.
|
||||
*/
|
||||
struct flex_algo {
|
||||
/* Flex-Algo definition */
|
||||
uint8_t algorithm;
|
||||
enum flex_algo_metric_type metric_type;
|
||||
uint8_t calc_type;
|
||||
uint8_t priority;
|
||||
uint8_t flags;
|
||||
|
||||
/* extended admin-groups */
|
||||
struct admin_group admin_group_exclude_any;
|
||||
struct admin_group admin_group_include_any;
|
||||
struct admin_group admin_group_include_all;
|
||||
|
||||
/* Exclude SRLG Sub-TLV is not yet supported by IS-IS
|
||||
* True if a Exclude SRLG Sub-TLV has been found
|
||||
*/
|
||||
bool exclude_srlg;
|
||||
|
||||
/* True if an unsupported sub-TLV other Exclude SRLG
|
||||
* has been received.
|
||||
* A router that receives an unsupported definition
|
||||
* that is elected must not participate in the algorithm.
|
||||
* This boolean prevents future sub-TLV from being considered
|
||||
* as supported.
|
||||
*/
|
||||
bool unsupported_subtlv;
|
||||
|
||||
/* Flex-Algo local data */
|
||||
|
||||
/* True if the local definition must be advertised */
|
||||
bool advertise_definition;
|
||||
|
||||
/* which dataplane must be used for the algorithm */
|
||||
#define FLEX_ALGO_SR_MPLS 0x01
|
||||
#define FLEX_ALGO_SRV6 0x02
|
||||
#define FLEX_ALGO_IP 0x04
|
||||
uint8_t dataplanes;
|
||||
|
||||
/*
|
||||
* This property can be freely extended among different routing
|
||||
* protocols. Since Flex-Algo is an IGP protocol agnostic, both IS-IS
|
||||
* and OSPF can implement Flex-Algo. The struct flex_algo thus provides
|
||||
* the general data structure of Flex-Algo, and the value of extending
|
||||
* it with the IGP protocol is provided by this property.
|
||||
*/
|
||||
void *data;
|
||||
};
|
||||
|
||||
typedef void *(*flex_algo_allocator_t)(void *);
|
||||
typedef void (*flex_algo_releaser_t)(void *);
|
||||
|
||||
struct flex_algos {
|
||||
flex_algo_allocator_t allocator;
|
||||
flex_algo_releaser_t releaser;
|
||||
struct list *flex_algos;
|
||||
};
|
||||
|
||||
/*
|
||||
* Flex-Algo Utilities
|
||||
*/
|
||||
struct flex_algos *flex_algos_alloc(flex_algo_allocator_t allocator,
|
||||
flex_algo_releaser_t releaser);
|
||||
struct flex_algo *flex_algo_alloc(struct flex_algos *flex_algos,
|
||||
uint8_t algorithm, void *arg);
|
||||
struct flex_algo *flex_algo_lookup(struct flex_algos *flex_algos,
|
||||
uint8_t algorithm);
|
||||
void flex_algos_free(struct flex_algos *flex_algos);
|
||||
bool flex_algo_definition_cmp(struct flex_algo *fa1, struct flex_algo *fa2);
|
||||
void flex_algo_delete(struct flex_algos *flex_algos, uint8_t algorithm);
|
||||
bool flex_algo_id_valid(uint16_t algorithm);
|
||||
char *flex_algo_metric_type_print(char *type_str, size_t sz,
|
||||
enum flex_algo_metric_type metric_type);
|
||||
|
||||
#endif /* _FRR_FLEX_ALGO_H */
|
@ -33,6 +33,7 @@ lib_libfrr_la_SOURCES = \
|
||||
lib/filter.c \
|
||||
lib/filter_cli.c \
|
||||
lib/filter_nb.c \
|
||||
lib/flex_algo.c \
|
||||
lib/frrcu.c \
|
||||
lib/frrlua.c \
|
||||
lib/frrscript.c \
|
||||
@ -211,6 +212,7 @@ pkginclude_HEADERS += \
|
||||
lib/distribute.h \
|
||||
lib/ferr.h \
|
||||
lib/filter.h \
|
||||
lib/flex_algo.h \
|
||||
lib/freebsd-queue.h \
|
||||
lib/frrlua.h \
|
||||
lib/frrscript.h \
|
||||
|
Loading…
Reference in New Issue
Block a user