Add better error handling to loader.

This commit is contained in:
Christian Deacon
2025-02-23 07:15:12 -05:00
parent f093bf96c4
commit 4e7c563274
4 changed files with 82 additions and 66 deletions

View File

@@ -22,6 +22,8 @@ struct stat conf_stat;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int ret;
// Parse the command line. // Parse the command line.
cmdline_t cmd = {0}; cmdline_t cmd = {0};
cmd.cfgfile = CONFIG_DEFAULT_PATH; cmd.cfgfile = CONFIG_DEFAULT_PATH;
@@ -41,7 +43,7 @@ int main(int argc, char *argv[])
if (setrlimit(RLIMIT_MEMLOCK, &rl)) if (setrlimit(RLIMIT_MEMLOCK, &rl))
{ {
fprintf(stderr, "Error setting rlimit. Please make sure this program is ran as root!\n"); fprintf(stderr, "[ERROR] Failed to raise rlimit. Please make sure this program is ran as root!\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -52,7 +54,12 @@ int main(int argc, char *argv[])
SetCfgDefaults(&cfg); SetCfgDefaults(&cfg);
// Load config. // Load config.
LoadConfig(&cfg, cmd.cfgfile); if ((ret = LoadConfig(&cfg, cmd.cfgfile)) != 0)
{
fprintf(stderr, "[ERROR] Failed to load config from file system (%s)(%d).\n", cmd.cfgfile, ret);
return EXIT_FAILURE;
}
// Check for list option. // Check for list option.
if (cmd.list) if (cmd.list)
@@ -67,7 +74,7 @@ int main(int argc, char *argv[])
if (ifidx < 0) if (ifidx < 0)
{ {
fprintf(stderr, "Error finding device %s.\n", cfg.interface); fprintf(stderr, "[ERROR] Failed to retrieve index of interface '%s'.\n", cfg.interface);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -77,15 +84,15 @@ int main(int argc, char *argv[])
if (prog == NULL) if (prog == NULL)
{ {
fprintf(stderr, "Error loading eBPF object file. File name => %s.\n", XDP_OBJ_PATH); fprintf(stderr, "[ERROR] Failed to load eBPF object file. Object path => %s.\n", XDP_OBJ_PATH);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// Attach XDP program. // Attach XDP program.
if (AttachXdp(prog, ifidx, 0, &cmd)) if ((ret = AttachXdp(prog, ifidx, 0, &cmd)) != 0)
{ {
fprintf(stderr, "Error attaching XDP program.\n"); fprintf(stderr, "[ERROR] Failed to attach XDP program to interface '%s' (%d).\n", cfg.interface, ret);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -96,7 +103,7 @@ int main(int argc, char *argv[])
// Check for valid maps. // Check for valid maps.
if (filters_map < 0) if (filters_map < 0)
{ {
fprintf(stderr, "Error finding 'filters_map' BPF map.\n"); fprintf(stderr, "[ERROR] Failed to find 'filters_map' BPF map.\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -105,7 +112,7 @@ int main(int argc, char *argv[])
if (stats_map < 0) if (stats_map < 0)
{ {
fprintf(stderr, "Error finding 'stats_map' BPF map.\n"); fprintf(stderr, "[ERROR] Failed to find 'stats_map' BPF map.\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -148,7 +155,10 @@ int main(int argc, char *argv[])
free(cfg.interface); free(cfg.interface);
// Update config. // Update config.
LoadConfig(&cfg, cmd.cfgfile); if ((ret = LoadConfig(&cfg, cmd.cfgfile)) != 0)
{
fprintf(stderr, "[WARNING] Failed to load config after update check (%d)\n", ret);
}
// Update BPF maps. // Update BPF maps.
UpdateFilters(filters_map, &cfg); UpdateFilters(filters_map, &cfg);
@@ -166,7 +176,7 @@ int main(int argc, char *argv[])
{ {
if (CalculateStats(stats_map, cpus)) if (CalculateStats(stats_map, cpus))
{ {
fprintf(stderr, "Error calculating packet stats. Stats map FD => %d.\n", stats_map); fprintf(stderr, "[WARNING] Failed to calculate packet stats. Stats map FD => %d.\n", stats_map);
} }
} }
@@ -178,7 +188,9 @@ int main(int argc, char *argv[])
// Detach XDP program. // Detach XDP program.
if (AttachXdp(prog, ifidx, 1, &cmd)) if (AttachXdp(prog, ifidx, 1, &cmd))
{ {
fprintf(stderr, "Failed to detach XDP program from interface '%s'.\n", cfg.interface); fprintf(stderr, "[ERROR] Failed to detach XDP program from interface '%s'.\n", cfg.interface);
return EXIT_FAILURE;
} }
fprintf(stdout, "Cleaned up and exiting...\n"); fprintf(stdout, "Cleaned up and exiting...\n");

View File

@@ -10,16 +10,16 @@ static FILE *file;
* @param cfg A pointer to the config structure. * @param cfg A pointer to the config structure.
* @param cfg_file The path to the config file. * @param cfg_file The path to the config file.
* *
* @return 0 on success or -1 on error. * @return 0 on success or 1 on error.
*/ */
int LoadConfig(config__t *cfg, char *cfg_file) int LoadConfig(config__t *cfg, char *cfg_file)
{ {
// Open config file. // Open config file.
if (OpenCfg(cfg_file) != 0) if (OpenCfg(cfg_file) != 0)
{ {
fprintf(stderr, "Error opening filters file: %s\n", cfg_file); fprintf(stderr, "Error opening config file.\n");
return -1; return EXIT_FAILURE;
} }
SetCfgDefaults(cfg); SetCfgDefaults(cfg);
@@ -29,12 +29,12 @@ int LoadConfig(config__t *cfg, char *cfg_file)
// Read config and check for errors. // Read config and check for errors.
if (ReadCfg(cfg) != 0) if (ReadCfg(cfg) != 0)
{ {
fprintf(stderr, "Error reading filters file.\n"); fprintf(stderr, "Error reading config file.\n");
return -1; return EXIT_FAILURE;
} }
return 0; return EXIT_SUCCESS;
} }
/** /**
@@ -165,7 +165,7 @@ int ReadCfg(config__t *cfg)
config_destroy(&conf); config_destroy(&conf);
return 1; return EXIT_FAILURE;
} }
// Get interface. // Get interface.
@@ -177,7 +177,7 @@ int ReadCfg(config__t *cfg)
config_destroy(&conf); config_destroy(&conf);
return 1; return EXIT_FAILURE;
} }
cfg->interface = strdup(interface); cfg->interface = strdup(interface);
@@ -534,7 +534,7 @@ int ReadCfg(config__t *cfg)
config_destroy(&conf); config_destroy(&conf);
return 0; return EXIT_SUCCESS;
} }
/** /**
@@ -546,10 +546,13 @@ int ReadCfg(config__t *cfg)
*/ */
void PrintConfig(config__t* cfg) void PrintConfig(config__t* cfg)
{ {
fprintf(stdout, "Current Settings:\n"); fprintf(stdout, "Printing config...\n");
fprintf(stdout, "Interface Name => %s\n", cfg->interface); fprintf(stdout, "\tGeneral Settings\n");
fprintf(stdout, "Update Time => %d\n", cfg->updatetime); fprintf(stdout, "\t\tInterface Name => %s\n", cfg->interface);
fprintf(stdout, "Stdout Update Time => %d\n\n", cfg->stdout_update_time); fprintf(stdout, "\t\tUpdate Time => %d\n", cfg->updatetime);
fprintf(stdout, "\t\tStdout Update Time => %d\n\n", cfg->stdout_update_time);
fprintf(stdout, "\tFiltes\n");
for (int i = 0; i < MAX_FILTERS; i++) for (int i = 0; i < MAX_FILTERS; i++)
{ {
@@ -560,26 +563,26 @@ void PrintConfig(config__t* cfg)
break; break;
} }
fprintf(stdout, "Filter #%d:\n", (i + 1)); fprintf(stdout, "\t\tFilter #%d:\n", (i + 1));
// Main. // Main.
fprintf(stdout, "\tID => %d\n", filter->id); fprintf(stdout, "\t\t\tID => %d\n", filter->id);
fprintf(stdout, "\tEnabled => %d\n", filter->enabled); fprintf(stdout, "\t\t\tEnabled => %d\n", filter->enabled);
fprintf(stdout, "\tAction => %d (0 = Block, 1 = Allow).\n\n", filter->action); fprintf(stdout, "\t\t\tAction => %d (0 = Block, 1 = Allow).\n\n", filter->action);
// IP Options. // IP Options.
fprintf(stdout, "\tIP Options\n"); fprintf(stdout, "\t\t\tIP Options\n");
// IP addresses require additional code for string printing. // IP addresses require additional code for string printing.
struct sockaddr_in sin; struct sockaddr_in sin;
sin.sin_addr.s_addr = filter->src_ip; sin.sin_addr.s_addr = filter->src_ip;
fprintf(stdout, "\t\tSource IPv4 => %s\n", inet_ntoa(sin.sin_addr)); fprintf(stdout, "\t\t\t\tSource IPv4 => %s\n", inet_ntoa(sin.sin_addr));
fprintf(stdout, "\t\tSource CIDR => %d\n", filter->src_cidr); fprintf(stdout, "\t\t\t\tSource CIDR => %d\n", filter->src_cidr);
struct sockaddr_in din; struct sockaddr_in din;
din.sin_addr.s_addr = filter->dst_ip; din.sin_addr.s_addr = filter->dst_ip;
fprintf(stdout, "\t\tDestination IPv4 => %s\n", inet_ntoa(din.sin_addr)); fprintf(stdout, "\t\t\t\tDestination IPv4 => %s\n", inet_ntoa(din.sin_addr));
fprintf(stdout, "\t\tDestination CIDR => %d\n", filter->dst_cidr); fprintf(stdout, "\t\t\t\tDestination CIDR => %d\n", filter->dst_cidr);
struct in6_addr sin6; struct in6_addr sin6;
memcpy(&sin6, &filter->src_ip6, sizeof(sin6)); memcpy(&sin6, &filter->src_ip6, sizeof(sin6));
@@ -587,7 +590,7 @@ void PrintConfig(config__t* cfg)
char srcipv6[INET6_ADDRSTRLEN]; char srcipv6[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &sin6, srcipv6, sizeof(srcipv6)); inet_ntop(AF_INET6, &sin6, srcipv6, sizeof(srcipv6));
fprintf(stdout, "\t\tSource IPv6 => %s\n", srcipv6); fprintf(stdout, "\t\t\t\tSource IPv6 => %s\n", srcipv6);
struct in6_addr din6; struct in6_addr din6;
memcpy(&din6, &filter->dst_ip6, sizeof(din6)); memcpy(&din6, &filter->dst_ip6, sizeof(din6));
@@ -595,43 +598,43 @@ void PrintConfig(config__t* cfg)
char dstipv6[INET6_ADDRSTRLEN]; char dstipv6[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &din6, dstipv6, sizeof(dstipv6)); inet_ntop(AF_INET6, &din6, dstipv6, sizeof(dstipv6));
fprintf(stdout, "\t\tDestination IPv6 => %s\n", dstipv6); fprintf(stdout, "\t\t\t\tDestination IPv6 => %s\n", dstipv6);
// Other IP header information. // Other IP header information.
fprintf(stdout, "\t\tMax Length => %d\n", filter->max_len); fprintf(stdout, "\t\t\t\tMax Length => %d\n", filter->max_len);
fprintf(stdout, "\t\tMin Length => %d\n", filter->min_len); fprintf(stdout, "\t\t\t\tMin Length => %d\n", filter->min_len);
fprintf(stdout, "\t\tMax TTL => %d\n", filter->max_ttl); fprintf(stdout, "\t\t\t\tMax TTL => %d\n", filter->max_ttl);
fprintf(stdout, "\t\tMin TTL => %d\n", filter->min_ttl); fprintf(stdout, "\t\t\t\tMin TTL => %d\n", filter->min_ttl);
fprintf(stdout, "\t\tTOS => %d\n", filter->tos); fprintf(stdout, "\t\t\t\tTOS => %d\n", filter->tos);
fprintf(stdout, "\t\tPPS => %llu\n", filter->pps); fprintf(stdout, "\t\t\t\tPPS => %llu\n", filter->pps);
fprintf(stdout, "\t\tBPS => %llu\n", filter->bps); fprintf(stdout, "\t\t\t\tBPS => %llu\n", filter->bps);
fprintf(stdout, "\t\tBlock Time => %llu\n\n", filter->blocktime); fprintf(stdout, "\t\t\t\tBlock Time => %llu\n\n", filter->blocktime);
// TCP Options. // TCP Options.
fprintf(stdout, "\tTCP Options\n"); fprintf(stdout, "\t\t\tTCP Options\n");
fprintf(stdout, "\t\tTCP Enabled => %d\n", filter->tcpopts.enabled); fprintf(stdout, "\t\t\t\tTCP Enabled => %d\n", filter->tcpopts.enabled);
fprintf(stdout, "\t\tTCP Source Port => %d\n", filter->tcpopts.sport); fprintf(stdout, "\t\t\t\tTCP Source Port => %d\n", filter->tcpopts.sport);
fprintf(stdout, "\t\tTCP Destination Port => %d\n", filter->tcpopts.dport); fprintf(stdout, "\t\t\t\tTCP Destination Port => %d\n", filter->tcpopts.dport);
fprintf(stdout, "\t\tTCP URG Flag => %d\n", filter->tcpopts.urg); fprintf(stdout, "\t\t\t\tTCP URG Flag => %d\n", filter->tcpopts.urg);
fprintf(stdout, "\t\tTCP ACK Flag => %d\n", filter->tcpopts.ack); fprintf(stdout, "\t\t\t\tTCP ACK Flag => %d\n", filter->tcpopts.ack);
fprintf(stdout, "\t\tTCP RST Flag => %d\n", filter->tcpopts.rst); fprintf(stdout, "\t\t\t\tTCP RST Flag => %d\n", filter->tcpopts.rst);
fprintf(stdout, "\t\tTCP PSH Flag => %d\n", filter->tcpopts.psh); fprintf(stdout, "\t\t\t\tTCP PSH Flag => %d\n", filter->tcpopts.psh);
fprintf(stdout, "\t\tTCP SYN Flag => %d\n", filter->tcpopts.syn); fprintf(stdout, "\t\t\t\tTCP SYN Flag => %d\n", filter->tcpopts.syn);
fprintf(stdout, "\t\tTCP FIN Flag => %d\n", filter->tcpopts.fin); fprintf(stdout, "\t\t\t\tTCP FIN Flag => %d\n", filter->tcpopts.fin);
fprintf(stdout, "\t\tTCP ECE Flag => %d\n", filter->tcpopts.ece); fprintf(stdout, "\t\t\t\tTCP ECE Flag => %d\n", filter->tcpopts.ece);
fprintf(stdout, "\t\tTCP CWR Flag => %d\n\n", filter->tcpopts.cwr); fprintf(stdout, "\t\t\t\tTCP CWR Flag => %d\n\n", filter->tcpopts.cwr);
// UDP Options. // UDP Options.
fprintf(stdout, "\tUDP Options\n"); fprintf(stdout, "\t\t\tUDP Options\n");
fprintf(stdout, "\t\tUDP Enabled => %d\n", filter->udpopts.enabled); fprintf(stdout, "\t\t\t\tUDP Enabled => %d\n", filter->udpopts.enabled);
fprintf(stdout, "\t\tUDP Source Port => %d\n", filter->udpopts.sport); fprintf(stdout, "\t\t\t\tUDP Source Port => %d\n", filter->udpopts.sport);
fprintf(stdout, "\t\tUDP Destination Port => %d\n\n", filter->udpopts.dport); fprintf(stdout, "\t\t\t\tUDP Destination Port => %d\n\n", filter->udpopts.dport);
// ICMP Options. // ICMP Options.
fprintf(stdout, "\tICMP Options\n"); fprintf(stdout, "\t\t\tICMP Options\n");
fprintf(stdout, "\t\tICMP Enabled => %d\n", filter->icmpopts.enabled); fprintf(stdout, "\t\t\t\tICMP Enabled => %d\n", filter->icmpopts.enabled);
fprintf(stdout, "\t\tICMP Code => %d\n", filter->icmpopts.code); fprintf(stdout, "\t\t\t\tICMP Code => %d\n", filter->icmpopts.code);
fprintf(stdout, "\t\tICMP Type => %d\n", filter->icmpopts.type); fprintf(stdout, "\t\t\t\tICMP Type => %d\n", filter->icmpopts.type);
fprintf(stdout, "\n\n"); fprintf(stdout, "\n\n");
} }

View File

@@ -4,7 +4,7 @@
#include <libbpf.h> #include <libbpf.h>
#include <xdp/libxdp.h> #include <xdp/libxdp.h>
#include <common/all.h> #include <common/all.h>
#include <loader/utils/cmdline.h> #include <loader/utils/cmdline.h>
#include <loader/utils/config.h> #include <loader/utils/config.h>

View File

@@ -166,6 +166,7 @@ int AttachXdp(struct xdp_program *prog, int ifidx, u8 detach, cmdline_t *cmd)
void UpdateFilters(int filters_map, config__t *cfg) void UpdateFilters(int filters_map, config__t *cfg)
{ {
int i; int i;
int ret;
// Loop through all filters and delete the map. We do this in the case rules were edited and were put out of order since the key doesn't uniquely map to a specific rule. // Loop through all filters and delete the map. We do this in the case rules were edited and were put out of order since the key doesn't uniquely map to a specific rule.
for (i = 0; i < MAX_FILTERS; i++) for (i = 0; i < MAX_FILTERS; i++)
@@ -194,9 +195,9 @@ void UpdateFilters(int filters_map, config__t *cfg)
} }
// Attempt to update BPF map. // Attempt to update BPF map.
if (bpf_map_update_elem(filters_map, &i, &filter, BPF_ANY) == -1) if ((ret = bpf_map_update_elem(filters_map, &i, &filter, BPF_ANY)) != 0)
{ {
fprintf(stderr, "Error updating BPF item #%d\n", i); fprintf(stderr, "[WARNING] Failed to update filter #%d due to BPF update error (%d).\n", i, ret);
} }
} }
} }