Separate filter rule structures from config and BPF map.

This commit is contained in:
Christian Deacon
2025-03-06 15:49:14 -05:00
parent 916189a498
commit ad045b5b84
9 changed files with 780 additions and 489 deletions

View File

@@ -2,7 +2,34 @@
#include <common/int_types.h> #include <common/int_types.h>
struct tcp_opts struct filter_ip
{
u32 src_ip;
u8 src_cidr;
u32 dst_ip;
u8 dst_cidr;
u32 src_ip6[4];
u32 dst_ip6[4];
unsigned int do_min_ttl : 1;
u8 min_ttl;
unsigned int do_max_ttl : 1;
u8 max_ttl;
unsigned int do_min_len : 1;
u16 min_len;
unsigned int do_max_len : 1;
u16 max_len;
unsigned int do_tos : 1;
u8 tos;
} typedef filter_ip_t;
struct filter_tcp
{ {
unsigned int enabled : 1; unsigned int enabled : 1;
@@ -36,9 +63,9 @@ struct tcp_opts
unsigned int do_cwr : 1; unsigned int do_cwr : 1;
unsigned int cwr : 1; unsigned int cwr : 1;
} typedef tcp_opts_t; } typedef filter_tcp_t;
struct udp_opts struct filter_udp
{ {
unsigned int enabled : 1; unsigned int enabled : 1;
@@ -47,9 +74,9 @@ struct udp_opts
unsigned int do_dport : 1; unsigned int do_dport : 1;
u16 dport; u16 dport;
} typedef udp_opts_t; } typedef filter_udp_t;
struct icmp_opts struct filter_icmp
{ {
unsigned int enabled : 1; unsigned int enabled : 1;
@@ -58,7 +85,7 @@ struct icmp_opts
unsigned int do_type : 1; unsigned int do_type : 1;
u8 type; u8 type;
} typedef icmp_opts_t; } typedef filter_icmp_t;
struct filter struct filter
{ {
@@ -67,30 +94,7 @@ struct filter
unsigned int enabled : 1; unsigned int enabled : 1;
u8 action; u8 action;
u16 block_time;
u32 src_ip;
u8 src_cidr;
u32 dst_ip;
u8 dst_cidr;
u32 src_ip6[4];
u32 dst_ip6[4];
unsigned int do_min_ttl : 1;
u8 min_ttl;
unsigned int do_max_ttl : 1;
u8 max_ttl;
unsigned int do_min_len : 1;
u16 min_len;
unsigned int do_max_len : 1;
u16 max_len;
unsigned int do_tos : 1;
u8 tos;
unsigned int do_pps : 1; unsigned int do_pps : 1;
u64 pps; u64 pps;
@@ -98,11 +102,11 @@ struct filter
unsigned int do_bps : 1; unsigned int do_bps : 1;
u64 bps; u64 bps;
u64 block_time; filter_ip_t ip;
tcp_opts_t tcpopts; filter_tcp_t tcp;
udp_opts_t udpopts; filter_udp_t udp;
icmp_opts_t icmpopts; filter_icmp_t icmp;
} __attribute__((__aligned__(8))) typedef filter_t; } __attribute__((__aligned__(8))) typedef filter_t;
struct stats struct stats

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,75 @@
#define CONFIG_DEFAULT_PATH "/etc/xdpfw/xdpfw.conf" #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 struct config
{ {
int verbose; int verbose;
@@ -24,7 +93,7 @@ struct config
unsigned int stats_per_second : 1; unsigned int stats_per_second : 1;
int stdout_update_time; int stdout_update_time;
filter_t filters[MAX_FILTERS]; filter_rule_cfg_t filters[MAX_FILTERS];
const char* drop_ranges[MAX_IP_RANGES]; const char* drop_ranges[MAX_IP_RANGES];
} typedef config__t; // config_t is taken by libconfig -.- } typedef config__t; // config_t is taken by libconfig -.-
@@ -41,10 +110,10 @@ struct config_overrides
} typedef config_overrides_t; } typedef config_overrides_t;
void set_cfg_defaults(config__t *cfg); 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 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 load_cfg(config__t *cfg, const char* cfg_file, config_overrides_t* overrides);
int save_cfg(config__t* cfg, const char* file_path); int save_cfg(config__t* cfg, const char* file_path);

View File

