Add option to calculate packet counters per second.
This commit is contained in:
@@ -128,6 +128,7 @@ The following table quickly explains the data types used within the configuratio
|
||||
| interface | string | `NULL` | The network interface name to attach the XDP program to (usually retrieved with `ip a` or `ifconfig`). |
|
||||
| update_time | uint | `0` | How often to update the config and filtering rules from the file system in seconds (0 disables). |
|
||||
| no_stats | bool | `false` | Whether to enable or disable packet counters. Disabling packet counters will improve performance, but result in less visibility on what the XDP Firewall is doing. |
|
||||
| stats_per_second | bool | `false` | If true, packet counters and stats are calculated per second. `stdout_update_time` must be 1000 or less for this to work properly. |
|
||||
| stdout_update_time | uint | `1000` | How often to update `stdout` when displaying packet counters in milliseconds. |
|
||||
| filters | Array of Filter Object(s) | `NULL` | An array of filters to use with the XDP Firewall. |
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ int main(int argc, char *argv[])
|
||||
struct stat conf_stat;
|
||||
|
||||
// Check if we're doing stats.
|
||||
if (!cfg.nostats)
|
||||
if (!cfg.no_stats)
|
||||
{
|
||||
doing_stats = 1;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Check for auto-update.
|
||||
if (cfg.updatetime > 0 && (cur_time - last_update_check) > cfg.updatetime)
|
||||
if (cfg.update_time > 0 && (cur_time - last_update_check) > cfg.update_time)
|
||||
{
|
||||
// Check if config file have been modified
|
||||
if (stat(cmd.cfgfile, &conf_stat) == 0 && conf_stat.st_mtime > last_config_check) {
|
||||
@@ -234,7 +234,7 @@ int main(int argc, char *argv[])
|
||||
last_config_check = time(NULL);
|
||||
|
||||
// Make sure we set doing stats if needed.
|
||||
if (!cfg.nostats && !doing_stats)
|
||||
if (!cfg.no_stats && !doing_stats)
|
||||
{
|
||||
doing_stats = 1;
|
||||
}
|
||||
@@ -245,9 +245,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Calculate and display stats if enabled.
|
||||
if (!cfg.nostats)
|
||||
if (!cfg.no_stats)
|
||||
{
|
||||
if (CalculateStats(stats_map, cpus))
|
||||
if (CalculateStats(stats_map, cpus, cfg.stats_per_second))
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "[WARNING] Failed to calculate packet stats. Stats map FD => %d...\n", stats_map);
|
||||
}
|
||||
|
||||
@@ -46,9 +46,10 @@ void SetCfgDefaults(config__t *cfg)
|
||||
{
|
||||
cfg->verbose = 2;
|
||||
cfg->log_file = strdup("/var/log/xdpfw/xdpfw.log");
|
||||
cfg->updatetime = 0;
|
||||
cfg->update_time = 0;
|
||||
cfg->interface = NULL;
|
||||
cfg->nostats = 0;
|
||||
cfg->no_stats = 0;
|
||||
cfg->stats_per_second = 0;
|
||||
cfg->stdout_update_time = 1000;
|
||||
|
||||
for (int i = 0; i < MAX_FILTERS; i++)
|
||||
@@ -214,11 +215,11 @@ int ReadCfg(config__t *cfg)
|
||||
cfg->interface = strdup(interface);
|
||||
|
||||
// Get auto update time.
|
||||
int updatetime;
|
||||
int update_time;
|
||||
|
||||
if (config_lookup_int(&conf, "update_time", &updatetime) == CONFIG_TRUE)
|
||||
if (config_lookup_int(&conf, "update_time", &update_time) == CONFIG_TRUE)
|
||||
{
|
||||
cfg->updatetime = updatetime;
|
||||
cfg->update_time = update_time;
|
||||
}
|
||||
|
||||
// Get stdout update time.
|
||||
@@ -230,11 +231,19 @@ int ReadCfg(config__t *cfg)
|
||||
}
|
||||
|
||||
// Get no stats.
|
||||
int nostats;
|
||||
int no_stats;
|
||||
|
||||
if (config_lookup_bool(&conf, "no_stats", &nostats) == CONFIG_TRUE)
|
||||
if (config_lookup_bool(&conf, "no_stats", &no_stats) == CONFIG_TRUE)
|
||||
{
|
||||
cfg->nostats = nostats;
|
||||
cfg->no_stats = no_stats;
|
||||
}
|
||||
|
||||
// Stats per second.
|
||||
int stats_per_second;
|
||||
|
||||
if (config_lookup_bool(&conf, "stats_per_second", &stats_per_second) == CONFIG_TRUE)
|
||||
{
|
||||
cfg->stats_per_second = stats_per_second;
|
||||
}
|
||||
|
||||
// Read filters in filters_map structure.
|
||||
@@ -586,9 +595,9 @@ void PrintConfig(config__t* cfg)
|
||||
fprintf(stdout, "Printing config...\n");
|
||||
fprintf(stdout, "\tGeneral Settings\n");
|
||||
fprintf(stdout, "\t\tInterface Name => %s\n", cfg->interface);
|
||||
fprintf(stdout, "\t\tUpdate Time => %d\n", cfg->updatetime);
|
||||
fprintf(stdout, "\t\tUpdate Time => %d\n", cfg->update_time);
|
||||
fprintf(stdout, "\t\tStdout Update Time => %d\n", cfg->stdout_update_time);
|
||||
fprintf(stdout, "\t\tNo Stats => %d\n\n", cfg->nostats);
|
||||
fprintf(stdout, "\t\tNo Stats => %d\n\n", cfg->no_stats);
|
||||
|
||||
fprintf(stdout, "\tFilters\n");
|
||||
|
||||
|
||||
@@ -18,8 +18,9 @@ struct config
|
||||
int verbose;
|
||||
char *log_file;
|
||||
char *interface;
|
||||
u16 updatetime;
|
||||
unsigned int nostats : 1;
|
||||
u16 update_time;
|
||||
unsigned int no_stats : 1;
|
||||
unsigned int stats_per_second : 1;
|
||||
int stdout_update_time;
|
||||
filter_t filters[MAX_FILTERS];
|
||||
} typedef config__t; // config_t is taken by libconfig -.-
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
#include <loader/utils/stats.h>
|
||||
|
||||
struct timespec last_update_time = {0};
|
||||
|
||||
u64 last_allowed = 0;
|
||||
u64 last_dropped = 0;
|
||||
u64 last_passed = 0;
|
||||
|
||||
/**
|
||||
* Calculates and displays packet counters/stats.
|
||||
*
|
||||
* @param stats_map The stats map BPF FD.
|
||||
* @param cpus The amount of CPUs the host has.
|
||||
* @param per_second Calculate packet counters per second (PPS).
|
||||
*
|
||||
* @return 0 on success or 1 on failure.
|
||||
*/
|
||||
int CalculateStats(int stats_map, int cpus)
|
||||
int CalculateStats(int stats_map, int cpus, int per_second)
|
||||
{
|
||||
u32 key = 0;
|
||||
|
||||
@@ -40,10 +47,49 @@ int CalculateStats(int stats_map, int cpus)
|
||||
dropped += stats[i].dropped;
|
||||
passed += stats[i].passed;
|
||||
}
|
||||
|
||||
u64 allowed_val = allowed, dropped_val = dropped, passed_val = passed;
|
||||
|
||||
if (per_second)
|
||||
{
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now); // Get precise time
|
||||
double elapsed_time = (now.tv_sec - last_update_time.tv_sec) +
|
||||
(now.tv_nsec - last_update_time.tv_nsec) / 1e9;
|
||||
|
||||
if (elapsed_time > 0)
|
||||
{
|
||||
allowed_val = (allowed - last_allowed) / elapsed_time;
|
||||
dropped_val = (dropped - last_dropped) / elapsed_time;
|
||||
passed_val = (passed - last_passed) / elapsed_time;
|
||||
}
|
||||
|
||||
last_allowed = allowed;
|
||||
last_dropped = dropped;
|
||||
last_passed = passed;
|
||||
last_update_time = now;
|
||||
}
|
||||
|
||||
char allowed_str[12];
|
||||
char dropped_str[12];
|
||||
char passed_str[12];
|
||||
|
||||
if (per_second)
|
||||
{
|
||||
snprintf(allowed_str, sizeof(allowed_str), "%llu PPS", allowed_val);
|
||||
snprintf(dropped_str, sizeof(dropped_str), "%llu PPS", dropped_val);
|
||||
snprintf(passed_str, sizeof(passed_str), "%llu PPS", passed_val);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(allowed_str, sizeof(allowed_str), "%llu", allowed_val);
|
||||
snprintf(dropped_str, sizeof(dropped_str), "%llu", dropped_val);
|
||||
snprintf(passed_str, sizeof(passed_str), "%llu", passed_val);
|
||||
}
|
||||
|
||||
printf("\r\033[1;32mAllowed:\033[0m %llu | ", allowed);
|
||||
printf("\033[1;31mDropped:\033[0m %llu | ", dropped);
|
||||
printf("\033[1;34mPassed:\033[0m %llu", passed);
|
||||
printf("\r\033[1;32mAllowed:\033[0m %s | ", allowed_str);
|
||||
printf("\033[1;31mDropped:\033[0m %s | ", dropped_str);
|
||||
printf("\033[1;34mPassed:\033[0m %s", passed_str);
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
|
||||
@@ -8,4 +8,6 @@
|
||||
#include <loader/utils/config.h>
|
||||
#include <loader/utils/helpers.h>
|
||||
|
||||
int CalculateStats(int stats_map, int cpus);
|
||||
#include <time.h>
|
||||
|
||||
int CalculateStats(int stats_map, int cpus, int per_second);
|
||||
Reference in New Issue
Block a user