diff options
Diffstat (limited to 'pceplib/pcep_utils_counters.c')
-rw-r--r-- | pceplib/pcep_utils_counters.c | 475 |
1 files changed, 475 insertions, 0 deletions
diff --git a/pceplib/pcep_utils_counters.c b/pceplib/pcep_utils_counters.c new file mode 100644 index 0000000..d8078f6 --- /dev/null +++ b/pceplib/pcep_utils_counters.c @@ -0,0 +1,475 @@ +/* + * This file is part of the PCEPlib, a PCEP protocol library. + * + * Copyright (C) 2020 Volta Networks https://voltanet.io/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * Author : Brady Johnson <brady@voltanet.io> + * + */ + + +/* + * Implementation of PCEP Counters. + */ + +#include <zebra.h> + +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "pcep_utils_counters.h" +#include "pcep_utils_logging.h" +#include "pcep_utils_memory.h" + +struct counters_group *create_counters_group(const char *group_name, + uint16_t max_subgroups) +{ + if (group_name == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot create counters group: group_name is NULL.", + __func__); + return NULL; + } + + if (max_subgroups > MAX_COUNTER_GROUPS) { + pcep_log( + LOG_INFO, + "%s: Cannot create counters group: max_subgroups [%d] is larger than max the [%d].", + __func__, max_subgroups, MAX_COUNTER_GROUPS); + return NULL; + } + + struct counters_group *group = + pceplib_malloc(PCEPLIB_INFRA, sizeof(struct counters_group)); + memset(group, 0, sizeof(struct counters_group)); + group->subgroups = + pceplib_malloc(PCEPLIB_INFRA, sizeof(struct counters_subgroup *) + * (max_subgroups + 1)); + memset(group->subgroups, 0, + sizeof(struct counters_subgroup *) * (max_subgroups + 1)); + + strlcpy(group->counters_group_name, group_name, + sizeof(group->counters_group_name)); + group->max_subgroups = max_subgroups; + group->start_time = time(NULL); + + return group; +} + +struct counters_subgroup *create_counters_subgroup(const char *subgroup_name, + uint16_t subgroup_id, + uint16_t max_counters) +{ + if (subgroup_name == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot create counters subgroup: subgroup_name is NULL.", + __func__); + return NULL; + } + + if (max_counters > MAX_COUNTERS) { + pcep_log( + LOG_INFO, + "%s: Cannot create counters subgroup: max_counters [%d] is larger than the max [%d].", + __func__, max_counters, MAX_COUNTERS); + return NULL; + } + + if (subgroup_id > MAX_COUNTER_GROUPS) { + pcep_log( + LOG_INFO, + "%s: Cannot create counters subgroup: subgroup_id [%d] is larger than max the [%d].", + __func__, subgroup_id, MAX_COUNTER_GROUPS); + return NULL; + } + + struct counters_subgroup *subgroup = + pceplib_malloc(PCEPLIB_INFRA, sizeof(struct counters_subgroup)); + memset(subgroup, 0, sizeof(struct counters_subgroup)); + subgroup->counters = pceplib_malloc( + PCEPLIB_INFRA, sizeof(struct counter *) * (max_counters + 1)); + memset(subgroup->counters, 0, + sizeof(struct counter *) * (max_counters + 1)); + + strlcpy(subgroup->counters_subgroup_name, subgroup_name, + sizeof(subgroup->counters_subgroup_name)); + subgroup->subgroup_id = subgroup_id; + subgroup->max_counters = max_counters; + + return subgroup; +} + +struct counters_subgroup * +clone_counters_subgroup(struct counters_subgroup *subgroup, + const char *subgroup_name, uint16_t subgroup_id) +{ + if (subgroup == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot clone counters subgroup: input counters_subgroup is NULL.", + __func__); + return NULL; + } + + if (subgroup_name == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot clone counters subgroup: subgroup_name is NULL.", + __func__); + return NULL; + } + + if (subgroup_id > MAX_COUNTER_GROUPS) { + pcep_log( + LOG_INFO, + "%s: Cannot clone counters subgroup: subgroup_id [%d] is larger than max the [%d].", + __func__, subgroup_id, MAX_COUNTER_GROUPS); + return NULL; + } + + struct counters_subgroup *cloned_subgroup = create_counters_subgroup( + subgroup_name, subgroup_id, subgroup->max_counters); + int i = 0; + for (; i <= subgroup->max_counters; i++) { + struct counter *counter = subgroup->counters[i]; + if (counter != NULL) { + create_subgroup_counter(cloned_subgroup, + counter->counter_id, + counter->counter_name); + } + } + + return cloned_subgroup; +} + +bool add_counters_subgroup(struct counters_group *group, + struct counters_subgroup *subgroup) +{ + if (group == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot add counters subgroup: counters_group is NULL.", + __func__); + return false; + } + + if (subgroup == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot add counters subgroup: counters_subgroup is NULL.", + __func__); + return false; + } + + if (subgroup->subgroup_id >= group->max_subgroups) { + pcep_log( + LOG_INFO, + "%s: Cannot add counters subgroup: counters_subgroup id [%d] is larger than the group max_subgroups [%d].", + __func__, subgroup->subgroup_id, group->max_subgroups); + return false; + } + + group->num_subgroups++; + group->subgroups[subgroup->subgroup_id] = subgroup; + + return true; +} + +bool create_subgroup_counter(struct counters_subgroup *subgroup, + uint32_t counter_id, const char *counter_name) +{ + if (subgroup == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot create subgroup counter: counters_subgroup is NULL.", + __func__); + return false; + } + + if (counter_id >= subgroup->max_counters) { + pcep_log( + LOG_INFO, + "%s: Cannot create subgroup counter: counter_id [%d] is larger than the subgroup max_counters [%d].", + __func__, counter_id, subgroup->max_counters); + return false; + } + + if (counter_name == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot create subgroup counter: counter_name is NULL.", + __func__); + return NULL; + } + + struct counter *counter = + pceplib_malloc(PCEPLIB_INFRA, sizeof(struct counter)); + memset(counter, 0, sizeof(struct counter)); + counter->counter_id = counter_id; + strlcpy(counter->counter_name, counter_name, + sizeof(counter->counter_name)); + + subgroup->num_counters++; + subgroup->counters[counter->counter_id] = counter; + + return true; +} + +bool delete_counters_group(struct counters_group *group) +{ + if (group == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot delete group counters: counters_group is NULL.", + __func__); + return false; + } + + int i = 0; + for (; i <= group->max_subgroups; i++) { + struct counters_subgroup *subgroup = group->subgroups[i]; + if (subgroup != NULL) { + delete_counters_subgroup(subgroup); + } + } + + pceplib_free(PCEPLIB_INFRA, group->subgroups); + pceplib_free(PCEPLIB_INFRA, group); + + return true; +} + +bool delete_counters_subgroup(struct counters_subgroup *subgroup) +{ + if (subgroup == NULL || subgroup->counters == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot delete subgroup counters: counters_subgroup is NULL.", + __func__); + return false; + } + + int i = 0; + for (; i <= subgroup->max_counters; i++) { + struct counter *counter = subgroup->counters[i]; + if (counter != NULL) { + pceplib_free(PCEPLIB_INFRA, counter); + } + } + + pceplib_free(PCEPLIB_INFRA, subgroup->counters); + pceplib_free(PCEPLIB_INFRA, subgroup); + + return true; +} + +bool reset_group_counters(struct counters_group *group) +{ + if (group == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot reset group counters: counters_group is NULL.", + __func__); + return false; + } + + int i = 0; + for (; i <= group->max_subgroups; i++) { + struct counters_subgroup *subgroup = group->subgroups[i]; + if (subgroup != NULL) { + reset_subgroup_counters(subgroup); + } + } + + group->start_time = time(NULL); + + return true; +} + +bool reset_subgroup_counters(struct counters_subgroup *subgroup) +{ + if (subgroup == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot reset subgroup counters: counters_subgroup is NULL.", + __func__); + return false; + } + + int i = 0; + for (; i <= subgroup->max_counters; i++) { + struct counter *counter = subgroup->counters[i]; + if (counter != NULL) { + counter->counter_value = 0; + } + } + + return true; +} + +bool increment_counter(struct counters_group *group, uint16_t subgroup_id, + uint16_t counter_id) +{ + if (group == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot increment counter: counters_group is NULL.", + __func__); + return false; + } + + if (subgroup_id >= group->max_subgroups) { + pcep_log( + LOG_DEBUG, + "%s: Cannot increment counter: subgroup_id [%d] is larger than the group max_subgroups [%d].", + __func__, subgroup_id, group->max_subgroups); + return false; + } + + struct counters_subgroup *subgroup = group->subgroups[subgroup_id]; + if (subgroup == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot increment counter: counters_subgroup in counters_group is NULL.", + __func__); + return false; + } + + return increment_subgroup_counter(subgroup, counter_id); +} + +bool increment_subgroup_counter(struct counters_subgroup *subgroup, + uint16_t counter_id) +{ + if (subgroup == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot increment counter: counters_subgroup is NULL.", + __func__); + return false; + } + + if (counter_id >= subgroup->max_counters) { + pcep_log( + LOG_DEBUG, + "%s: Cannot increment counter: counter_id [%d] is larger than the subgroup max_counters [%d].", + __func__, counter_id, subgroup->max_counters); + return false; + } + + if (subgroup->counters[counter_id] == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot increment counter: No counter exists for counter_id [%d].", + __func__, counter_id); + return false; + } + + subgroup->counters[counter_id]->counter_value++; + + return true; +} + +bool dump_counters_group_to_log(struct counters_group *group) +{ + if (group == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot dump group counters to log: counters_group is NULL.", + __func__); + return false; + } + + time_t now = time(NULL); + pcep_log( + LOG_INFO, + "%s: PCEP Counters group:\n %s \n Sub-Groups [%d] \n Active for [%d seconds]", + __func__, group->counters_group_name, group->num_subgroups, + (now - group->start_time)); + + int i = 0; + for (; i <= group->max_subgroups; i++) { + struct counters_subgroup *subgroup = group->subgroups[i]; + if (subgroup != NULL) { + dump_counters_subgroup_to_log(subgroup); + } + } + + return true; +} + +bool dump_counters_subgroup_to_log(struct counters_subgroup *subgroup) +{ + if (subgroup == NULL) { + pcep_log( + LOG_INFO, + "%s: Cannot dump subgroup counters to log: counters_subgroup is NULL.", + __func__); + return false; + } + + pcep_log(LOG_INFO, + "%s: \tPCEP Counters sub-group [%s] with [%d] counters", + __func__, subgroup->counters_subgroup_name, + subgroup->num_counters); + + int i = 0; + for (; i <= subgroup->max_counters; i++) { + struct counter *counter = subgroup->counters[i]; + if (counter != NULL) { + pcep_log(LOG_INFO, "%s: \t\t%s %d", __func__, + counter->counter_name, counter->counter_value); + } + } + + return true; +} + +struct counters_subgroup *find_subgroup(const struct counters_group *group, + uint16_t subgroup_id) +{ + int i = 0; + for (; i <= group->max_subgroups; i++) { + struct counters_subgroup *subgroup = group->subgroups[i]; + if (subgroup != NULL) { + if (subgroup->subgroup_id == subgroup_id) { + return subgroup; + } + } + } + + return NULL; +} + +uint32_t subgroup_counters_total(struct counters_subgroup *subgroup) +{ + if (subgroup == NULL) { + return 0; + } + uint32_t counter_total = 0; + int i = 0; + for (; i <= subgroup->max_counters; i++) { + struct counter *counter = subgroup->counters[i]; + if (counter != NULL) { + counter_total += counter->counter_value; + } + } + + return counter_total; +} |