1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*********************************************************************
3 * Copyright 2022 Hiroki Shirokura, LINE Corporation
4 * Copyright 2022 Masakazu Asama
5 * Copyright 2022 6WIND S.A.
7 * flex_algo.c: Flexible Algorithm library
18 #include "flex_algo.h"
20 DEFINE_MTYPE_STATIC(LIB
, FLEX_ALGO_DATABASE
, "Flex-Algo database");
21 DEFINE_MTYPE_STATIC(LIB
, FLEX_ALGO
, "Flex-Algo algorithm information");
23 static void _flex_algo_delete(struct flex_algos
*flex_algos
,
24 struct flex_algo
*fa
);
26 struct flex_algos
*flex_algos_alloc(flex_algo_allocator_t allocator
,
27 flex_algo_releaser_t releaser
)
29 struct flex_algos
*flex_algos
;
32 XCALLOC(MTYPE_FLEX_ALGO_DATABASE
, sizeof(struct flex_algos
));
33 flex_algos
->flex_algos
= list_new();
34 flex_algos
->allocator
= allocator
;
35 flex_algos
->releaser
= releaser
;
39 void flex_algos_free(struct flex_algos
*flex_algos
)
41 struct listnode
*node
, *nnode
;
44 for (ALL_LIST_ELEMENTS(flex_algos
->flex_algos
, node
, nnode
, fa
))
45 _flex_algo_delete(flex_algos
, fa
);
46 list_delete(&flex_algos
->flex_algos
);
47 XFREE(MTYPE_FLEX_ALGO_DATABASE
, flex_algos
);
50 struct flex_algo
*flex_algo_alloc(struct flex_algos
*flex_algos
,
51 uint8_t algorithm
, void *arg
)
55 fa
= XCALLOC(MTYPE_FLEX_ALGO
, sizeof(struct flex_algo
));
56 fa
->algorithm
= algorithm
;
57 if (flex_algos
->allocator
)
58 fa
->data
= flex_algos
->allocator(arg
);
59 admin_group_init(&fa
->admin_group_exclude_any
);
60 admin_group_init(&fa
->admin_group_include_any
);
61 admin_group_init(&fa
->admin_group_include_all
);
62 listnode_add(flex_algos
->flex_algos
, fa
);
66 static void _flex_algo_delete(struct flex_algos
*flex_algos
,
69 if (flex_algos
->releaser
)
70 flex_algos
->releaser(fa
->data
);
71 admin_group_term(&fa
->admin_group_exclude_any
);
72 admin_group_term(&fa
->admin_group_include_any
);
73 admin_group_term(&fa
->admin_group_include_all
);
74 listnode_delete(flex_algos
->flex_algos
, fa
);
75 XFREE(MTYPE_FLEX_ALGO
, fa
);
79 void flex_algo_delete(struct flex_algos
*flex_algos
, uint8_t algorithm
)
81 struct listnode
*node
, *nnode
;
84 for (ALL_LIST_ELEMENTS(flex_algos
->flex_algos
, node
, nnode
, fa
)) {
85 if (fa
->algorithm
!= algorithm
)
87 _flex_algo_delete(flex_algos
, fa
);
92 * @brief Look up the local flex-algo object by its algorithm number.
93 * @param algorithm flex-algo algorithm number
94 * @param area area pointer of flex-algo
95 * @return local flex-algo object if exist, else NULL
97 struct flex_algo
*flex_algo_lookup(struct flex_algos
*flex_algos
,
100 struct listnode
*node
;
101 struct flex_algo
*fa
;
103 for (ALL_LIST_ELEMENTS_RO(flex_algos
->flex_algos
, node
, fa
))
104 if (fa
->algorithm
== algorithm
)
110 * @brief Compare two Flex-Algo Definitions (FAD)
113 * @return true if the definition is equal, else false
115 bool flex_algo_definition_cmp(struct flex_algo
*fa1
, struct flex_algo
*fa2
)
117 if (fa1
->algorithm
!= fa2
->algorithm
)
119 if (fa1
->calc_type
!= fa2
->calc_type
)
121 if (fa1
->metric_type
!= fa2
->metric_type
)
123 if (fa1
->exclude_srlg
!= fa2
->exclude_srlg
)
125 if (fa1
->flags
!= fa2
->flags
)
127 if (fa1
->unsupported_subtlv
!= fa2
->unsupported_subtlv
)
130 if (!admin_group_cmp(&fa1
->admin_group_exclude_any
,
131 &fa2
->admin_group_exclude_any
))
133 if (!admin_group_cmp(&fa1
->admin_group_include_all
,
134 &fa2
->admin_group_include_all
))
136 if (!admin_group_cmp(&fa1
->admin_group_include_any
,
137 &fa2
->admin_group_include_any
))
144 * Check SR Algorithm is Flex-Algo
145 * according to RFC9350 section 4
147 * @param algorithm SR Algorithm
149 bool flex_algo_id_valid(uint16_t algorithm
)
151 return algorithm
>= SR_ALGORITHM_FLEX_MIN
&&
152 algorithm
<= SR_ALGORITHM_FLEX_MAX
;
155 char *flex_algo_metric_type_print(char *type_str
, size_t sz
,
156 enum flex_algo_metric_type metric_type
)
158 switch (metric_type
) {
160 snprintf(type_str
, sz
, "igp");
162 case MT_MIN_UNI_LINK_DELAY
:
163 snprintf(type_str
, sz
, "delay");
166 snprintf(type_str
, sz
, "te");
172 bool flex_algo_get_state(struct flex_algos
*flex_algos
, uint8_t algorithm
)
174 struct flex_algo
*fa
= flex_algo_lookup(flex_algos
, algorithm
);
182 void flex_algo_set_state(struct flex_algos
*flex_algos
, uint8_t algorithm
,
185 struct flex_algo
*fa
= flex_algo_lookup(flex_algos
, algorithm
);