Optimize inserting filters into BPF map.

This commit is contained in:
Christian Deacon
2025-02-27 06:59:52 -05:00
parent 5f60030721
commit c631266061
4 changed files with 17 additions and 24 deletions

View File

@@ -62,10 +62,8 @@ struct icmp_opts
struct filter struct filter
{ {
u8 id; unsigned int set : 1;
unsigned int log : 1; unsigned int log : 1;
unsigned int enabled : 1; unsigned int enabled : 1;
u8 action; u8 action;

View File

@@ -57,7 +57,7 @@ void SetCfgDefaults(config__t *cfg)
{ {
filter_t* filter = &cfg->filters[i]; filter_t* filter = &cfg->filters[i];
filter->id = 0; filter->set = 0;
filter->enabled = 1; filter->enabled = 1;
filter->log = 0; filter->log = 0;
@@ -318,9 +318,6 @@ int ReadCfg(config__t *cfg, config_overrides_t* overrides)
return 1; return 1;
} }
// Set filter count.
int filters = 0;
for (int i = 0; i < config_setting_length(setting); i++) for (int i = 0; i < config_setting_length(setting); i++)
{ {
filter_t* filter = &cfg->filters[i]; filter_t* filter = &cfg->filters[i];
@@ -633,8 +630,8 @@ int ReadCfg(config__t *cfg, config_overrides_t* overrides)
filter->icmpopts.do_type = 1; filter->icmpopts.do_type = 1;
} }
// Assign ID and increase filter count. // Make sure filter is set.
filter->id = ++filters; filter->set = 1;
} }
config_destroy(&conf); config_destroy(&conf);
@@ -682,7 +679,7 @@ void PrintConfig(config__t* cfg)
{ {
filter_t *filter = &cfg->filters[i]; filter_t *filter = &cfg->filters[i];
if (filter->id < 1) if (!filter->set)
{ {
break; break;
} }
@@ -690,7 +687,6 @@ void PrintConfig(config__t* cfg)
printf("\t\tFilter #%d:\n", (i + 1)); printf("\t\tFilter #%d:\n", (i + 1));
// Main. // Main.
printf("\t\t\tID => %d\n", filter->id);
printf("\t\t\tLog => %d\n", filter->log); printf("\t\t\tLog => %d\n", filter->log);
printf("\t\t\tEnabled => %d\n", filter->enabled); printf("\t\t\tEnabled => %d\n", filter->enabled);
printf("\t\t\tAction => %d (0 = Block, 1 = Allow).\n\n", filter->action); printf("\t\t\tAction => %d (0 = Block, 1 = Allow).\n\n", filter->action);

View File

@@ -187,35 +187,40 @@ int AttachXdp(struct xdp_program *prog, char** mode, int ifidx, u8 detach, cmdli
void UpdateFilters(int filters_map, config__t *cfg) void UpdateFilters(int filters_map, config__t *cfg)
{ {
int ret; int ret;
int cur_idx = 0;
// Add a filter to the filter maps. // Add a filter to the filter maps.
for (int i = 0; i < MAX_FILTERS; i++) for (int i = 0; i < MAX_FILTERS; i++)
{ {
filter_t* filter = &cfg->filters[i];
// Delete previous rule from BPF map. // Delete previous rule from BPF 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. // 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.
u32 key = i; u32 key = i;
bpf_map_delete_elem(filters_map, &key); bpf_map_delete_elem(filters_map, &key);
// Check if we have a valid filter. // Only insert set and enabled filters.
if (cfg->filters[i].id < 1) if (!filter->set || !filter->enabled)
{ {
continue; continue;
} }
// Create value array (max CPUs in size) since we're using a per CPU map. // Create value array (max CPUs in size) since we're using a per CPU map.
filter_t filter[MAX_CPUS]; filter_t filter_cpus[MAX_CPUS];
memset(filter, 0, sizeof(filter)); memset(filter_cpus, 0, sizeof(filter_cpus));
for (int j = 0; j < MAX_CPUS; j++) for (int j = 0; j < MAX_CPUS; j++)
{ {
filter[j] = cfg->filters[i]; filter_cpus[j] = *filter;
} }
// Attempt to update BPF map. // Attempt to update BPF map.
if ((ret = bpf_map_update_elem(filters_map, &i, &filter, BPF_ANY)) != 0) if ((ret = bpf_map_update_elem(filters_map, &cur_idx, &filter_cpus, BPF_ANY)) != 0)
{ {
fprintf(stderr, "[WARNING] Failed to update filter #%d due to BPF update error (%d)...\n", i, ret); fprintf(stderr, "[WARNING] Failed to update filter #%d due to BPF update error (%d)...\n", i, ret);
} }
cur_idx++;
} }
} }

View File

@@ -275,17 +275,11 @@ int xdp_prog_main(struct xdp_md *ctx)
filter_t *filter = bpf_map_lookup_elem(&filters_map, &key); filter_t *filter = bpf_map_lookup_elem(&filters_map, &key);
// Check if ID is above 0 (if 0, it's an invalid rule). // Check if ID is above 0 (if 0, it's an invalid rule).
if (!filter || filter->id < 1) if (!filter || !filter->set)
{ {
break; break;
} }
// Check if the rule is enabled.
if (!filter->enabled)
{
continue;
}
// Do specific IPv6. // Do specific IPv6.
if (iph6) if (iph6)
{ {