diff --git a/README.md b/README.md index e28159b..36fd85d 100644 --- a/README.md +++ b/README.md @@ -58,8 +58,8 @@ The following table quickly explains the data types used within the configuratio | enabled | bool | `false` | Whether the rule is enabled or not. | | action | uint | `0` | The value of `0` drops or blocks the packet while `1` allows/passes the packet through. | | block_time | uint | `1` | The amount of seconds to block the source IP for if matched. | -| src_ip | string | `NULL` | The source IPv4 address to match (e.g. `10.50.0.3`). | -| dst_ip | string | `NULL` | The destination IPv4 address to match (e.g. `10.50.0.4`) | +| src_ip | string | `NULL` | The source IPv4 address to match (e.g. `10.50.0.3`). CIDRs are also supported (e.g. `10.50.0.0/24`)! | +| dst_ip | string | `NULL` | The destination IPv4 address to match (e.g. `10.50.0.4`). CIDRs are also supported (e.g. `10.50.0.0/24`)! | | src_ip6 | string | `NULL` | The source IPv6 address to match (e.g. `fe80::18c4:dfff:fe70:d8a6`). | | dst_ip6 | string | `NULL` | The destination IPv6 address to match (e.g. `fe80::ac21:14ff:fe4b:3a6d`). | | min_ttl | byte | `NULL` | The minimum TTL (time-to-live) to match. | diff --git a/src/cmdline.c b/src/cmdline.c index 0781307..2ddfd0d 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -22,7 +22,7 @@ const struct option opts[] = * * @return Void */ -void parsecommandline(struct cmdline *cmd, int argc, char *argv[]) +void ParseCommandLine(struct cmdline *cmd, int argc, char *argv[]) { int c; diff --git a/src/cmdline.h b/src/cmdline.h index 4425c8d..ff6bf95 100644 --- a/src/cmdline.h +++ b/src/cmdline.h @@ -10,4 +10,4 @@ struct cmdline unsigned int help : 1; }; -void parsecommandline(struct cmdline *cmd, int argc, char *argv[]); \ No newline at end of file +void ParseCommandLine(struct cmdline *cmd, int argc, char *argv[]); \ No newline at end of file diff --git a/src/config.c b/src/config.c index a21562b..23a5035 100644 --- a/src/config.c +++ b/src/config.c @@ -8,6 +8,7 @@ #include "xdpfw.h" #include "config.h" +#include "utils.h" FILE *file; @@ -18,7 +19,7 @@ FILE *file; * * @return Void */ -void setcfgdefaults(struct config *cfg) +void SetCfgDefaults(struct config *cfg) { cfg->updatetime = 0; cfg->interface = NULL; @@ -30,13 +31,13 @@ void setcfgdefaults(struct config *cfg) cfg->filters[i].id = 0; cfg->filters[i].enabled = 0; cfg->filters[i].action = 0; - cfg->filters[i].srcip = 0; - cfg->filters[i].dstip = 0; + cfg->filters[i].src_ip = 0; + cfg->filters[i].dst_ip = 0; for (__u8 j = 0; j < 4; j++) { - cfg->filters[i].srcip6[j] = 0; - cfg->filters[i].dstip6[j] = 0; + cfg->filters[i].src_ip6[j] = 0; + cfg->filters[i].dst_ip6[j] = 0; } cfg->filters[i].do_min_len = 0; @@ -91,7 +92,7 @@ void setcfgdefaults(struct config *cfg) * * @return 0 on success or 1 on error. */ -int opencfg(const char *filename) +int OpenCfg(const char *filename) { // Close any existing files. if (file != NULL) @@ -118,7 +119,7 @@ int opencfg(const char *filename) * * @return 0 on success or 1/-1 on error. */ -int readcfg(struct config *cfg) +int ReadCfg(struct config *cfg) { // Not sure why this would be set to NULL after checking for it in OpenConfig(), but just for safety. if (file == NULL) @@ -232,7 +233,10 @@ int readcfg(struct config *cfg) if (config_setting_lookup_string(filter, "src_ip", &sip)) { - cfg->filters[i].srcip = inet_addr(sip); + struct ip ip = ParseIp(sip); + + cfg->filters[i].src_ip = ip.ip; + cfg->filters[i].src_cidr = ip.cidr; } // Destination IP (not required). @@ -240,7 +244,10 @@ int readcfg(struct config *cfg) if (config_setting_lookup_string(filter, "dst_ip", &dip)) { - cfg->filters[i].dstip = inet_addr(dip); + struct ip ip = ParseIp(dip); + + cfg->filters[i].dst_ip = ip.ip; + cfg->filters[i].dst_cidr = ip.cidr; } // Source IP (IPv6) (not required). @@ -254,7 +261,7 @@ int readcfg(struct config *cfg) for (__u8 j = 0; j < 4; j++) { - cfg->filters[i].srcip6[j] = in.__in6_u.__u6_addr32[j]; + cfg->filters[i].src_ip6[j] = in.__in6_u.__u6_addr32[j]; } } @@ -269,7 +276,7 @@ int readcfg(struct config *cfg) for (__u8 j = 0; j < 4; j++) { - cfg->filters[i].dstip6[j] = in.__in6_u.__u6_addr32[j]; + cfg->filters[i].dst_ip6[j] = in.__in6_u.__u6_addr32[j]; } } diff --git a/src/config.h b/src/config.h index 45b775d..fbac5a0 100644 --- a/src/config.h +++ b/src/config.h @@ -13,6 +13,6 @@ struct config struct filter filters[MAX_FILTERS]; }; -void setcfgdefaults(struct config *cfg); -int opencfg(const char *filename); -int readcfg(struct config *cfg); \ No newline at end of file +void SetCfgDefaults(struct config *cfg); +int OpenCfg(const char *filename); +int ReadCfg(struct config *cfg); \ No newline at end of file diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..65a06af --- /dev/null +++ b/src/utils.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include +#include +#include + +struct ip +{ + __u32 ip; + __u32 cidr; +}; + +/** + * Parses an IP string with CIDR support. Stores IP in network byte order in ip.ip and CIDR in ip.cidr. + * + * @param ip The IP string. + * + * @return Returns an IP structure with IP and CIDR. +*/ +struct ip ParseIp(const char *ip) +{ + struct ip ret = {0}; + ret.cidr = 32; + + char *token = strtok((char *) ip, "/"); + + if (token) + { + ret.ip = inet_addr(token); + + token = strtok(NULL, "/"); + + if (token) + { + ret.cidr = (unsigned int) strtoul(token, NULL, 10); + } + } + + return ret; +} \ No newline at end of file diff --git a/src/xdp_utils.h b/src/xdp_utils.h new file mode 100644 index 0000000..7b840bc --- /dev/null +++ b/src/xdp_utils.h @@ -0,0 +1,17 @@ +#pragma once + +#include "xdpfw.h" + +/** + * Checks if an IP is within a specific CIDR range. + * + * @param src_ip The source/main IP to check against. + * @param net_ip The network IP. + * @param cidr The CIDR range. + * + * @return 1 on yes, 0 on no. +*/ +static __always_inline __u8 IsIpInRange(__u32 src_ip, __u32 net_ip, __u8 cidr) +{ + return !((src_ip ^ net_ip) & htonl(0xFFFFFFFFu << (32 - cidr))); +} \ No newline at end of file diff --git a/src/xdpfw.c b/src/xdpfw.c index 52df448..c0a3849 100644 --- a/src/xdpfw.c +++ b/src/xdpfw.c @@ -23,13 +23,14 @@ #include "xdpfw.h" #include "config.h" #include "cmdline.h" +#include "xdp_utils.h" // Other variables. static __u8 cont = 1; static int filtersmap = -1; static int statsmap = -1; -void signalHndl(int tmp) +void SignalHndl(int tmp) { cont = 0; } @@ -41,7 +42,7 @@ void signalHndl(int tmp) * * @return Void */ -void updatefilters(struct config *cfg) +void UpdateFilters(struct config *cfg) { // 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 (__u8 i = 0; i < MAX_FILTERS; i++) @@ -84,17 +85,17 @@ void updatefilters(struct config *cfg) * * @return 0 on success or -1 on error. */ -int updateconfig(struct config *cfg, char *cfgfile) +int UpdateConfig(struct config *cfg, char *cfgfile) { // Open config file. - if (opencfg(cfgfile) != 0) + if (OpenCfg(cfgfile) != 0) { fprintf(stderr, "Error opening filters file: %s\n", cfgfile); return -1; } - setcfgdefaults(cfg); + SetCfgDefaults(cfg); for (__u16 i = 0; i < MAX_FILTERS; i++) { @@ -102,7 +103,7 @@ int updateconfig(struct config *cfg, char *cfgfile) } // Read config and check for errors. - if (readcfg(cfg) != 0) + if (ReadCfg(cfg) != 0) { fprintf(stderr, "Error reading filters file.\n"); @@ -120,7 +121,7 @@ int updateconfig(struct config *cfg, char *cfgfile) * * @return The map's FD. */ -int findmapfd(struct xdp_program *prog, const char *mapname) +int FindMapFd(struct xdp_program *prog, const char *mapname) { int fd = -1; @@ -155,7 +156,7 @@ int findmapfd(struct xdp_program *prog, const char *mapname) * * @return XDP program structure (pointer) or NULL. */ -struct xdp_program *loadbpfobj(const char *filename) +struct xdp_program *LoadBpfObj(const char *filename) { struct xdp_program *prog = xdp_program__open_file(filename, "xdp_prog", NULL); @@ -178,7 +179,7 @@ struct xdp_program *loadbpfobj(const char *filename) * * @return 0 on success and 1 on error. */ -int attachxdp(struct xdp_program *prog, int ifidx, __u8 detach, struct cmdline *cmd) +int AttachXdp(struct xdp_program *prog, int ifidx, __u8 detach, struct cmdline *cmd) { int err; @@ -267,6 +268,7 @@ int attachxdp(struct xdp_program *prog, int ifidx, __u8 detach, struct cmdline * } struct stat conf_stat; + int main(int argc, char *argv[]) { // Parse the command line. @@ -278,7 +280,7 @@ int main(int argc, char *argv[]) .offload = 0 }; - parsecommandline(&cmd, argc, argv); + ParseCommandLine(&cmd, argc, argv); // Check for help menu. if (cmd.help) @@ -314,10 +316,10 @@ int main(int argc, char *argv[]) // Initialize config. struct config cfg = {0}; - setcfgdefaults(&cfg); + SetCfgDefaults(&cfg); // Update config. - updateconfig(&cfg, cmd.cfgfile); + UpdateConfig(&cfg, cmd.cfgfile); // Check for list option. if (cmd.list) @@ -329,7 +331,9 @@ int main(int argc, char *argv[]) for (uint16_t i = 0; i < MAX_FILTERS; i++) { - if (cfg.filters[i].id < 1) + struct filter *filter = &cfg.filters[i]; + + if (filter->id < 1) { break; } @@ -337,24 +341,26 @@ int main(int argc, char *argv[]) fprintf(stdout, "Filter #%d:\n", (i + 1)); // Main. - fprintf(stdout, "\tID => %d\n", cfg.filters[i].id); - fprintf(stdout, "\tEnabled => %d\n", cfg.filters[i].enabled); - fprintf(stdout, "\tAction => %d (0 = Block, 1 = Allow).\n\n", cfg.filters[i].action); + fprintf(stdout, "\tID => %d\n", filter->id); + fprintf(stdout, "\tEnabled => %d\n", filter->enabled); + fprintf(stdout, "\tAction => %d (0 = Block, 1 = Allow).\n\n", filter->action); // IP Options. fprintf(stdout, "\tIP Options\n"); // IP addresses require additional code for string printing. struct sockaddr_in sin; - sin.sin_addr.s_addr = cfg.filters[i].srcip; + sin.sin_addr.s_addr = filter->src_ip; fprintf(stdout, "\t\tSource IPv4 => %s\n", inet_ntoa(sin.sin_addr)); + fprintf(stdout, "\t\tSource CIDR => %d\n", filter->src_cidr); struct sockaddr_in din; - din.sin_addr.s_addr = cfg.filters[i].dstip; + din.sin_addr.s_addr = filter->dst_ip; fprintf(stdout, "\t\tDestination IPv4 => %s\n", inet_ntoa(din.sin_addr)); + fprintf(stdout, "\t\tDestination CIDR => %d\n", filter->dst_cidr); struct in6_addr sin6; - memcpy(&sin6, &cfg.filters[i].srcip6, sizeof(sin6)); + memcpy(&sin6, &filter->src_ip6, sizeof(sin6)); char srcipv6[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &sin6, srcipv6, sizeof(srcipv6)); @@ -362,7 +368,7 @@ int main(int argc, char *argv[]) fprintf(stdout, "\t\tSource IPv6 => %s\n", srcipv6); struct in6_addr din6; - memcpy(&din6, &cfg.filters[i].dstip6, sizeof(din6)); + memcpy(&din6, &filter->dst_ip6, sizeof(din6)); char dstipv6[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &din6, dstipv6, sizeof(dstipv6)); @@ -370,40 +376,40 @@ int main(int argc, char *argv[]) fprintf(stdout, "\t\tDestination IPv6 => %s\n", dstipv6); // Other IP header information. - fprintf(stdout, "\t\tMax Length => %d\n", cfg.filters[i].max_len); - fprintf(stdout, "\t\tMin Length => %d\n", cfg.filters[i].min_len); - fprintf(stdout, "\t\tMax TTL => %d\n", cfg.filters[i].max_ttl); - fprintf(stdout, "\t\tMin TTL => %d\n", cfg.filters[i].min_ttl); - fprintf(stdout, "\t\tTOS => %d\n", cfg.filters[i].tos); - fprintf(stdout, "\t\tPPS => %llu\n", cfg.filters[i].pps); - fprintf(stdout, "\t\tBPS => %llu\n", cfg.filters[i].bps); - fprintf(stdout, "\t\tBlock Time => %llu\n\n", cfg.filters[i].blocktime); + fprintf(stdout, "\t\tMax Length => %d\n", filter->max_len); + fprintf(stdout, "\t\tMin Length => %d\n", filter->min_len); + fprintf(stdout, "\t\tMax TTL => %d\n", filter->max_ttl); + fprintf(stdout, "\t\tMin TTL => %d\n", filter->min_ttl); + fprintf(stdout, "\t\tTOS => %d\n", filter->tos); + fprintf(stdout, "\t\tPPS => %llu\n", filter->pps); + fprintf(stdout, "\t\tBPS => %llu\n", filter->bps); + fprintf(stdout, "\t\tBlock Time => %llu\n\n", filter->blocktime); // TCP Options. fprintf(stdout, "\tTCP Options\n"); - fprintf(stdout, "\t\tTCP Enabled => %d\n", cfg.filters[i].tcpopts.enabled); - fprintf(stdout, "\t\tTCP Source Port => %d\n", cfg.filters[i].tcpopts.sport); - fprintf(stdout, "\t\tTCP Destination Port => %d\n", cfg.filters[i].tcpopts.dport); - fprintf(stdout, "\t\tTCP URG Flag => %d\n", cfg.filters[i].tcpopts.urg); - fprintf(stdout, "\t\tTCP ACK Flag => %d\n", cfg.filters[i].tcpopts.ack); - fprintf(stdout, "\t\tTCP RST Flag => %d\n", cfg.filters[i].tcpopts.rst); - fprintf(stdout, "\t\tTCP PSH Flag => %d\n", cfg.filters[i].tcpopts.psh); - fprintf(stdout, "\t\tTCP SYN Flag => %d\n", cfg.filters[i].tcpopts.syn); - fprintf(stdout, "\t\tTCP FIN Flag => %d\n", cfg.filters[i].tcpopts.fin); - fprintf(stdout, "\t\tTCP ECE Flag => %d\n", cfg.filters[i].tcpopts.ece); - fprintf(stdout, "\t\tTCP CWR Flag => %d\n\n", cfg.filters[i].tcpopts.cwr); + fprintf(stdout, "\t\tTCP Enabled => %d\n", filter->tcpopts.enabled); + fprintf(stdout, "\t\tTCP Source Port => %d\n", filter->tcpopts.sport); + fprintf(stdout, "\t\tTCP Destination Port => %d\n", filter->tcpopts.dport); + fprintf(stdout, "\t\tTCP URG Flag => %d\n", filter->tcpopts.urg); + fprintf(stdout, "\t\tTCP ACK Flag => %d\n", filter->tcpopts.ack); + fprintf(stdout, "\t\tTCP RST Flag => %d\n", filter->tcpopts.rst); + fprintf(stdout, "\t\tTCP PSH Flag => %d\n", filter->tcpopts.psh); + fprintf(stdout, "\t\tTCP SYN Flag => %d\n", filter->tcpopts.syn); + fprintf(stdout, "\t\tTCP FIN Flag => %d\n", filter->tcpopts.fin); + fprintf(stdout, "\t\tTCP ECE Flag => %d\n", filter->tcpopts.ece); + fprintf(stdout, "\t\tTCP CWR Flag => %d\n\n", filter->tcpopts.cwr); // UDP Options. fprintf(stdout, "\tUDP Options\n"); - fprintf(stdout, "\t\tUDP Enabled => %d\n", cfg.filters[i].udpopts.enabled); - fprintf(stdout, "\t\tUDP Source Port => %d\n", cfg.filters[i].udpopts.sport); - fprintf(stdout, "\t\tUDP Destination Port => %d\n\n", cfg.filters[i].udpopts.dport); + fprintf(stdout, "\t\tUDP Enabled => %d\n", filter->udpopts.enabled); + fprintf(stdout, "\t\tUDP Source Port => %d\n", filter->udpopts.sport); + fprintf(stdout, "\t\tUDP Destination Port => %d\n\n", filter->udpopts.dport); // ICMP Options. fprintf(stdout, "\tICMP Options\n"); - fprintf(stdout, "\t\tICMP Enabled => %d\n", cfg.filters[i].icmpopts.enabled); - fprintf(stdout, "\t\tICMP Code => %d\n", cfg.filters[i].icmpopts.code); - fprintf(stdout, "\t\tICMP Type => %d\n", cfg.filters[i].icmpopts.type); + fprintf(stdout, "\t\tICMP Enabled => %d\n", filter->icmpopts.enabled); + fprintf(stdout, "\t\tICMP Code => %d\n", filter->icmpopts.code); + fprintf(stdout, "\t\tICMP Type => %d\n", filter->icmpopts.type); fprintf(stdout, "\n\n"); } @@ -425,7 +431,7 @@ int main(int argc, char *argv[]) const char *filename = "/etc/xdpfw/xdpfw_kern.o"; // Load BPF object. - struct xdp_program *prog = loadbpfobj(filename); + struct xdp_program *prog = LoadBpfObj(filename); if (prog == NULL) { @@ -435,14 +441,14 @@ int main(int argc, char *argv[]) } // Attach XDP program. - if (attachxdp(prog, ifidx, 0, &cmd)) + if (AttachXdp(prog, ifidx, 0, &cmd)) { return EXIT_FAILURE; } // Retrieve BPF maps. - filtersmap = findmapfd(prog, "filters_map"); - statsmap = findmapfd(prog, "stats_map"); + filtersmap = FindMapFd(prog, "filters_map"); + statsmap = FindMapFd(prog, "stats_map"); // Check for valid maps. if (filtersmap < 0) @@ -460,10 +466,10 @@ int main(int argc, char *argv[]) } // Update BPF maps. - updatefilters(&cfg); + UpdateFilters(&cfg); // Signal. - signal(SIGINT, signalHndl); + signal(SIGINT, SignalHndl); // Receive CPU count for stats map parsing. int cpus = get_nprocs_conf(); @@ -492,15 +498,15 @@ int main(int argc, char *argv[]) { // Check if config file have been modified if (stat(cmd.cfgfile, &conf_stat) == 0 && conf_stat.st_mtime > lastupdated) { - // Memleak fix for strdup() in updateconfig() + // Memleak fix for strdup() in UpdateConfig() // Before updating it again, we need to free the old return value free(cfg.interface); // Update config. - updateconfig(&cfg, cmd.cfgfile); + UpdateConfig(&cfg, cmd.cfgfile); // Update BPF maps. - updatefilters(&cfg); + UpdateFilters(&cfg); // Update timer lastupdated = time(NULL); @@ -553,7 +559,7 @@ int main(int argc, char *argv[]) } // Detach XDP program. - attachxdp(prog, ifidx, 1, &cmd); + AttachXdp(prog, ifidx, 1, &cmd); // Add spacing. fprintf(stdout, "\n"); diff --git a/src/xdpfw.h b/src/xdpfw.h index bdbfe3a..5e28357 100644 --- a/src/xdpfw.h +++ b/src/xdpfw.h @@ -101,11 +101,14 @@ struct filter __u8 action; - __u32 srcip; - __u32 dstip; + __u32 src_ip; + __u8 src_cidr; - __u32 srcip6[4]; - __u32 dstip6[4]; + __u32 dst_ip; + __u8 dst_cidr; + + __u32 src_ip6[4]; + __u32 dst_ip6[4]; unsigned int do_min_ttl : 1; __u8 min_ttl; diff --git a/src/xdpfw_kern.c b/src/xdpfw_kern.c index d157847..2931044 100644 --- a/src/xdpfw_kern.c +++ b/src/xdpfw_kern.c @@ -16,6 +16,7 @@ #include #include "xdpfw.h" +#include "xdp_utils.h" #ifndef memcpy #define memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n)) @@ -103,7 +104,7 @@ int xdp_prog_main(struct xdp_md *ctx) // Initialize IP headers. struct iphdr *iph = NULL; struct ipv6hdr *iph6 = NULL; - __u128 srcip6 = 0; + __u128 src_ip6 = 0; // Set IPv4 and IPv6 common variables. if (eth->h_proto == htons(ETH_P_IPV6)) @@ -115,7 +116,7 @@ int xdp_prog_main(struct xdp_md *ctx) return XDP_DROP; } - memcpy(&srcip6, &iph6->saddr.in6_u.u6_addr32, sizeof(srcip6)); + memcpy(&src_ip6, &iph6->saddr.in6_u.u6_addr32, sizeof(src_ip6)); } else { @@ -144,7 +145,7 @@ int xdp_prog_main(struct xdp_md *ctx) if (iph6) { - blocked = bpf_map_lookup_elem(&ip6_blacklist_map, &srcip6); + blocked = bpf_map_lookup_elem(&ip6_blacklist_map, &src_ip6); } else if (iph) { @@ -162,7 +163,7 @@ int xdp_prog_main(struct xdp_md *ctx) // Remove element from map. if (iph6) { - bpf_map_delete_elem(&ip6_blacklist_map, &srcip6); + bpf_map_delete_elem(&ip6_blacklist_map, &src_ip6); } else if (iph) { @@ -192,7 +193,7 @@ int xdp_prog_main(struct xdp_md *ctx) if (iph6) { - ip_stats = bpf_map_lookup_elem(&ip6_stats_map, &srcip6); + ip_stats = bpf_map_lookup_elem(&ip6_stats_map, &src_ip6); } else if (iph) { @@ -234,7 +235,7 @@ int xdp_prog_main(struct xdp_md *ctx) if (iph6) { - bpf_map_update_elem(&ip6_stats_map, &srcip6, &new, BPF_ANY); + bpf_map_update_elem(&ip6_stats_map, &src_ip6, &new, BPF_ANY); } else if (iph) { @@ -353,19 +354,19 @@ int xdp_prog_main(struct xdp_md *ctx) if (iph6) { // Source address. - if (filter->srcip6[0] != 0 && (iph6->saddr.in6_u.u6_addr32[0] != filter->srcip6[0] || iph6->saddr.in6_u.u6_addr32[1] != filter->srcip6[1] || iph6->saddr.in6_u.u6_addr32[2] != filter->srcip6[2] || iph6->saddr.in6_u.u6_addr32[3] != filter->srcip6[3])) + 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])) { continue; } // Destination address. - if (filter->dstip6[0] != 0 && (iph6->daddr.in6_u.u6_addr32[0] != filter->dstip6[0] || iph6->daddr.in6_u.u6_addr32[1] != filter->dstip6[1] || iph6->daddr.in6_u.u6_addr32[2] != filter->dstip6[2] || iph6->daddr.in6_u.u6_addr32[3] != filter->dstip6[3])) + 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])) { continue; } #ifdef ALLOWSINGLEIPV4V6 - if (filter->srcip != 0 || filter->dstip != 0) + if (filter->src_ip != 0 || filter->dst_ip != 0) { continue; } @@ -398,19 +399,35 @@ int xdp_prog_main(struct xdp_md *ctx) else if (iph) { // Source address. - if (filter->srcip && iph->saddr != filter->srcip) + if (filter->src_ip) { - continue; + if (filter->src_cidr == 32 && iph->saddr != filter->src_ip) + { + continue; + } + + if (!IsIpInRange(iph->saddr, filter->src_ip, filter->src_cidr)) + { + continue; + } } // Destination address. - if (filter->dstip != 0 && iph->daddr != filter->dstip) + if (filter->dst_ip) { - continue; + if (filter->dst_cidr == 32 && iph->daddr != filter->dst_ip) + { + continue; + } + + if (!IsIpInRange(iph->daddr, filter->dst_ip, filter->dst_cidr)) + { + continue; + } } #ifdef ALLOWSINGLEIPV4V6 - if ((filter->srcip6[0] != 0 || filter->srcip6[1] != 0 || filter->srcip6[2] != 0 || filter->srcip6[3] != 0) || (filter->dstip6[0] != 0 || filter->dstip6[1] != 0 || filter->dstip6[2] != 0 || filter->dstip6[3] != 0)) + 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)) { continue; } @@ -615,7 +632,7 @@ int xdp_prog_main(struct xdp_md *ctx) if (iph6) { - bpf_map_update_elem(&ip6_blacklist_map, &srcip6, &newTime, BPF_ANY); + bpf_map_update_elem(&ip6_blacklist_map, &src_ip6, &newTime, BPF_ANY); } else if (iph) {