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