@@ -134,7 +134,7 @@ int hdl_filters_rb_event(void* ctx, void* data, size_t sz)
config__t* cfg = (config__t*)ctx; config__t* cfg = (config__t*)ctx;
filter_log_event_t* e = (filter_log_event_t*)data; 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) if (filter == NULL)
{ {

View File

@@ -45,7 +45,7 @@ int get_map_fd(struct xdp_program *prog, const char *map_name)
* *
* @return void * @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; return 0;
} }
@@ -61,7 +61,7 @@ void set_libbpf_log_mode(int silent)
{ {
if (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. * Updates a filter rule.
* *
* @param map_filters The filters BPF map FD. * @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. * @param idx The filter index to insert or update.
* *
* @return 0 on success or error value of bpf_map_update_elem(). * @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]; filter_t filter_cpus[MAX_CPUS];
memset(filter_cpus, 0, sizeof(filter_cpus)); memset(filter_cpus, 0, sizeof(filter_cpus));
for (int j = 0; j < MAX_CPUS; j++) 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); 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. // 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); 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. // Only insert set and enabled filters.
if (!filter->set || !filter->enabled) if (!filter->set || !filter->enabled)

View File

@@ -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); int delete_filter(int map_filters, u32 idx);
void delete_filters(int map_filters); 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); 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); int pin_bpf_map(struct bpf_object* obj, const char* pin_dir, const char* map_name);

View File

