]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/pcep_utils_counters.c
Merge pull request #12159 from opensourcerouting/fix/conditional_advertisement_track_...
[mirror_frr.git] / pceplib / pcep_utils_counters.c
1 /*
2 * This file is part of the PCEPlib, a PCEP protocol library.
3 *
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 *
19 * Author : Brady Johnson <brady@voltanet.io>
20 *
21 */
22
23
24 /*
25 * Implementation of PCEP Counters.
26 */
27
28 #include <zebra.h>
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <time.h>
33
34 #include "pcep_utils_counters.h"
35 #include "pcep_utils_logging.h"
36 #include "pcep_utils_memory.h"
37
38 struct counters_group *create_counters_group(const char *group_name,
39 uint16_t max_subgroups)
40 {
41 if (group_name == NULL) {
42 pcep_log(
43 LOG_INFO,
44 "%s: Cannot create counters group: group_name is NULL.",
45 __func__);
46 return NULL;
47 }
48
49 if (max_subgroups > MAX_COUNTER_GROUPS) {
50 pcep_log(
51 LOG_INFO,
52 "%s: Cannot create counters group: max_subgroups [%d] is larger than max the [%d].",
53 __func__, max_subgroups, MAX_COUNTER_GROUPS);
54 return NULL;
55 }
56
57 struct counters_group *group =
58 pceplib_malloc(PCEPLIB_INFRA, sizeof(struct counters_group));
59 memset(group, 0, sizeof(struct counters_group));
60 group->subgroups =
61 pceplib_malloc(PCEPLIB_INFRA, sizeof(struct counters_subgroup *)
62 * (max_subgroups + 1));
63 memset(group->subgroups, 0,
64 sizeof(struct counters_subgroup *) * (max_subgroups + 1));
65
66 strlcpy(group->counters_group_name, group_name,
67 sizeof(group->counters_group_name));
68 group->max_subgroups = max_subgroups;
69 group->start_time = time(NULL);
70
71 return group;
72 }
73
74 struct counters_subgroup *create_counters_subgroup(const char *subgroup_name,
75 uint16_t subgroup_id,
76 uint16_t max_counters)
77 {
78 if (subgroup_name == NULL) {
79 pcep_log(
80 LOG_INFO,
81 "%s: Cannot create counters subgroup: subgroup_name is NULL.",
82 __func__);
83 return NULL;
84 }
85
86 if (max_counters > MAX_COUNTERS) {
87 pcep_log(
88 LOG_INFO,
89 "%s: Cannot create counters subgroup: max_counters [%d] is larger than the max [%d].",
90 __func__, max_counters, MAX_COUNTERS);
91 return NULL;
92 }
93
94 if (subgroup_id > MAX_COUNTER_GROUPS) {
95 pcep_log(
96 LOG_INFO,
97 "%s: Cannot create counters subgroup: subgroup_id [%d] is larger than max the [%d].",
98 __func__, subgroup_id, MAX_COUNTER_GROUPS);
99 return NULL;
100 }
101
102 struct counters_subgroup *subgroup =
103 pceplib_malloc(PCEPLIB_INFRA, sizeof(struct counters_subgroup));
104 memset(subgroup, 0, sizeof(struct counters_subgroup));
105 subgroup->counters = pceplib_malloc(
106 PCEPLIB_INFRA, sizeof(struct counter *) * (max_counters + 1));
107 memset(subgroup->counters, 0,
108 sizeof(struct counter *) * (max_counters + 1));
109
110 strlcpy(subgroup->counters_subgroup_name, subgroup_name,
111 sizeof(subgroup->counters_subgroup_name));
112 subgroup->subgroup_id = subgroup_id;
113 subgroup->max_counters = max_counters;
114
115 return subgroup;
116 }
117
118 struct counters_subgroup *
119 clone_counters_subgroup(struct counters_subgroup *subgroup,
120 const char *subgroup_name, uint16_t subgroup_id)
121 {
122 if (subgroup == NULL) {
123 pcep_log(
124 LOG_INFO,
125 "%s: Cannot clone counters subgroup: input counters_subgroup is NULL.",
126 __func__);
127 return NULL;
128 }
129
130 if (subgroup_name == NULL) {
131 pcep_log(
132 LOG_INFO,
133 "%s: Cannot clone counters subgroup: subgroup_name is NULL.",
134 __func__);
135 return NULL;
136 }
137
138 if (subgroup_id > MAX_COUNTER_GROUPS) {
139 pcep_log(
140 LOG_INFO,
141 "%s: Cannot clone counters subgroup: subgroup_id [%d] is larger than max the [%d].",
142 __func__, subgroup_id, MAX_COUNTER_GROUPS);
143 return NULL;
144 }
145
146 struct counters_subgroup *cloned_subgroup = create_counters_subgroup(
147 subgroup_name, subgroup_id, subgroup->max_counters);
148 int i = 0;
149 for (; i <= subgroup->max_counters; i++) {
150 struct counter *counter = subgroup->counters[i];
151 if (counter != NULL) {
152 create_subgroup_counter(cloned_subgroup,
153 counter->counter_id,
154 counter->counter_name);
155 }
156 }
157
158 return cloned_subgroup;
159 }
160
161 bool add_counters_subgroup(struct counters_group *group,
162 struct counters_subgroup *subgroup)
163 {
164 if (group == NULL) {
165 pcep_log(
166 LOG_INFO,
167 "%s: Cannot add counters subgroup: counters_group is NULL.",
168 __func__);
169 return false;
170 }
171
172 if (subgroup == NULL) {
173 pcep_log(
174 LOG_INFO,
175 "%s: Cannot add counters subgroup: counters_subgroup is NULL.",
176 __func__);
177 return false;
178 }
179
180 if (subgroup->subgroup_id >= group->max_subgroups) {
181 pcep_log(
182 LOG_INFO,
183 "%s: Cannot add counters subgroup: counters_subgroup id [%d] is larger than the group max_subgroups [%d].",
184 __func__, subgroup->subgroup_id, group->max_subgroups);
185 return false;
186 }
187
188 group->num_subgroups++;
189 group->subgroups[subgroup->subgroup_id] = subgroup;
190
191 return true;
192 }
193
194 bool create_subgroup_counter(struct counters_subgroup *subgroup,
195 uint32_t counter_id, const char *counter_name)
196 {
197 if (subgroup == NULL) {
198 pcep_log(
199 LOG_INFO,
200 "%s: Cannot create subgroup counter: counters_subgroup is NULL.",
201 __func__);
202 return false;
203 }
204
205 if (counter_id >= subgroup->max_counters) {
206 pcep_log(
207 LOG_INFO,
208 "%s: Cannot create subgroup counter: counter_id [%d] is larger than the subgroup max_counters [%d].",
209 __func__, counter_id, subgroup->max_counters);
210 return false;
211 }
212
213 if (counter_name == NULL) {
214 pcep_log(
215 LOG_INFO,
216 "%s: Cannot create subgroup counter: counter_name is NULL.",
217 __func__);
218 return NULL;
219 }
220
221 struct counter *counter =
222 pceplib_malloc(PCEPLIB_INFRA, sizeof(struct counter));
223 memset(counter, 0, sizeof(struct counter));
224 counter->counter_id = counter_id;
225 strlcpy(counter->counter_name, counter_name,
226 sizeof(counter->counter_name));
227
228 subgroup->num_counters++;
229 subgroup->counters[counter->counter_id] = counter;
230
231 return true;
232 }
233
234 bool delete_counters_group(struct counters_group *group)
235 {
236 if (group == NULL) {
237 pcep_log(
238 LOG_INFO,
239 "%s: Cannot delete group counters: counters_group is NULL.",
240 __func__);
241 return false;
242 }
243
244 int i = 0;
245 for (; i <= group->max_subgroups; i++) {
246 struct counters_subgroup *subgroup = group->subgroups[i];
247 if (subgroup != NULL) {
248 delete_counters_subgroup(subgroup);
249 }
250 }
251
252 pceplib_free(PCEPLIB_INFRA, group->subgroups);
253 pceplib_free(PCEPLIB_INFRA, group);
254
255 return true;
256 }
257
258 bool delete_counters_subgroup(struct counters_subgroup *subgroup)
259 {
260 if (subgroup == NULL || subgroup->counters == NULL) {
261 pcep_log(
262 LOG_INFO,
263 "%s: Cannot delete subgroup counters: counters_subgroup is NULL.",
264 __func__);
265 return false;
266 }
267
268 int i = 0;
269 for (; i <= subgroup->max_counters; i++) {
270 struct counter *counter = subgroup->counters[i];
271 if (counter != NULL) {
272 pceplib_free(PCEPLIB_INFRA, counter);
273 }
274 }
275
276 pceplib_free(PCEPLIB_INFRA, subgroup->counters);
277 pceplib_free(PCEPLIB_INFRA, subgroup);
278
279 return true;
280 }
281
282 bool reset_group_counters(struct counters_group *group)
283 {
284 if (group == NULL) {
285 pcep_log(
286 LOG_INFO,
287 "%s: Cannot reset group counters: counters_group is NULL.",
288 __func__);
289 return false;
290 }
291
292 int i = 0;
293 for (; i <= group->max_subgroups; i++) {
294 struct counters_subgroup *subgroup = group->subgroups[i];
295 if (subgroup != NULL) {
296 reset_subgroup_counters(subgroup);
297 }
298 }
299
300 group->start_time = time(NULL);
301
302 return true;
303 }
304
305 bool reset_subgroup_counters(struct counters_subgroup *subgroup)
306 {
307 if (subgroup == NULL) {
308 pcep_log(
309 LOG_INFO,
310 "%s: Cannot reset subgroup counters: counters_subgroup is NULL.",
311 __func__);
312 return false;
313 }
314
315 int i = 0;
316 for (; i <= subgroup->max_counters; i++) {
317 struct counter *counter = subgroup->counters[i];
318 if (counter != NULL) {
319 counter->counter_value = 0;
320 }
321 }
322
323 return true;
324 }
325
326 bool increment_counter(struct counters_group *group, uint16_t subgroup_id,
327 uint16_t counter_id)
328 {
329 if (group == NULL) {
330 pcep_log(
331 LOG_INFO,
332 "%s: Cannot increment counter: counters_group is NULL.",
333 __func__);
334 return false;
335 }
336
337 if (subgroup_id >= group->max_subgroups) {
338 pcep_log(
339 LOG_DEBUG,
340 "%s: Cannot increment counter: subgroup_id [%d] is larger than the group max_subgroups [%d].",
341 __func__, subgroup_id, group->max_subgroups);
342 return false;
343 }
344
345 struct counters_subgroup *subgroup = group->subgroups[subgroup_id];
346 if (subgroup == NULL) {
347 pcep_log(
348 LOG_INFO,
349 "%s: Cannot increment counter: counters_subgroup in counters_group is NULL.",
350 __func__);
351 return false;
352 }
353
354 return increment_subgroup_counter(subgroup, counter_id);
355 }
356
357 bool increment_subgroup_counter(struct counters_subgroup *subgroup,
358 uint16_t counter_id)
359 {
360 if (subgroup == NULL) {
361 pcep_log(
362 LOG_INFO,
363 "%s: Cannot increment counter: counters_subgroup is NULL.",
364 __func__);
365 return false;
366 }
367
368 if (counter_id >= subgroup->max_counters) {
369 pcep_log(
370 LOG_DEBUG,
371 "%s: Cannot increment counter: counter_id [%d] is larger than the subgroup max_counters [%d].",
372 __func__, counter_id, subgroup->max_counters);
373 return false;
374 }
375
376 if (subgroup->counters[counter_id] == NULL) {
377 pcep_log(
378 LOG_INFO,
379 "%s: Cannot increment counter: No counter exists for counter_id [%d].",
380 __func__, counter_id);
381 return false;
382 }
383
384 subgroup->counters[counter_id]->counter_value++;
385
386 return true;
387 }
388
389 bool dump_counters_group_to_log(struct counters_group *group)
390 {
391 if (group == NULL) {
392 pcep_log(
393 LOG_INFO,
394 "%s: Cannot dump group counters to log: counters_group is NULL.",
395 __func__);
396 return false;
397 }
398
399 time_t now = time(NULL);
400 pcep_log(
401 LOG_INFO,
402 "%s: PCEP Counters group:\n %s \n Sub-Groups [%d] \n Active for [%d seconds]",
403 __func__, group->counters_group_name, group->num_subgroups,
404 (now - group->start_time));
405
406 int i = 0;
407 for (; i <= group->max_subgroups; i++) {
408 struct counters_subgroup *subgroup = group->subgroups[i];
409 if (subgroup != NULL) {
410 dump_counters_subgroup_to_log(subgroup);
411 }
412 }
413
414 return true;
415 }
416
417 bool dump_counters_subgroup_to_log(struct counters_subgroup *subgroup)
418 {
419 if (subgroup == NULL) {
420 pcep_log(
421 LOG_INFO,
422 "%s: Cannot dump subgroup counters to log: counters_subgroup is NULL.",
423 __func__);
424 return false;
425 }
426
427 pcep_log(LOG_INFO,
428 "%s: \tPCEP Counters sub-group [%s] with [%d] counters",
429 __func__, subgroup->counters_subgroup_name,
430 subgroup->num_counters);
431
432 int i = 0;
433 for (; i <= subgroup->max_counters; i++) {
434 struct counter *counter = subgroup->counters[i];
435 if (counter != NULL) {
436 pcep_log(LOG_INFO, "%s: \t\t%s %d", __func__,
437 counter->counter_name, counter->counter_value);
438 }
439 }
440
441 return true;
442 }
443
444 struct counters_subgroup *find_subgroup(const struct counters_group *group,
445 uint16_t subgroup_id)
446 {
447 int i = 0;
448 for (; i <= group->max_subgroups; i++) {
449 struct counters_subgroup *subgroup = group->subgroups[i];
450 if (subgroup != NULL) {
451 if (subgroup->subgroup_id == subgroup_id) {
452 return subgroup;
453 }
454 }
455 }
456
457 return NULL;
458 }
459
460 uint32_t subgroup_counters_total(struct counters_subgroup *subgroup)
461 {
462 if (subgroup == NULL) {
463 return 0;
464 }
465 uint32_t counter_total = 0;
466 int i = 0;
467 for (; i <= subgroup->max_counters; i++) {
468 struct counter *counter = subgroup->counters[i];
469 if (counter != NULL) {
470 counter_total += counter->counter_value;
471 }
472 }
473
474 return counter_total;
475 }