Separate filter rule structures from config and BPF map.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,75 @@
|
||||
|
||||
#define CONFIG_DEFAULT_PATH "/etc/xdpfw/xdpfw.conf"
|
||||
|
||||
struct filter_rule_ip_opts
|
||||
{
|
||||
const char* src_ip;
|
||||
const char* dst_ip;
|
||||
|
||||
const char* src_ip6;
|
||||
const char* dst_ip6;
|
||||
|
||||
int min_ttl;
|
||||
int max_ttl;
|
||||
|
||||
int min_len;
|
||||
int max_len;
|
||||
|
||||
int tos;
|
||||
} typedef filter_rule_ip_opts_t;
|
||||
|
||||
struct filter_rule_filter_tcp
|
||||
{
|
||||
int enabled;
|
||||
|
||||
int sport;
|
||||
int dport;
|
||||
|
||||
int urg;
|
||||
int ack;
|
||||
int rst;
|
||||
int psh;
|
||||
int syn;
|
||||
int fin;
|
||||
int ece;
|
||||
int cwr;
|
||||
} typedef filter_rule_filter_tcp_t;
|
||||
|
||||
struct filter_rule_filter_udp
|
||||
{
|
||||
int enabled;
|
||||
|
||||
int sport;
|
||||
int dport;
|
||||
} typedef filter_rule_filter_udp_t;
|
||||
|
||||
struct filter_rule_filter_icmp
|
||||
{
|
||||
int enabled;
|
||||
|
||||
int code;
|
||||
int type;
|
||||
} typedef filter_rule_filter_icmp_t;
|
||||
|
||||
struct filter_rule_cfg
|
||||
{
|
||||
int set;
|
||||
int log;
|
||||
int enabled;
|
||||
|
||||
int action;
|
||||
int block_time;
|
||||
|
||||
s64 pps;
|
||||
s64 bps;
|
||||
|
||||
filter_rule_ip_opts_t ip;
|
||||
|
||||
filter_rule_filter_tcp_t tcp;
|
||||
filter_rule_filter_udp_t udp;
|
||||
filter_rule_filter_icmp_t icmp;
|
||||
} typedef filter_rule_cfg_t;
|
||||
|
||||
struct config
|
||||
{
|
||||
int verbose;
|
||||
@@ -24,7 +93,7 @@ struct config
|
||||
unsigned int stats_per_second : 1;
|
||||
int stdout_update_time;
|
||||
|
||||
filter_t filters[MAX_FILTERS];
|
||||
filter_rule_cfg_t filters[MAX_FILTERS];
|
||||
const char* drop_ranges[MAX_IP_RANGES];
|
||||
} typedef config__t; // config_t is taken by libconfig -.-
|
||||
|
||||
@@ -41,10 +110,10 @@ struct config_overrides
|
||||
} typedef config_overrides_t;
|
||||
|
||||
void set_cfg_defaults(config__t *cfg);
|
||||
void set_filter_defaults(filter_t* filter);
|
||||
void set_filter_defaults(filter_rule_cfg_t* filter);
|
||||
|
||||
void print_cfg(config__t* cfg);
|
||||
void PrintFilter(filter_t* filter, int idx);
|
||||
void print_filter(filter_rule_cfg_t* filter, int idx);
|
||||
|
||||
int load_cfg(config__t *cfg, const char* cfg_file, config_overrides_t* overrides);
|
||||
int save_cfg(config__t* cfg, const char* file_path);
|
||||
|
||||
@@ -134,7 +134,7 @@ int hdl_filters_rb_event(void* ctx, void* data, size_t sz)
|
||||
config__t* cfg = (config__t*)ctx;
|
||||
filter_log_event_t* e = (filter_log_event_t*)data;
|
||||
|
||||
filter_t* filter = &cfg->filters[e->filter_id];
|
||||
filter_rule_cfg_t* filter = &cfg->filters[e->filter_id];
|
||||
|
||||
if (filter == NULL)
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ int get_map_fd(struct xdp_program *prog, const char *map_name)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static int LibBPFSilent(enum libbpf_print_level level, const char *format, va_list args)
|
||||
static int libbpf_silent(enum libbpf_print_level level, const char *format, va_list args)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ void set_libbpf_log_mode(int silent)
|
||||
{
|
||||
if (silent)
|
||||
{
|
||||
libbpf_set_print(LibBPFSilent);
|
||||
libbpf_set_print(libbpf_silent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,21 +221,239 @@ void delete_filters(int map_filters)
|
||||
* Updates a filter rule.
|
||||
*
|
||||
* @param map_filters The filters BPF map FD.
|
||||
* @param filter A pointer to the filter.
|
||||
* @param filter_cfg A pointer to the filter config rule.
|
||||
* @param idx The filter index to insert or update.
|
||||
*
|
||||
* @return 0 on success or error value of bpf_map_update_elem().
|
||||
*/
|
||||
int update_filter(int map_filters, filter_t* filter, int idx)
|
||||
int update_filter(int map_filters, filter_rule_cfg_t* filter_cfg, int idx)
|
||||
{
|
||||
int ret;
|
||||
filter_t filter = {0};
|
||||
|
||||
filter.set = filter_cfg->set;
|
||||
|
||||
if (filter_cfg->enabled > -1)
|
||||
{
|
||||
filter.enabled = filter_cfg->enabled;
|
||||
}
|
||||
|
||||
if (filter_cfg->log > -1)
|
||||
{
|
||||
filter.log = filter_cfg->log;
|
||||
}
|
||||
|
||||
if (filter_cfg->action > -1)
|
||||
{
|
||||
filter.action = filter_cfg->action;
|
||||
}
|
||||
|
||||
if (filter_cfg->block_time > -1)
|
||||
{
|
||||
filter.block_time = filter_cfg->block_time;
|
||||
}
|
||||
|
||||
if (filter_cfg->pps > -1)
|
||||
{
|
||||
filter.do_pps = 1;
|
||||
|
||||
filter.pps = (u64) filter_cfg->pps;
|
||||
}
|
||||
|
||||
if (filter_cfg->bps > -1)
|
||||
{
|
||||
filter.do_bps = 1;
|
||||
|
||||
filter.bps = (u64) filter_cfg->bps;
|
||||
}
|
||||
|
||||
if (filter_cfg->ip.src_ip)
|
||||
{
|
||||
ip_range_t ip_range = parse_ip_range(filter_cfg->ip.src_ip);
|
||||
|
||||
filter.ip.src_ip = ip_range.ip;
|
||||
filter.ip.src_cidr = ip_range.cidr;
|
||||
}
|
||||
|
||||
if (filter_cfg->ip.dst_ip)
|
||||
{
|
||||
ip_range_t ip_range = parse_ip_range(filter_cfg->ip.dst_ip);
|
||||
|
||||
filter.ip.dst_ip = ip_range.ip;
|
||||
filter.ip.dst_cidr = ip_range.cidr;
|
||||
}
|
||||
|
||||
if (filter_cfg->ip.src_ip6)
|
||||
{
|
||||
struct in6_addr in;
|
||||
|
||||
inet_pton(AF_INET6, filter_cfg->ip.src_ip6, &in);
|
||||
|
||||
memcpy(filter.ip.src_ip6, in.__in6_u.__u6_addr32, 4);
|
||||
}
|
||||
|
||||
if (filter_cfg->ip.dst_ip6)
|
||||
{
|
||||
struct in6_addr in;
|
||||
|
||||
inet_pton(AF_INET6, filter_cfg->ip.dst_ip6, &in);
|
||||
|
||||
memcpy(filter.ip.dst_ip6, in.__in6_u.__u6_addr32, 4);
|
||||
}
|
||||
|
||||
if (filter_cfg->ip.min_ttl > -1)
|
||||
{
|
||||
filter.ip.do_min_ttl = 1;
|
||||
|
||||
filter.ip.min_ttl = filter_cfg->ip.min_ttl;
|
||||
}
|
||||
|
||||
if (filter_cfg->ip.max_ttl > -1)
|
||||
{
|
||||
filter.ip.do_max_ttl = 1;
|
||||
|
||||
filter.ip.max_ttl = filter_cfg->ip.max_ttl;
|
||||
}
|
||||
|
||||
if (filter_cfg->ip.min_len > -1)
|
||||
{
|
||||
filter.ip.do_min_len = 1;
|
||||
|
||||
filter.ip.min_len = filter_cfg->ip.min_len;
|
||||
}
|
||||
|
||||
if (filter_cfg->ip.max_len > -1)
|
||||
{
|
||||
filter.ip.do_max_len = 1;
|
||||
|
||||
filter.ip.max_len = filter_cfg->ip.max_len;
|
||||
}
|
||||
|
||||
if (filter_cfg->ip.tos > -1)
|
||||
{
|
||||
filter.ip.do_tos = 1;
|
||||
|
||||
filter.ip.tos = filter_cfg->ip.tos;
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.enabled > -1)
|
||||
{
|
||||
filter.tcp.enabled = filter_cfg->tcp.enabled;
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.sport > -1)
|
||||
{
|
||||
filter.tcp.do_sport = 1;
|
||||
|
||||
filter.tcp.sport = htons((u16)filter_cfg->tcp.sport);
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.dport > -1)
|
||||
{
|
||||
filter.tcp.do_dport = 1;
|
||||
|
||||
filter.tcp.dport = htons((u16)filter_cfg->tcp.dport);
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.urg > -1)
|
||||
{
|
||||
filter.tcp.do_urg = 1;
|
||||
|
||||
filter.tcp.urg = filter_cfg->tcp.urg;
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.ack > -1)
|
||||
{
|
||||
filter.tcp.do_ack = 1;
|
||||
|
||||
filter.tcp.ack = filter_cfg->tcp.ack;
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.rst > -1)
|
||||
{
|
||||
filter.tcp.do_rst = 1;
|
||||
|
||||
filter.tcp.rst = filter_cfg->tcp.rst;
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.psh > -1)
|
||||
{
|
||||
filter.tcp.do_psh = 1;
|
||||
|
||||
filter.tcp.psh = filter_cfg->tcp.psh;
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.syn > -1)
|
||||
{
|
||||
filter.tcp.do_syn = 1;
|
||||
|
||||
filter.tcp.syn = filter_cfg->tcp.syn;
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.fin > -1)
|
||||
{
|
||||
filter.tcp.do_fin = 1;
|
||||
|
||||
filter.tcp.fin = filter_cfg->tcp.fin;
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.ece > -1)
|
||||
{
|
||||
filter.tcp.do_ece = 1;
|
||||
|
||||
filter.tcp.ece = filter_cfg->tcp.ece;
|
||||
}
|
||||
|
||||
if (filter_cfg->tcp.cwr > -1)
|
||||
{
|
||||
filter.tcp.do_cwr = 1;
|
||||
|
||||
filter.tcp.cwr = filter_cfg->tcp.cwr;
|
||||
}
|
||||
|
||||
if (filter_cfg->udp.enabled > -1)
|
||||
{
|
||||
filter.udp.enabled = filter_cfg->udp.enabled;
|
||||
}
|
||||
|
||||
if (filter_cfg->udp.sport > -1)
|
||||
{
|
||||
filter.udp.do_sport = 1;
|
||||
|
||||
filter.udp.sport = htons((u16)filter_cfg->udp.sport);
|
||||
}
|
||||
|
||||
if (filter_cfg->udp.dport > -1)
|
||||
{
|
||||
filter.udp.do_dport = 1;
|
||||
|
||||
filter.udp.dport = htons((u16)filter_cfg->udp.dport);
|
||||
}
|
||||
|
||||
if (filter_cfg->icmp.enabled > -1)
|
||||
{
|
||||
filter.icmp.enabled = filter_cfg->icmp.enabled;
|
||||
}
|
||||
|
||||
if (filter_cfg->icmp.code > -1)
|
||||
{
|
||||
filter.icmp.do_code = 1;
|
||||
|
||||
filter.icmp.code = filter_cfg->icmp.code;
|
||||
}
|
||||
|
||||
if (filter_cfg->icmp.type > -1)
|
||||
{
|
||||
filter.icmp.do_type = 1;
|
||||
|
||||
filter.icmp.type = filter_cfg->icmp.type;
|
||||
}
|
||||
|
||||
filter_t filter_cpus[MAX_CPUS];
|
||||
memset(filter_cpus, 0, sizeof(filter_cpus));
|
||||
|
||||
for (int j = 0; j < MAX_CPUS; j++)
|
||||
{
|
||||
filter_cpus[j] = *filter;
|
||||
filter_cpus[j] = filter;
|
||||
}
|
||||
|
||||
return bpf_map_update_elem(map_filters, &idx, &filter_cpus, BPF_ANY);
|
||||
@@ -261,7 +479,7 @@ void update_filters(int map_filters, config__t *cfg)
|
||||
// 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.
|
||||
delete_filter(map_filters, i);
|
||||
|
||||
filter_t* filter = &cfg->filters[i];
|
||||
filter_rule_cfg_t* filter = &cfg->filters[i];
|
||||
|
||||
// Only insert set and enabled filters.
|
||||
if (!filter->set || !filter->enabled)
|
||||
|
||||
@@ -21,7 +21,7 @@ int attach_xdp(struct xdp_program *prog, char** mode, int ifidx, int detach, int
|
||||
int delete_filter(int map_filters, u32 idx);
|
||||
void delete_filters(int map_filters);
|
||||
|
||||
int update_filter(int map_filters, filter_t* filter, int idx);
|
||||
int update_filter(int map_filters, filter_rule_cfg_t* filter, int idx);
|
||||
void update_filters(int map_filters, config__t *cfg);
|
||||
|
||||
int pin_bpf_map(struct bpf_object* obj, const char* pin_dir, const char* map_name);
|
||||
|
||||
Reference in New Issue
Block a user