@@ -158,7 +158,7 @@ int main(int argc, char *argv[])
printf("Using 'map_filters' FD => %d...\n", map_filters); printf("Using 'map_filters' FD => %d...\n", map_filters);
// Create new base filter and set its defaults. // Create new base filter and set its defaults.
filter_t new_filter = {0}; filter_rule_cfg_t new_filter = {0};
set_filter_defaults(&new_filter); set_filter_defaults(&new_filter);
new_filter.set = 1; new_filter.set = 1;
@@ -205,189 +205,144 @@ int main(int argc, char *argv[])
if (cli.src_ip) if (cli.src_ip)
{ {
ip_range_t range = parse_ip_range(cli.src_ip); new_filter.ip.src_ip = cli.src_ip;
new_filter.src_ip = range.ip;
new_filter.src_cidr = range.cidr;
} }
if (cli.dst_ip) if (cli.dst_ip)
{ {
ip_range_t range = parse_ip_range(cli.dst_ip); new_filter.ip.dst_ip = cli.dst_ip;
new_filter.dst_ip = range.ip;
new_filter.dst_cidr = range.cidr;
} }
if (cli.src_ip6) if (cli.src_ip6)
{ {
struct in6_addr addr; new_filter.ip.src_ip6 = cli.src_ip6;
if ((ret = inet_pton(AF_INET6, cli.src_ip6, &addr)) != 1)
{
fprintf(stderr, "Failed to convert source IPv6 address to decimal (%d).\n", ret);
return EXIT_FAILURE;
}
memcpy(new_filter.src_ip6, addr.s6_addr, sizeof(new_filter.src_ip6));
} }
if (cli.dst_ip6) if (cli.dst_ip6)
{ {
struct in6_addr addr; new_filter.ip.dst_ip6 = cli.dst_ip6;
if ((ret = inet_pton(AF_INET6, cli.dst_ip6, &addr)) != 1)
{
fprintf(stderr, "Failed to convert destination IPv6 address to decimal (%d).\n", ret);
return EXIT_FAILURE;
}
memcpy(new_filter.dst_ip6, addr.s6_addr, sizeof(new_filter.dst_ip6));
} }
// To Do: See if I can create a macro for below. // To Do: See if I can create a macro for below.
// As long as the naming convention lines up, it should be easily possible. // As long as the naming convention lines up, it should be easily possible.
if (cli.pps > -1) if (cli.pps > -1)
{ {
new_filter.do_pps = 1;
new_filter.pps = cli.pps; new_filter.pps = cli.pps;
} }
if (cli.bps > -1) if (cli.bps > -1)
{ {
new_filter.do_bps = 1;
new_filter.bps = cli.bps; new_filter.bps = cli.bps;
} }
if (cli.min_ttl > -1) if (cli.min_ttl > -1)
{ {
new_filter.do_min_ttl = 1; new_filter.ip.min_ttl = cli.min_ttl;
new_filter.min_ttl = cli.min_ttl;
} }
if (cli.max_ttl > -1) if (cli.max_ttl > -1)
{ {
new_filter.do_max_ttl = 1; new_filter.ip.max_ttl = cli.max_ttl;
new_filter.max_ttl = cli.max_ttl;
} }
if (cli.min_len > -1) if (cli.min_len > -1)
{ {
new_filter.do_min_len = 1; new_filter.ip.min_len = cli.min_len;
new_filter.min_len = cli.min_len;
} }
if (cli.max_len > -1) if (cli.max_len > -1)
{ {
new_filter.do_max_len = 1; new_filter.ip.max_len = cli.max_len;
new_filter.max_len = cli.max_len;
} }
if (cli.tos > -1) if (cli.tos > -1)
{ {
new_filter.do_tos = 1; new_filter.ip.tos = cli.tos;
new_filter.tos = cli.tos;
} }
if (cli.tcp_enabled > -1) if (cli.tcp_enabled > -1)
{ {
new_filter.tcpopts.enabled = cli.tcp_enabled; new_filter.tcp.enabled = cli.tcp_enabled;
} }
if (cli.tcp_sport > -1) if (cli.tcp_sport > -1)
{ {
new_filter.tcpopts.do_sport = 1; new_filter.tcp.sport = cli.tcp_sport;
new_filter.tcpopts.sport = cli.tcp_sport;
} }
if (cli.tcp_dport > -1) if (cli.tcp_dport > -1)
{ {
new_filter.tcpopts.do_dport = 1; new_filter.tcp.dport = cli.tcp_dport;
new_filter.tcpopts.dport = cli.tcp_dport;
} }
if (cli.tcp_urg > -1) if (cli.tcp_urg > -1)
{ {
new_filter.tcpopts.do_urg = 1; new_filter.tcp.urg = cli.tcp_urg;
new_filter.tcpopts.urg = cli.tcp_urg;
} }
if (cli.tcp_ack > -1) if (cli.tcp_ack > -1)
{ {
new_filter.tcpopts.do_ack = 1; new_filter.tcp.ack = cli.tcp_ack;
new_filter.tcpopts.ack = cli.tcp_ack;
} }
if (cli.tcp_rst > -1) if (cli.tcp_rst > -1)
{ {
new_filter.tcpopts.do_rst = 1; new_filter.tcp.rst = cli.tcp_rst;
new_filter.tcpopts.rst = cli.tcp_rst;
} }
if (cli.tcp_psh > -1) if (cli.tcp_psh > -1)
{ {
new_filter.tcpopts.do_psh = 1; new_filter.tcp.psh = cli.tcp_psh;
new_filter.tcpopts.psh = cli.tcp_psh;
} }
if (cli.tcp_syn > -1) if (cli.tcp_syn > -1)
{ {
new_filter.tcpopts.do_syn = 1; new_filter.tcp.syn = cli.tcp_syn;
new_filter.tcpopts.syn = cli.tcp_syn;
} }
if (cli.tcp_fin > -1) if (cli.tcp_fin > -1)
{ {
new_filter.tcpopts.do_fin = 1; new_filter.tcp.fin = cli.tcp_fin;
new_filter.tcpopts.fin = cli.tcp_fin;
} }
if (cli.tcp_ece > -1) if (cli.tcp_ece > -1)
{ {
new_filter.tcpopts.do_ece = 1; new_filter.tcp.ece = cli.tcp_ece;
new_filter.tcpopts.ece = cli.tcp_ece;
} }
if (cli.tcp_cwr > -1) if (cli.tcp_cwr > -1)
{ {
new_filter.tcpopts.do_cwr = 1; new_filter.tcp.cwr = cli.tcp_cwr;
new_filter.tcpopts.cwr = cli.tcp_cwr;
} }
if (cli.udp_enabled > -1) if (cli.udp_enabled > -1)
{ {
new_filter.udpopts.enabled = cli.udp_enabled; new_filter.udp.enabled = cli.udp_enabled;
} }
if (cli.udp_sport > -1) if (cli.udp_sport > -1)
{ {
new_filter.udpopts.do_sport = 1; new_filter.udp.sport = cli.udp_sport;
new_filter.udpopts.sport = cli.udp_sport;
} }
if (cli.udp_dport > -1) if (cli.udp_dport > -1)
{ {
new_filter.udpopts.do_dport = 1; new_filter.udp.dport = cli.udp_dport;
new_filter.udpopts.dport = cli.udp_dport;
} }
if (cli.icmp_enabled > -1) if (cli.icmp_enabled > -1)
{ {
new_filter.icmpopts.enabled = cli.icmp_enabled; new_filter.icmp.enabled = cli.icmp_enabled;
} }
if (cli.icmp_code > -1) if (cli.icmp_code > -1)
{ {
new_filter.icmpopts.do_code = 1; new_filter.icmp.code = cli.icmp_code;
new_filter.icmpopts.code = cli.icmp_code;
} }
if (cli.icmp_type > -1) if (cli.icmp_type > -1)
{ {
new_filter.icmpopts.do_type = 1; new_filter.icmp.type = cli.icmp_type;
new_filter.icmpopts.type = cli.icmp_type;
} }
// Set filter at index. // Set filter at index.

