Optimize inserting filters into BPF map.
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user