Implement new logging system.
This commit is contained in:
@@ -46,6 +46,8 @@ int LoadConfig(config__t *cfg, char *cfg_file)
|
||||
*/
|
||||
void SetCfgDefaults(config__t *cfg)
|
||||
{
|
||||
cfg->verbose = 1;
|
||||
cfg->log_file = strdup("/var/log/xdpfw/xdpfw.log");
|
||||
cfg->updatetime = 0;
|
||||
cfg->interface = NULL;
|
||||
cfg->nostats = 0;
|
||||
@@ -168,6 +170,35 @@ int ReadCfg(config__t *cfg)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int verbose;
|
||||
|
||||
if (config_lookup_int(&conf, "verbose", &verbose) == CONFIG_TRUE)
|
||||
{
|
||||
cfg->verbose = verbose;
|
||||
}
|
||||
|
||||
const char* log_file;
|
||||
|
||||
if (config_lookup_string(&conf, "log_file", &log_file) == CONFIG_TRUE)
|
||||
{
|
||||
// We must free previous value to prevent memory leak.
|
||||
if (cfg->log_file != NULL)
|
||||
{
|
||||
free(cfg->log_file);
|
||||
cfg->log_file = NULL;
|
||||
}
|
||||
|
||||
if (strlen(log_file) > 0)
|
||||
{
|
||||
cfg->log_file = strdup(log_file);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg->log_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Get interface.
|
||||
const char *interface;
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
struct config
|
||||
{
|
||||
int verbose;
|
||||
char *log_file;
|
||||
char *interface;
|
||||
u16 updatetime;
|
||||
unsigned int nostats : 1;
|
||||
|
||||
96
src/loader/utils/logging.c
Normal file
96
src/loader/utils/logging.c
Normal file
@@ -0,0 +1,96 @@
|
||||
#include <loader/utils/logging.h>
|
||||
|
||||
/**
|
||||
* Prints a log message to stdout/stderr along with a file if specified.
|
||||
*
|
||||
* @param req_lvl The required level for this message.
|
||||
* @param cur_lvl The current verbose level.
|
||||
* @param error If 1, sets pipe to stderr instead of stdout.
|
||||
* @param msg The log message.
|
||||
* @param args A VA list of arguments for the message.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static void LogMsgRaw(int req_lvl, int cur_lvl, int error, const char* log_path, const char* msg, va_list args)
|
||||
{
|
||||
if (cur_lvl < req_lvl)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FILE* pipe = stdout;
|
||||
|
||||
if (error)
|
||||
{
|
||||
pipe = stderr;
|
||||
}
|
||||
|
||||
// We need to format the message.
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
int len = vsnprintf(NULL, 0, msg, args_copy);
|
||||
va_end(args_copy);
|
||||
|
||||
if (len < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char f_msg[len + 1];
|
||||
vsnprintf(f_msg, sizeof(f_msg), msg, args);
|
||||
|
||||
char full_msg[len + 6 + 1];
|
||||
snprintf(full_msg, sizeof(full_msg), "[%d] %s", req_lvl, f_msg);
|
||||
|
||||
fprintf(pipe, "%s\n", full_msg);
|
||||
|
||||
if (log_path != NULL)
|
||||
{
|
||||
FILE* log_file = fopen(log_path, "a");
|
||||
|
||||
if (!log_file)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
time_t now = time(NULL);
|
||||
struct tm* tm_val = localtime(&now);
|
||||
|
||||
if (!tm_val)
|
||||
{
|
||||
fclose(log_file);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
char log_file_msg[len + 22 + 1];
|
||||
|
||||
snprintf(log_file_msg, sizeof(log_file_msg), "[%02d-%02d-%02d %02d:%02d:%02d]%s", tm_val->tm_year % 100, tm_val->tm_mon + 1, tm_val->tm_mday,
|
||||
tm_val->tm_hour, tm_val->tm_min, tm_val->tm_sec, full_msg);
|
||||
|
||||
fprintf(log_file, "%s\n", log_file_msg);
|
||||
|
||||
fclose(log_file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a log message using LogMsgRaw().
|
||||
*
|
||||
* @param cfg A pointer to the config structure.
|
||||
* @param req_lvl The required level for this message.
|
||||
* @param error Whether this is an error.
|
||||
* @param msg The log message with format support.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void LogMsg(config__t* cfg, int req_lvl, int error, const char* msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
|
||||
LogMsgRaw(req_lvl, cfg->verbose, error, (const char*)cfg->log_file, msg, args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
15
src/loader/utils/logging.h
Normal file
15
src/loader/utils/logging.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <common/all.h>
|
||||
|
||||
#include <loader/utils/config.h>
|
||||
|
||||
#include <xdp/libxdp.h>
|
||||
|
||||
void LogMsg(config__t* cfg, int req_lvl, int error, const char* msg, ...);
|
||||
@@ -60,31 +60,32 @@ struct xdp_program *LoadBpfObj(const char *file_name)
|
||||
* Attempts to attach or detach (progfd = -1) a BPF/XDP program to an interface.
|
||||
*
|
||||
* @param prog A pointer to the XDP program structure.
|
||||
* @param mode_used The mode being used.
|
||||
* @param ifidx The index to the interface to attach to.
|
||||
* @param detach If above 0, attempts to detach XDP program.
|
||||
* @param cmd A pointer to a cmdline struct that includes command line arguments (mostly checking for offload/HW mode set).
|
||||
*
|
||||
* @return 0 on success and 1 on error.
|
||||
*/
|
||||
int AttachXdp(struct xdp_program *prog, int ifidx, u8 detach, cmdline_t *cmd)
|
||||
int AttachXdp(struct xdp_program *prog, char** mode, int ifidx, u8 detach, cmdline_t *cmd)
|
||||
{
|
||||
int err;
|
||||
|
||||
u32 mode = XDP_MODE_NATIVE;
|
||||
char *smode;
|
||||
u32 attach_mode = XDP_MODE_NATIVE;
|
||||
|
||||
smode = "DRV/native";
|
||||
*mode = "DRV/native";
|
||||
|
||||
if (cmd->offload)
|
||||
{
|
||||
smode = "HW/offload";
|
||||
*mode = "HW/offload";
|
||||
|
||||
mode = XDP_MODE_HW;
|
||||
attach_mode = XDP_MODE_HW;
|
||||
}
|
||||
else if (cmd->skb)
|
||||
{
|
||||
smode = "SKB/generic";
|
||||
mode = XDP_MODE_SKB;
|
||||
*mode = "SKB/generic";
|
||||
|
||||
attach_mode = XDP_MODE_SKB;
|
||||
}
|
||||
|
||||
int exit = 0;
|
||||
@@ -96,39 +97,35 @@ int AttachXdp(struct xdp_program *prog, int ifidx, u8 detach, cmdline_t *cmd)
|
||||
|
||||
if (detach)
|
||||
{
|
||||
err = xdp_program__detach(prog, ifidx, mode, 0);
|
||||
err = xdp_program__detach(prog, ifidx, attach_mode, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = xdp_program__attach(prog, ifidx, mode, 0);
|
||||
err = xdp_program__attach(prog, ifidx, attach_mode, 0);
|
||||
}
|
||||
|
||||
if (err)
|
||||
{
|
||||
if (err)
|
||||
{
|
||||
fprintf(stderr, "Could not attach with mode %s (%s) (%d).\n", smode, strerror(-err), -err);
|
||||
}
|
||||
|
||||
// Decrease mode.
|
||||
switch (mode)
|
||||
switch (attach_mode)
|
||||
{
|
||||
case XDP_MODE_HW:
|
||||
mode = XDP_MODE_NATIVE;
|
||||
smode = "DRV/native";
|
||||
attach_mode = XDP_MODE_NATIVE;
|
||||
*mode = "DRV/native";
|
||||
|
||||
break;
|
||||
|
||||
case XDP_MODE_NATIVE:
|
||||
mode = XDP_MODE_SKB;
|
||||
smode = "SKB/generic";
|
||||
attach_mode = XDP_MODE_SKB;
|
||||
*mode = "SKB/generic";
|
||||
|
||||
break;
|
||||
|
||||
case XDP_MODE_SKB:
|
||||
// Exit loop.
|
||||
exit = 1;
|
||||
smode = NULL;
|
||||
|
||||
*mode = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -142,16 +139,11 @@ int AttachXdp(struct xdp_program *prog, int ifidx, u8 detach, cmdline_t *cmd)
|
||||
}
|
||||
|
||||
// If exit is set to 1 or smode is NULL, it indicates full failure.
|
||||
if (exit || smode == NULL)
|
||||
if (exit || *mode == NULL)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (detach < 1)
|
||||
{
|
||||
fprintf(stdout, "Loaded XDP program on mode %s...\n", smode);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
|
||||
int FindMapFd(struct xdp_program *prog, const char *map_name);
|
||||
struct xdp_program *LoadBpfObj(const char *file_name);
|
||||
int AttachXdp(struct xdp_program *prog, int ifidx, u8 detach, cmdline_t *cmd);
|
||||
int AttachXdp(struct xdp_program *prog, char** mode, int ifidx, u8 detach, cmdline_t *cmd);
|
||||
void UpdateFilters(int filters_map, config__t *cfg);
|
||||
Reference in New Issue
Block a user