View File

@@ -99,7 +99,7 @@ int main(int argc, char *argv[])
// So we need to loop through each and ignore disabled rules. // So we need to loop through each and ignore disabled rules.
for (int i = 0; i < MAX_FILTERS; i++) for (int i = 0; i < MAX_FILTERS; i++)
{ {
filter_t* filter = &cfg.filters[i]; filter_rule_cfg_t* filter = &cfg.filters[i];
if (!filter->set || !filter->enabled) if (!filter->set || !filter->enabled)
{ {

View File

@@ -299,44 +299,44 @@ int xdp_prog_main(struct xdp_md *ctx)
if (iph6) if (iph6)
{ {
// Source address. // Source address.
if (filter->src_ip6[0] != 0 && (iph6->saddr.in6_u.u6_addr32[0] != filter->src_ip6[0] || iph6->saddr.in6_u.u6_addr32[1] != filter->src_ip6[1] || iph6->saddr.in6_u.u6_addr32[2] != filter->src_ip6[2] || iph6->saddr.in6_u.u6_addr32[3] != filter->src_ip6[3])) if (filter->ip.src_ip6[0] != 0 && (iph6->saddr.in6_u.u6_addr32[0] != filter->ip.src_ip6[0] || iph6->saddr.in6_u.u6_addr32[1] != filter->ip.src_ip6[1] || iph6->saddr.in6_u.u6_addr32[2] != filter->ip.src_ip6[2] || iph6->saddr.in6_u.u6_addr32[3] != filter->ip.src_ip6[3]))
{ {
continue; continue;
} }
// Destination address. // Destination address.
if (filter->dst_ip6[0] != 0 && (iph6->daddr.in6_u.u6_addr32[0] != filter->dst_ip6[0] || iph6->daddr.in6_u.u6_addr32[1] != filter->dst_ip6[1] || iph6->daddr.in6_u.u6_addr32[2] != filter->dst_ip6[2] || iph6->daddr.in6_u.u6_addr32[3] != filter->dst_ip6[3])) if (filter->ip.dst_ip6[0] != 0 && (iph6->daddr.in6_u.u6_addr32[0] != filter->ip.dst_ip6[0] || iph6->daddr.in6_u.u6_addr32[1] != filter->ip.dst_ip6[1] || iph6->daddr.in6_u.u6_addr32[2] != filter->ip.dst_ip6[2] || iph6->daddr.in6_u.u6_addr32[3] != filter->ip.dst_ip6[3]))
{ {
continue; continue;
} }
#ifdef ALLOW_SINGLE_IP_V4_V6 #ifdef ALLOW_SINGLE_IP_V4_V6
if (filter->src_ip != 0 || filter->dst_ip != 0) if (filter->ip.src_ip != 0 || filter->ip.dst_ip != 0)
{ {
continue; continue;
} }
#endif #endif
// Max TTL length. // Max TTL length.
if (filter->do_max_ttl && filter->max_ttl > iph6->hop_limit) if (filter->ip.do_max_ttl && filter->ip.max_ttl > iph6->hop_limit)
{ {
continue; continue;
} }
// Min TTL length. // Min TTL length.
if (filter->do_min_ttl && filter->min_ttl < iph6->hop_limit) if (filter->ip.do_min_ttl && filter->ip.min_ttl < iph6->hop_limit)
{ {
continue; continue;
} }
// Max packet length. // Max packet length.
if (filter->do_max_len && filter->max_len > (ntohs(iph6->payload_len) + sizeof(struct ethhdr))) if (filter->ip.do_max_len && filter->ip.max_len > (ntohs(iph6->payload_len) + sizeof(struct ethhdr)))
{ {
continue; continue;
} }
// Min packet length. // Min packet length.
if (filter->do_min_len && filter->min_len < (ntohs(iph6->payload_len) + sizeof(struct ethhdr))) if (filter->ip.do_min_len && filter->ip.min_len < (ntohs(iph6->payload_len) + sizeof(struct ethhdr)))
{ {
continue; continue;
} }
@@ -344,68 +344,66 @@ int xdp_prog_main(struct xdp_md *ctx)
else if (iph) else if (iph)
{ {
// Source address. // Source address.
if (filter->src_ip) if (filter->ip.src_ip)
{ {
if (filter->src_cidr == 32 && iph->saddr != filter->src_ip) if (filter->ip.src_cidr == 32 && iph->saddr != filter->ip.src_ip)
{ {
continue; continue;
} }
if (!is_ip_in_range(iph->saddr, filter->src_ip, filter->src_cidr)) if (!is_ip_in_range(iph->saddr, filter->ip.src_ip, filter->ip.src_cidr))
{ {
continue; continue;
} }
} }
// Destination address. // Destination address.
if (filter->dst_ip) if (filter->ip.dst_ip)
{ {
if (filter->dst_cidr == 32 && iph->daddr != filter->dst_ip) if (filter->ip.dst_cidr == 32 && iph->daddr != filter->ip.dst_ip)
{ {
continue; continue;
} }
if (!is_ip_in_range(iph->daddr, filter->dst_ip, filter->dst_cidr)) if (!is_ip_in_range(iph->daddr, filter->ip.dst_ip, filter->ip.dst_cidr))
{ {
continue; continue;
} }
} }
#ifdef ALLOW_SINGLE_IP_V4_V6 #ifdef ALLOW_SINGLE_IP_V4_V6
if ((filter->src_ip6[0] != 0 || filter->src_ip6[1] != 0 || filter->src_ip6[2] != 0 || filter->src_ip6[3] != 0) || (filter->dst_ip6[0] != 0 || filter->dst_ip6[1] != 0 || filter->dst_ip6[2] != 0 || filter->dst_ip6[3] != 0)) if ((filter->ip.src_ip6[0] != 0 || filter->ip.src_ip6[1] != 0 || filter->ip.src_ip6[2] != 0 || filter->ip.src_ip6[3] != 0) || (filter->ip.dst_ip6[0] != 0 || filter->ip.dst_ip6[1] != 0 || filter->ip.dst_ip6[2] != 0 || filter->ip.dst_ip6[3] != 0))
{ {
continue; continue;
} }
#endif #endif
// TOS. // TOS.
if (filter->do_tos && filter->tos != iph->tos) if (filter->ip.do_tos && filter->ip.tos != iph->tos)
{ {
continue; continue;
} }
// Max TTL length. // Max TTL length.
if (filter->do_max_ttl && filter->max_ttl < iph->ttl) if (filter->ip.do_max_ttl && filter->ip.max_ttl < iph->ttl)
{ {
continue; continue;
} }
// Min TTL length. // Min TTL length.
if (filter->do_min_ttl && filter->min_ttl > iph->ttl) if (filter->ip.do_min_ttl && filter->ip.min_ttl > iph->ttl)
{ {
continue; continue;
} }
// Max packet length. // Max packet length.
if (filter->do_max_len && filter->max_len < (ntohs(iph->tot_len) + sizeof(struct ethhdr))) if (filter->ip.do_max_len && filter->ip.max_len < (ntohs(iph->tot_len) + sizeof(struct ethhdr)))
{ {
continue; continue;
} }
// Min packet length. // Min packet length.
if (filter->do_min_len && filter->min_len > (ntohs(iph->tot_len) + sizeof(struct ethhdr))) if (filter->ip.do_min_len && filter->ip.min_len > (ntohs(iph->tot_len) + sizeof(struct ethhdr)))
{ {
continue; continue;
} }
@@ -424,7 +422,7 @@ int xdp_prog_main(struct xdp_md *ctx)
} }
// Do TCP options. // Do TCP options.
if (filter->tcpopts.enabled) if (filter->tcp.enabled)
{ {
if (!tcph) if (!tcph)
{ {
@@ -432,66 +430,66 @@ int xdp_prog_main(struct xdp_md *ctx)
} }
// Source port. // Source port.
if (filter->tcpopts.do_sport && htons(filter->tcpopts.sport) != tcph->source) if (filter->tcp.do_sport && filter->tcp.sport != tcph->source)
{ {
continue; continue;
} }
// Destination port. // Destination port.
if (filter->tcpopts.do_dport && htons(filter->tcpopts.dport) != tcph->dest) if (filter->tcp.do_dport && filter->tcp.dport != tcph->dest)
{ {
continue; continue;
} }
// URG flag. // URG flag.
if (filter->tcpopts.do_urg && filter->tcpopts.urg != tcph->urg) if (filter->tcp.do_urg && filter->tcp.urg != tcph->urg)
{ {
continue; continue;
} }
// ACK flag. // ACK flag.
if (filter->tcpopts.do_ack && filter->tcpopts.ack != tcph->ack) if (filter->tcp.do_ack && filter->tcp.ack != tcph->ack)
{ {
continue; continue;
} }
// RST flag. // RST flag.
if (filter->tcpopts.do_rst && filter->tcpopts.rst != tcph->rst) if (filter->tcp.do_rst && filter->tcp.rst != tcph->rst)
{ {
continue; continue;
} }
// PSH flag. // PSH flag.
if (filter->tcpopts.do_psh && filter->tcpopts.psh != tcph->psh) if (filter->tcp.do_psh && filter->tcp.psh != tcph->psh)
{ {
continue; continue;
} }
// SYN flag. // SYN flag.
if (filter->tcpopts.do_syn && filter->tcpopts.syn != tcph->syn) if (filter->tcp.do_syn && filter->tcp.syn != tcph->syn)
{ {
continue; continue;
} }
// FIN flag. // FIN flag.
if (filter->tcpopts.do_fin && filter->tcpopts.fin != tcph->fin) if (filter->tcp.do_fin && filter->tcp.fin != tcph->fin)
{ {
continue; continue;
} }
// ECE flag. // ECE flag.
if (filter->tcpopts.do_ece && filter->tcpopts.ece != tcph->ece) if (filter->tcp.do_ece && filter->tcp.ece != tcph->ece)
{ {
continue; continue;
} }
// CWR flag. // CWR flag.
if (filter->tcpopts.do_cwr && filter->tcpopts.cwr != tcph->cwr) if (filter->tcp.do_cwr && filter->tcp.cwr != tcph->cwr)
{ {
continue; continue;
} }
} }
else if (filter->udpopts.enabled) else if (filter->udp.enabled)
{ {
if (!udph) if (!udph)
{ {
@@ -499,30 +497,30 @@ int xdp_prog_main(struct xdp_md *ctx)
} }
// Source port. // Source port.
if (filter->udpopts.do_sport && htons(filter->udpopts.sport) != udph->source) if (filter->udp.do_sport && filter->udp.sport != udph->source)
{ {
continue; continue;
} }
// Destination port. // Destination port.
if (filter->udpopts.do_dport && htons(filter->udpopts.dport) != udph->dest) if (filter->udp.do_dport && filter->udp.dport != udph->dest)
{ {
continue; continue;
} }
} }
else if (filter->icmpopts.enabled) else if (filter->icmp.enabled)
{ {
if (icmph) if (icmph)
{ {
// Code. // Code.
if (filter->icmpopts.do_code && filter->icmpopts.code != icmph->code) if (filter->icmp.do_code && filter->icmp.code != icmph->code)
{ {
continue; continue;
} }
// Type. // Type.
if (filter->icmpopts.do_type && filter->icmpopts.type != icmph->type) if (filter->icmp.do_type && filter->icmp.type != icmph->type)
{ {
continue; continue;
} }
@@ -530,13 +528,13 @@ int xdp_prog_main(struct xdp_md *ctx)
else if (icmp6h) else if (icmp6h)
{ {
// Code. // Code.
if (filter->icmpopts.do_code && filter->icmpopts.code != icmp6h->icmp6_code) if (filter->icmp.do_code && filter->icmp.code != icmp6h->icmp6_code)
{ {
continue; continue;
} }
// Type. // Type.
if (filter->icmpopts.do_type && filter->icmpopts.type != icmp6h->icmp6_type) if (filter->icmp.do_type && filter->icmp.type != icmp6h->icmp6_type)
{ {
continue; continue;
} }