/*
* 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 .
*
* Author : Brady Johnson
*
*/
/*
* Implementation of PCEP Counters.
*/
#include
#include
#include
#include
#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;
}