]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: LGPL-2.1-or-later |
74971473 JG |
2 | /* |
3 | * This file is part of the PCEPlib, a PCEP protocol library. | |
4 | * | |
5 | * Copyright (C) 2020 Volta Networks https://voltanet.io/ | |
6 | * | |
74971473 JG |
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 | } |