Merge pull request #63 from gamemann/20250306-multiple-interfaces
Multiple Interfaces Support + Reworking & Improving Code
This commit is contained in:
36
Makefile
36
Makefile
@@ -52,8 +52,8 @@ LOADER_UTILS_DIR = $(LOADER_DIR)/utils
|
||||
LOADER_UTILS_CONFIG_SRC = config.c
|
||||
LOADER_UTILS_CONFIG_OBJ = config.o
|
||||
|
||||
LOADER_UTILS_CMDLINE_SRC = cmdline.c
|
||||
LOADER_UTILS_CMDLINE_OBJ = cmdline.o
|
||||
LOADER_UTILS_cli_SRC = cli.c
|
||||
LOADER_UTILS_cli_OBJ = cli.o
|
||||
|
||||
LOADER_UTILS_XDP_SRC = xdp.c
|
||||
LOADER_UTILS_XDP_OBJ = xdp.o
|
||||
@@ -68,7 +68,7 @@ LOADER_UTILS_HELPERS_SRC = helpers.c
|
||||
LOADER_UTILS_HELPERS_OBJ = helpers.o
|
||||
|
||||
# Loader objects.
|
||||
LOADER_OBJS = $(BUILD_LOADER_DIR)/$(LOADER_UTILS_CONFIG_OBJ) $(BUILD_LOADER_DIR)/$(LOADER_UTILS_CMDLINE_OBJ) $(BUILD_LOADER_DIR)/$(LOADER_UTILS_XDP_OBJ) $(BUILD_LOADER_DIR)/$(LOADER_UTILS_LOGGING_OBJ) $(BUILD_LOADER_DIR)/$(LOADER_UTILS_STATS_OBJ) $(BUILD_LOADER_DIR)/$(LOADER_UTILS_HELPERS_OBJ)
|
||||
LOADER_OBJS = $(BUILD_LOADER_DIR)/$(LOADER_UTILS_CONFIG_OBJ) $(BUILD_LOADER_DIR)/$(LOADER_UTILS_cli_OBJ) $(BUILD_LOADER_DIR)/$(LOADER_UTILS_XDP_OBJ) $(BUILD_LOADER_DIR)/$(LOADER_UTILS_LOGGING_OBJ) $(BUILD_LOADER_DIR)/$(LOADER_UTILS_STATS_OBJ) $(BUILD_LOADER_DIR)/$(LOADER_UTILS_HELPERS_OBJ)
|
||||
|
||||
ifeq ($(LIBXDP_STATIC), 1)
|
||||
LOADER_OBJS := $(LIBBPF_OBJS) $(LIBXDP_OBJS) $(LOADER_OBJS)
|
||||
@@ -92,10 +92,10 @@ RULE_ADD_OUT = xdpfw-add
|
||||
RULE_ADD_UTILS_DIR = $(RULE_ADD_DIR)/utils
|
||||
|
||||
# Rule add utils.
|
||||
RULE_ADD_UTILS_CMDLINE_SRC = cmdline.c
|
||||
RULE_ADD_UTILS_CMDLINE_OBJ = cmdline.o
|
||||
RULE_ADD_UTILS_cli_SRC = cli.c
|
||||
RULE_ADD_UTILS_cli_OBJ = cli.o
|
||||
|
||||
RULE_ADD_OBJS = $(BUILD_RULE_ADD_DIR)/$(RULE_ADD_UTILS_CMDLINE_OBJ)
|
||||
RULE_ADD_OBJS = $(BUILD_RULE_ADD_DIR)/$(RULE_ADD_UTILS_cli_OBJ)
|
||||
|
||||
# Rule delete.
|
||||
RULE_DEL_SRC = prog.c
|
||||
@@ -104,10 +104,10 @@ RULE_DEL_OUT = xdpfw-del
|
||||
RULE_DEL_UTILS_DIR = $(RULE_DEL_DIR)/utils
|
||||
|
||||
# Rule delete utils.
|
||||
RULE_DEL_UTILS_CMDLINE_SRC = cmdline.c
|
||||
RULE_DEL_UTILS_CMDLINE_OBJ = cmdline.o
|
||||
RULE_DEL_UTILS_cli_SRC = cli.c
|
||||
RULE_DEL_UTILS_cli_OBJ = cli.o
|
||||
|
||||
RULE_DEL_OBJS = $(BUILD_RULE_DEL_DIR)/$(RULE_DEL_UTILS_CMDLINE_OBJ)
|
||||
RULE_DEL_OBJS = $(BUILD_RULE_DEL_DIR)/$(RULE_DEL_UTILS_cli_OBJ)
|
||||
|
||||
# Includes.
|
||||
INCS = -I $(SRC_DIR) -I /usr/include -I /usr/local/include
|
||||
@@ -133,13 +133,13 @@ all: loader xdp rule_add rule_del
|
||||
loader: loader_utils
|
||||
$(CC) $(INCS) $(FLAGS) $(FLAGS_LOADER) -o $(BUILD_LOADER_DIR)/$(LOADER_OUT) $(LOADER_OBJS) $(LOADER_DIR)/$(LOADER_SRC)
|
||||
|
||||
loader_utils: loader_utils_config loader_utils_cmdline loader_utils_helpers loader_utils_xdp loader_utils_logging loader_utils_stats
|
||||
loader_utils: loader_utils_config loader_utils_cli loader_utils_helpers loader_utils_xdp loader_utils_logging loader_utils_stats
|
||||
|
||||
loader_utils_config:
|
||||
$(CC) $(INCS) $(FLAGS) -c -o $(BUILD_LOADER_DIR)/$(LOADER_UTILS_CONFIG_OBJ) $(LOADER_UTILS_DIR)/$(LOADER_UTILS_CONFIG_SRC)
|
||||
|
||||
loader_utils_cmdline:
|
||||
$(CC) $(INCS) $(FLAGS) -c -o $(BUILD_LOADER_DIR)/$(LOADER_UTILS_CMDLINE_OBJ) $(LOADER_UTILS_DIR)/$(LOADER_UTILS_CMDLINE_SRC)
|
||||
loader_utils_cli:
|
||||
$(CC) $(INCS) $(FLAGS) -c -o $(BUILD_LOADER_DIR)/$(LOADER_UTILS_cli_OBJ) $(LOADER_UTILS_DIR)/$(LOADER_UTILS_cli_SRC)
|
||||
|
||||
loader_utils_xdp:
|
||||
$(CC) $(INCS) $(FLAGS) -c -o $(BUILD_LOADER_DIR)/$(LOADER_UTILS_XDP_OBJ) $(LOADER_UTILS_DIR)/$(LOADER_UTILS_XDP_SRC)
|
||||
@@ -161,19 +161,19 @@ xdp:
|
||||
rule_add: loader_utils rule_add_utils
|
||||
$(CC) $(INCS) $(FLAGS) $(FLAGS_LOADER) -o $(BUILD_RULE_ADD_DIR)/$(RULE_ADD_OUT) $(RULE_OBJS) $(RULE_ADD_OBJS) $(RULE_ADD_DIR)/$(RULE_ADD_SRC)
|
||||
|
||||
rule_add_utils: rule_add_utils_cmdline
|
||||
rule_add_utils: rule_add_utils_cli
|
||||
|
||||
rule_add_utils_cmdline:
|
||||
$(CC) $(INCS) $(FLAGS) -c -o $(BUILD_RULE_ADD_DIR)/$(RULE_ADD_UTILS_CMDLINE_OBJ) $(RULE_ADD_UTILS_DIR)/$(RULE_ADD_UTILS_CMDLINE_SRC)
|
||||
rule_add_utils_cli:
|
||||
$(CC) $(INCS) $(FLAGS) -c -o $(BUILD_RULE_ADD_DIR)/$(RULE_ADD_UTILS_cli_OBJ) $(RULE_ADD_UTILS_DIR)/$(RULE_ADD_UTILS_cli_SRC)
|
||||
|
||||
# Rule delete.
|
||||
rule_del: loader_utils rule_del_utils
|
||||
$(CC) $(INCS) $(FLAGS) $(FLAGS_LOADER) -o $(BUILD_RULE_DEL_DIR)/$(RULE_DEL_OUT) $(RULE_OBJS) $(RULE_DEL_OBJS) $(RULE_DEL_DIR)/$(RULE_DEL_SRC)
|
||||
|
||||
rule_del_utils: rule_del_utils_cmdline
|
||||
rule_del_utils: rule_del_utils_cli
|
||||
|
||||
rule_del_utils_cmdline:
|
||||
$(CC) $(INCS) $(FLAGS) -c -o $(BUILD_RULE_DEL_DIR)/$(RULE_DEL_UTILS_CMDLINE_OBJ) $(RULE_DEL_UTILS_DIR)/$(RULE_DEL_UTILS_CMDLINE_SRC)
|
||||
rule_del_utils_cli:
|
||||
$(CC) $(INCS) $(FLAGS) -c -o $(BUILD_RULE_DEL_DIR)/$(RULE_DEL_UTILS_cli_OBJ) $(RULE_DEL_UTILS_DIR)/$(RULE_DEL_UTILS_cli_SRC)
|
||||
|
||||
# LibXDP chain. We need to install objects here since our program relies on installed object files and such.
|
||||
libxdp:
|
||||
|
||||
66
README.md
66
README.md
@@ -134,7 +134,7 @@ Additionally, there are command line overrides for base config options you may i
|
||||
| ---- | ------- | ----------- |
|
||||
| -v, --verbose | `-v 3` | Overrides the config's verbose value. |
|
||||
| --log-file | `--log-file ./test.log` | Overrides the config's log file value. |
|
||||
| -i, --interface | `-i enp1s0` | Overrides the config's interface value. |
|
||||
| -i, --interface | `-i enp1s0` | Overrides the config's first interface value. |
|
||||
| -p, --pin-maps | `-p 0` | Overrides the config's pin maps value. |
|
||||
| -u, --update-time | `-u 30` | Overrides the config's update time value. |
|
||||
| -n, --no-stats | `-n 1` | Overrides the config's no stats value. |
|
||||
@@ -152,51 +152,41 @@ The [`libconfig`](https://hyperrealm.github.io/libconfig/libconfig_manual.html)
|
||||
|
||||
Here are more details on the layout of the runtime configuration.
|
||||
|
||||
### Data Types
|
||||
The following table quickly explains the data types used within the configuration documentation below (known data types which are not used within the configuration below will **not** be listed).
|
||||
|
||||
| Name | Size (Bytes) | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| bool | 1 | A simple `true` or `false` field. |
|
||||
| byte | 1 | A number from `0` to `255`. |
|
||||
| string | N/A | An array of characters with no known size (values should be within quotes, `""`). |
|
||||
| uint | 4 | A number from `0` to `4294967295`. |
|
||||
| ulong | 8 | A number from `0` to `18446744073709551615 `. |
|
||||
| ushort | 2 | A number from `0` to `65535`. |
|
||||
| NULL | N/A | No address/value; Empty or 0. |
|
||||
|
||||
### Main
|
||||
| Name | Type | Default | Description |
|
||||
| ---- | ---- | ------- | ----------- |
|
||||
| verbose | int | `2` | The verbose level for logging (0 - 5 supported so far). |
|
||||
| log_file | string | `/var/log/xdpfw.log` | The log file location. If the string is empty (`""`), the log file is disabled. |
|
||||
| interface | string | `NULL` | The network interface name to attach the XDP program to (usually retrieved with `ip a` or `ifconfig`). |
|
||||
| interfaces | string \| list of strings | `NULL` | The network interface(s) to attach the XDP program to (usually retrieved with `ip a` or `ifconfig`). |
|
||||
| pin_maps | bool | `true` | Pins main BPF maps to `/sys/fs/bpf/xdpfw/[map_name]` on the file system. |
|
||||
| update_time | uint | `0` | How often to update the config and filtering rules from the file system in seconds (0 disables). |
|
||||
| update_time | int | `0` | How often to update the config and filtering rules from the file system in seconds (0 disables). |
|
||||
| no_stats | bool | `false` | Whether to enable or disable packet counters. Disabling packet counters will improve performance, but result in less visibility on what the XDP Firewall is doing. |
|
||||
| stats_per_second | bool | `false` | If true, packet counters and stats are calculated per second. `stdout_update_time` must be 1000 or less for this to work properly. |
|
||||
| stdout_update_time | uint | `1000` | How often to update `stdout` when displaying packet counters in milliseconds. |
|
||||
| filters | Array of Filter Object(s) | `NULL` | An array of filters to use with the XDP Firewall. |
|
||||
| ip_drop_ranges | Array Of IP Ranges | `NULL` | An array of IP ranges (strings) to drop if the IP range drop feature is enabled. |
|
||||
| stdout_update_time | int | `1000` | How often to update `stdout` when displaying packet counters in milliseconds. |
|
||||
| filters | list of filter objects | `()` | A list of filters to use with the XDP Firewall. |
|
||||
| ip_drop_ranges | list of strings | `()` | A list of IP ranges (strings) to drop if the IP range drop feature is enabled. |
|
||||
|
||||
### Filter Object
|
||||
| Name | Type | Default | Description |
|
||||
| ---- | ---- | ------- | ----------- |
|
||||
| enabled | bool | `true` | Whether the rule is enabled or not. |
|
||||
| action | uint | `1` | The value of `0` drops or blocks the packet while `1` allows/passes the packet through. |
|
||||
| log | bool | `false` | Whether to log packets that are matched. |
|
||||
| block_time | uint | `1` | The amount of seconds to block the source IP for if matched. |
|
||||
| action | int | `1` | The value of `0` drops or blocks the packet while `1` allows/passes the packet through. |
|
||||
| block_time | int | `1` | The amount of seconds to block the source IP for if matched. |
|
||||
| pps | int64 | `NULL` | Matches if this threshold of packets per second is exceeded for a source IP. |
|
||||
| bps | int64 | `NULL` | Matches if this threshold of bytes per second is exceeded for a source IP. |
|
||||
|
||||
#### IP Options
|
||||
| Name | Type | Default | Description |
|
||||
| ---- | ---- | ------- | ----------- |
|
||||
| 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. |
|
||||
| max_ttl | byte | `NULL` | The maximum TTL (time-to-live) to match. |
|
||||
| min_len | ushort | `NULL` | The minimum packet length to match (includes the entire packet including the ethernet header and payload). |
|
||||
| max_len | ushort | `NULL` | The maximum packet length to match (includes the entire packet including the ethernet header and payload). |
|
||||
| tos | byte | `NULL` | The ToS (type-of-service) to match. |
|
||||
| pps | ulong | `NULL` | Matches if this threshold of packets per second is exceeded for a source IP. |
|
||||
| bps | ulong | `NULL` | Matches if this threshold of bytes per second is exceeded for a source IP. |
|
||||
| min_ttl | int | `NULL` | The minimum TTL (time-to-live) to match. |
|
||||
| max_ttl | int | `NULL` | The maximum TTL (time-to-live) to match. |
|
||||
| max_len | int | `NULL` | The maximum packet length to match (includes the entire packet including the ethernet header and payload). |
|
||||
| tos | int | `NULL` | The ToS (type-of-service) to match. |
|
||||
|
||||
#### TCP Options
|
||||
You may additionally specified TCP header options for a filter rule which start with `tcp_`.
|
||||
@@ -204,8 +194,8 @@ You may additionally specified TCP header options for a filter rule which start
|
||||
| Name | Type | Default | Description |
|
||||
| ---- | ---- | ------- | ----------- |
|
||||
| tcp_enabled | bool | `false` | Whether to enable TCP on this filter rule. |
|
||||
| tcp_sport | ushort | `NULL` | The TCP source port to match. |
|
||||
| tcp_dport | ushort | `NULL` | The TCP destination port to match. |
|
||||
| tcp_sport | int | `NULL` | The TCP source port to match. |
|
||||
| tcp_dport | int | `NULL` | The TCP destination port to match. |
|
||||
| tcp_syn | bool | `false` | Matches if the TCP SYN flag is set. |
|
||||
| tcp_ack | bool | `false` | Matches if the TCP ACK flag is set. |
|
||||
| tcp_rst | bool | `false` | Matches if the TCP RST flag is set. |
|
||||
@@ -221,8 +211,8 @@ You may additionally specified UDP header options for a filter rule which start
|
||||
| Name | Type | Default | Description |
|
||||
| ---- | ---- | ------- | ----------- |
|
||||
| udp_enabled | bool | `false` | Whether to enable UDP on this filter rule. |
|
||||
| udp_sport | ushort | `NULL` | The UDP source port to match. |
|
||||
| udp_dport | ushort | `NULL` | The UDP destination port to match. |
|
||||
| udp_sport | int | `NULL` | The UDP source port to match. |
|
||||
| udp_dport | int | `NULL` | The UDP destination port to match. |
|
||||
|
||||
#### ICMP Options
|
||||
You may additionally specified UDP header options for a filter rule which start with `icmp_`.
|
||||
@@ -230,13 +220,13 @@ You may additionally specified UDP header options for a filter rule which start
|
||||
| Name | Type | Default | Description |
|
||||
| ---- | ---- | ------- | ----------- |
|
||||
| icmp_enabled | bool | `false` | Whether to enable ICMP on this filter rule. |
|
||||
| icmp_code | byte | `NULL` | The ICMP code to match. |
|
||||
| icmp_type | byte | `NULL` | The ICMP type to match. |
|
||||
| icmp_code | int | `NULL` | The ICMP code to match. |
|
||||
| icmp_type | int | `NULL` | The ICMP type to match. |
|
||||
|
||||
#### Notes
|
||||
* All settings within a filter rule other than `enabled` and `action` are **not** required. This means you do not have to define them within your config.
|
||||
* When a filter rule's setting is set (not `NULL`), but doesn't match the packet, the program moves onto the next filter rule. Therefore, all of the filter rule's settings that are set must match the packet in order to perform the action specified. Think of it as something like `if src_ip == "10.50.0.3" and udp_dport == 27015: action`.
|
||||
* As of right now, you can specify up to **60 total** dynamic filter rules. You may increase this limit by raising the `MAX_FILTERS` constant in the `src/common/config.h` [file](https://github.com/gamemann/XDP-Firewall/blob/master/src/common/config.h#L5) and then recompile the firewall. If you receive a BPF program too large error, this is due to BPF's limitations with complexity and jumps. You may try increasing BPF limitations manually or with a patch. If you want to do this, please read [this](https://github.com/gamemann/XDP-Forwarding/tree/master/patches) README from my XDP Forwarding project.
|
||||
* When a setting field inside of a filter rule is not set or if it's set to `-1` (or `NULL`), the default setting value will be used (see [`set_filter_defaults()`](https://github.com/gamemann/XDP-Firewall/blob/master/src/loader/utils/config.c#L1047)).
|
||||
* When a filter rule's setting is set, but doesn't match the packet, the program moves onto the next filter rule. Therefore, all of the filter rule's settings that are set must match the packet in order to perform the action specified. Think of it as something like `if src_ip == "10.50.0.3" and udp_dport == 27015: action`.
|
||||
* As of right now, you can specify up to **60 total** dynamic filter rules. You may increase this limit by raising the `MAX_FILTERS` constant in the `src/common/config.h` [file](https://github.com/gamemann/XDP-Firewall/blob/master/src/common/config.h#L5) and then recompile the firewall. If you receive a BPF program too large error, this is due to BPF's limitations with complexity and jumps. You may try increasing BPF limitations manually or with a patch. If you want to do this, please read [this](https://github.com/gamemann/XDP-Proxy/tree/master/patches) from my XDP Proxy project.
|
||||
|
||||
### Runtime Example
|
||||
Here's a runtime config example.
|
||||
@@ -244,7 +234,7 @@ Here's a runtime config example.
|
||||
```squidconf
|
||||
verbose = 5;
|
||||
log_file = "";
|
||||
interface = "ens18";
|
||||
interfaces = "ens18";
|
||||
pin_maps = true;
|
||||
update_time = 15;
|
||||
no_stats = false;
|
||||
|
||||
@@ -39,3 +39,6 @@
|
||||
// Enables filter logging through XDP.
|
||||
// If performance is a concern, it is best to disable this feature by commenting out the below line with //.
|
||||
#define ENABLE_FILTER_LOGGING
|
||||
|
||||
// Maximum interfaces the firewall can attach to.
|
||||
#define MAX_INTERFACES 6
|
||||
@@ -2,7 +2,34 @@
|
||||
|
||||
#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;
|
||||
|
||||
@@ -36,9 +63,9 @@ struct tcp_opts
|
||||
|
||||
unsigned int do_cwr : 1;
|
||||
unsigned int cwr : 1;
|
||||
} typedef tcp_opts_t;
|
||||
} typedef filter_tcp_t;
|
||||
|
||||
struct udp_opts
|
||||
struct filter_udp
|
||||
{
|
||||
unsigned int enabled : 1;
|
||||
|
||||
@@ -47,9 +74,9 @@ struct udp_opts
|
||||
|
||||
unsigned int do_dport : 1;
|
||||
u16 dport;
|
||||
} typedef udp_opts_t;
|
||||
} typedef filter_udp_t;
|
||||
|
||||
struct icmp_opts
|
||||
struct filter_icmp
|
||||
{
|
||||
unsigned int enabled : 1;
|
||||
|
||||
@@ -58,7 +85,7 @@ struct icmp_opts
|
||||
|
||||
unsigned int do_type : 1;
|
||||
u8 type;
|
||||
} typedef icmp_opts_t;
|
||||
} typedef filter_icmp_t;
|
||||
|
||||
struct filter
|
||||
{
|
||||
@@ -67,30 +94,7 @@ struct filter
|
||||
unsigned int enabled : 1;
|
||||
|
||||
u8 action;
|
||||
|
||||
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;
|
||||
u16 block_time;
|
||||
|
||||
unsigned int do_pps : 1;
|
||||
u64 pps;
|
||||
@@ -98,11 +102,11 @@ struct filter
|
||||
unsigned int do_bps : 1;
|
||||
u64 bps;
|
||||
|
||||
u64 block_time;
|
||||
filter_ip_t ip;
|
||||
|
||||
tcp_opts_t tcpopts;
|
||||
udp_opts_t udpopts;
|
||||
icmp_opts_t icmpopts;
|
||||
filter_tcp_t tcp;
|
||||
filter_udp_t udp;
|
||||
filter_icmp_t icmp;
|
||||
} __attribute__((__aligned__(8))) typedef filter_t;
|
||||
|
||||
struct stats
|
||||
@@ -138,6 +142,8 @@ struct filter_log_event
|
||||
u64 ts;
|
||||
int filter_id;
|
||||
|
||||
int length;
|
||||
|
||||
u32 src_ip;
|
||||
u32 src_ip6[4];
|
||||
|
||||
@@ -154,7 +160,8 @@ struct filter_log_event
|
||||
u64 bps;
|
||||
} typedef filter_log_event_t;
|
||||
|
||||
struct lpm_trie_key {
|
||||
struct lpm_trie_key
|
||||
{
|
||||
u32 prefix_len;
|
||||
u32 data;
|
||||
} typedef LpmTrieKey;
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <loader/utils/cmdline.h>
|
||||
#include <loader/utils/cli.h>
|
||||
#include <loader/utils/config.h>
|
||||
#include <loader/utils/xdp.h>
|
||||
#include <loader/utils/logging.h>
|
||||
@@ -28,56 +28,56 @@ int doing_stats = 0;
|
||||
* @param obj A pointer to the BPF object.
|
||||
* @param ignore_errors Whether to ignore errors.
|
||||
*/
|
||||
static void UnpinNeededMaps(config__t* cfg, struct bpf_object* obj, int ignore_errors)
|
||||
static void unpin_needed_maps(config__t* cfg, struct bpf_object* obj, int ignore_errors)
|
||||
{
|
||||
int ret;
|
||||
|
||||
// Unpin block map.
|
||||
if ((ret = UnpinBpfMap(obj, XDP_MAP_PIN_DIR, "map_block")) != 0)
|
||||
if ((ret = unpin_bpf_map(obj, XDP_MAP_PIN_DIR, "map_block")) != 0)
|
||||
{
|
||||
if (!ignore_errors)
|
||||
{
|
||||
LogMsg(cfg, 1, 0, "[WARNING] Failed to un-pin BPF map 'map_block' from file system (%d).", ret);
|
||||
log_msg(cfg, 1, 0, "[WARNING] Failed to un-pin BPF map 'map_block' from file system (%d).", ret);
|
||||
}
|
||||
}
|
||||
|
||||
// Unpin block (IPv6) map.
|
||||
if ((ret = UnpinBpfMap(obj, XDP_MAP_PIN_DIR, "map_block6")) != 0)
|
||||
if ((ret = unpin_bpf_map(obj, XDP_MAP_PIN_DIR, "map_block6")) != 0)
|
||||
{
|
||||
if (!ignore_errors)
|
||||
{
|
||||
LogMsg(cfg, 1, 0, "[WARNING] Failed to un-pin BPF map 'map_block6' from file system (%d).", ret);
|
||||
log_msg(cfg, 1, 0, "[WARNING] Failed to un-pin BPF map 'map_block6' from file system (%d).", ret);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IP_RANGE_DROP
|
||||
// Unpin IPv4 range drop map.
|
||||
if ((ret = UnpinBpfMap(obj, XDP_MAP_PIN_DIR, "map_range_drop")) != 0)
|
||||
if ((ret = unpin_bpf_map(obj, XDP_MAP_PIN_DIR, "map_range_drop")) != 0)
|
||||
{
|
||||
if (!ignore_errors)
|
||||
{
|
||||
LogMsg(cfg, 1, 0, "[WARNING] Failed to un-pin BPF map 'map_range_drop' from file system (%d).", ret);
|
||||
log_msg(cfg, 1, 0, "[WARNING] Failed to un-pin BPF map 'map_range_drop' from file system (%d).", ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FILTERS
|
||||
// Unpin filters map.
|
||||
if ((ret = UnpinBpfMap(obj, XDP_MAP_PIN_DIR, "map_filters")) != 0)
|
||||
if ((ret = unpin_bpf_map(obj, XDP_MAP_PIN_DIR, "map_filters")) != 0)
|
||||
{
|
||||
if (!ignore_errors)
|
||||
{
|
||||
LogMsg(cfg, 1, 0, "[WARNING] Failed to un-pin BPF map 'map_filters' from file system (%d).", ret);
|
||||
log_msg(cfg, 1, 0, "[WARNING] Failed to un-pin BPF map 'map_filters' from file system (%d).", ret);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_FILTER_LOGGING
|
||||
// Unpin filters log map.
|
||||
if ((ret = UnpinBpfMap(obj, XDP_MAP_PIN_DIR, "map_filter_log")) != 0)
|
||||
if ((ret = unpin_bpf_map(obj, XDP_MAP_PIN_DIR, "map_filter_log")) != 0)
|
||||
{
|
||||
if (!ignore_errors)
|
||||
{
|
||||
LogMsg(cfg, 1, 0, "[WARNING] Failed to un-pin BPF map 'map_filter_log' from file system (%d).", ret);
|
||||
log_msg(cfg, 1, 0, "[WARNING] Failed to un-pin BPF map 'map_filter_log' from file system (%d).", ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -89,21 +89,21 @@ int main(int argc, char *argv[])
|
||||
int ret;
|
||||
|
||||
// Parse the command line.
|
||||
cmdline_t cmd = {0};
|
||||
cmd.cfg_file = CONFIG_DEFAULT_PATH;
|
||||
cmd.verbose = -1;
|
||||
cmd.pin_maps = -1;
|
||||
cmd.update_time = -1;
|
||||
cmd.no_stats = -1;
|
||||
cmd.stats_per_second = -1;
|
||||
cmd.stdout_update_time = -1;
|
||||
cli_t cli = {0};
|
||||
cli.cfg_file = CONFIG_DEFAULT_PATH;
|
||||
cli.verbose = -1;
|
||||
cli.pin_maps = -1;
|
||||
cli.update_time = -1;
|
||||
cli.no_stats = -1;
|
||||
cli.stats_per_second = -1;
|
||||
cli.stdout_update_time = -1;
|
||||
|
||||
ParseCommandLine(&cmd, argc, argv);
|
||||
parse_cli(&cli, argc, argv);
|
||||
|
||||
// Check for help.
|
||||
if (cmd.help)
|
||||
if (cli.help)
|
||||
{
|
||||
PrintHelpMenu();
|
||||
print_help_menu();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -111,31 +111,29 @@ int main(int argc, char *argv[])
|
||||
// Initialize config.
|
||||
config__t cfg = {0};
|
||||
|
||||
SetCfgDefaults(&cfg);
|
||||
|
||||
// Create overrides for config and set arguments from CLI.
|
||||
config_overrides_t cfg_overrides = {0};
|
||||
cfg_overrides.verbose = cmd.verbose;
|
||||
cfg_overrides.log_file = cmd.log_file;
|
||||
cfg_overrides.interface = cmd.interface;
|
||||
cfg_overrides.pin_maps = cmd.pin_maps;
|
||||
cfg_overrides.update_time = cmd.update_time;
|
||||
cfg_overrides.no_stats = cmd.no_stats;
|
||||
cfg_overrides.stats_per_second = cmd.stats_per_second;
|
||||
cfg_overrides.stdout_update_time = cmd.stdout_update_time;
|
||||
cfg_overrides.verbose = cli.verbose;
|
||||
cfg_overrides.log_file = cli.log_file;
|
||||
cfg_overrides.interface = cli.interface;
|
||||
cfg_overrides.pin_maps = cli.pin_maps;
|
||||
cfg_overrides.update_time = cli.update_time;
|
||||
cfg_overrides.no_stats = cli.no_stats;
|
||||
cfg_overrides.stats_per_second = cli.stats_per_second;
|
||||
cfg_overrides.stdout_update_time = cli.stdout_update_time;
|
||||
|
||||
// Load config.
|
||||
if ((ret = LoadConfig(&cfg, cmd.cfg_file, &cfg_overrides)) != 0)
|
||||
if ((ret = load_cfg(&cfg, cli.cfg_file, 1, &cfg_overrides)) != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] Failed to load config from file system (%s)(%d).\n", cmd.cfg_file, ret);
|
||||
fprintf(stderr, "[ERROR] Failed to load config from file system (%s)(%d).\n", cli.cfg_file, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Check for list option.
|
||||
if (cmd.list)
|
||||
if (cli.list)
|
||||
{
|
||||
PrintConfig(&cfg);
|
||||
print_cfg(&cfg);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -143,42 +141,30 @@ int main(int argc, char *argv[])
|
||||
// Print tool info.
|
||||
if (cfg.verbose > 0)
|
||||
{
|
||||
PrintToolInfo();
|
||||
print_tool_info();
|
||||
}
|
||||
|
||||
// Check interface.
|
||||
if (cfg.interface == NULL)
|
||||
// Check first interface.
|
||||
if (!cfg.interfaces[0])
|
||||
{
|
||||
LogMsg(&cfg, 0, 1, "[ERROR] No interface specified in config or CLI override.");
|
||||
log_msg(&cfg, 0, 1, "[ERROR] No interface(s) specified in config or CLI override.");
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
LogMsg(&cfg, 2, 0, "Raising RLimit...");
|
||||
log_msg(&cfg, 2, 0, "Raising RLimit...");
|
||||
|
||||
// Raise RLimit.
|
||||
struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
|
||||
|
||||
if (setrlimit(RLIMIT_MEMLOCK, &rl))
|
||||
{
|
||||
LogMsg(&cfg, 0, 1, "[ERROR] Failed to raise rlimit. Please make sure this program is ran as root!\n");
|
||||
log_msg(&cfg, 0, 1, "[ERROR] Failed to raise rlimit. Please make sure this program is ran as root!\n");
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
LogMsg(&cfg, 2, 0, "Retrieving interface index for '%s'...", cfg.interface);
|
||||
|
||||
// Get interface index.
|
||||
int ifidx = if_nametoindex(cfg.interface);
|
||||
|
||||
if (ifidx < 0)
|
||||
{
|
||||
LogMsg(&cfg, 0, 1, "[ERROR] Failed to retrieve index of network interface '%s'.\n", cfg.interface);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
LogMsg(&cfg, 2, 0, "Loading XDP/BPF program at '%s'...", XDP_OBJ_PATH);
|
||||
log_msg(&cfg, 2, 0, "Loading XDP/BPF program at '%s'...", XDP_OBJ_PATH);
|
||||
|
||||
// Determine custom LibBPF log level.
|
||||
int silent = 1;
|
||||
@@ -188,187 +174,227 @@ int main(int argc, char *argv[])
|
||||
silent = 0;
|
||||
}
|
||||
|
||||
SetLibBPFLogMode(silent);
|
||||
set_libbpf_log_mode(silent);
|
||||
|
||||
// Load BPF object.
|
||||
struct xdp_program *prog = LoadBpfObj(XDP_OBJ_PATH);
|
||||
struct xdp_program *prog = load_bpf_obj(XDP_OBJ_PATH);
|
||||
|
||||
if (prog == NULL)
|
||||
{
|
||||
LogMsg(&cfg, 0, 1, "[ERROR] Failed to load eBPF object file. Object path => %s.\n", XDP_OBJ_PATH);
|
||||
log_msg(&cfg, 0, 1, "[ERROR] Failed to load eBPF object file. Object path => %s.\n", XDP_OBJ_PATH);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
LogMsg(&cfg, 2, 0, "Attaching XDP program to interface '%s'...", cfg.interface);
|
||||
int if_idx[MAX_INTERFACES] = {0};
|
||||
int attach_success = 0;
|
||||
|
||||
// Attach XDP program to interface(s).
|
||||
for (int i = 0; i < cfg.interfaces_cnt; i++)
|
||||
{
|
||||
const char* interface = cfg.interfaces[i];
|
||||
|
||||
if (!interface)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
log_msg(&cfg, 4, 0, "Retrieving interface index for '%s'...", interface);
|
||||
|
||||
// Get interface index.
|
||||
if_idx[i] = if_nametoindex(interface);
|
||||
|
||||
if (if_idx[i] < 0)
|
||||
{
|
||||
log_msg(&cfg, 0, 1, "[WARNING] Failed to retrieve index of network interface '%s'.\n", interface);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
log_msg(&cfg, 3, 0, "Interface index for '%s' => %d.", interface, if_idx[i]);
|
||||
|
||||
log_msg(&cfg, 2, 0, "Attaching XDP program to interface '%s'...", interface);
|
||||
|
||||
// Attach XDP program.
|
||||
char* mode_used = NULL;
|
||||
|
||||
if ((ret = AttachXdp(prog, &mode_used, ifidx, 0, cmd.skb, cmd.offload)) != 0)
|
||||
if ((ret = attach_xdp(prog, &mode_used, if_idx[i], 0, cli.skb, cli.offload)) != 0)
|
||||
{
|
||||
LogMsg(&cfg, 0, 1, "[ERROR] Failed to attach XDP program to interface '%s' using available modes (%d).\n", cfg.interface, ret);
|
||||
log_msg(&cfg, 0, 1, "[WARNING] Failed to attach XDP program to interface '%s' using available modes (%d).\n", interface, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mode_used != NULL)
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "Attached XDP program using mode '%s'...", mode_used);
|
||||
log_msg(&cfg, 1, 0, "Attached XDP program to interface '%s' using mode '%s'...", interface, mode_used);
|
||||
}
|
||||
|
||||
LogMsg(&cfg, 2, 0, "Retrieving BPF map FDs...");
|
||||
if (!attach_success)
|
||||
{
|
||||
attach_success = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!attach_success)
|
||||
{
|
||||
log_msg(&cfg, 0, 1, "[ERROR] Failed to attach XDP program to any configured interfaces.");
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
log_msg(&cfg, 2, 0, "Retrieving BPF map FDs...");
|
||||
|
||||
// Retrieve BPF maps.
|
||||
int map_stats = FindMapFd(prog, "map_stats");
|
||||
int map_stats = get_map_fd(prog, "map_stats");
|
||||
|
||||
if (map_stats < 0)
|
||||
{
|
||||
LogMsg(&cfg, 0, 1, "[ERROR] Failed to find 'map_stats' BPF map.\n");
|
||||
log_msg(&cfg, 0, 1, "[ERROR] Failed to find 'map_stats' BPF map.\n");
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_FILTERS
|
||||
int map_filters = FindMapFd(prog, "map_filters");
|
||||
int map_filters = get_map_fd(prog, "map_filters");
|
||||
|
||||
// Check for valid maps.
|
||||
if (map_filters < 0)
|
||||
{
|
||||
LogMsg(&cfg, 0, 1, "[ERROR] Failed to find 'map_filters' BPF map.\n");
|
||||
log_msg(&cfg, 0, 1, "[ERROR] Failed to find 'map_filters' BPF map.\n");
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
LogMsg(&cfg, 3, 0, "map_filters FD => %d.", map_filters);
|
||||
log_msg(&cfg, 3, 0, "map_filters FD => %d.", map_filters);
|
||||
|
||||
#ifdef ENABLE_FILTER_LOGGING
|
||||
int map_filter_log = FindMapFd(prog, "map_filter_log");
|
||||
int map_filter_log = get_map_fd(prog, "map_filter_log");
|
||||
|
||||
struct ring_buffer* rb = NULL;
|
||||
|
||||
if (map_filter_log < 0)
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "[WARNING] Failed to find 'map_filter_log' BPF map. Filter logging will be disabled...");
|
||||
log_msg(&cfg, 1, 0, "[WARNING] Failed to find 'map_filter_log' BPF map. Filter logging will be disabled...");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMsg(&cfg, 3, 0, "map_filter_log FD => %d.", map_filter_log);
|
||||
log_msg(&cfg, 3, 0, "map_filter_log FD => %d.", map_filter_log);
|
||||
|
||||
rb = ring_buffer__new(map_filter_log, HandleRbEvent, &cfg, NULL);
|
||||
rb = ring_buffer__new(map_filter_log, hdl_filters_rb_event, &cfg, NULL);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_IP_RANGE_DROP
|
||||
int map_range_drop = FindMapFd(prog, "map_range_drop");
|
||||
int map_range_drop = get_map_fd(prog, "map_range_drop");
|
||||
|
||||
if (map_range_drop < 0)
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "[WARNING] Failed to find 'map_range_drop' BPF map. IP range drops will be disabled...");
|
||||
log_msg(&cfg, 1, 0, "[WARNING] Failed to find 'map_range_drop' BPF map. IP range drops will be disabled...");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMsg(&cfg, 3, 0, "map_range_drop FD => %d.", map_range_drop);
|
||||
log_msg(&cfg, 3, 0, "map_range_drop FD => %d.", map_range_drop);
|
||||
}
|
||||
#endif
|
||||
|
||||
LogMsg(&cfg, 3, 0, "map_stats FD => %d.", map_stats);
|
||||
log_msg(&cfg, 3, 0, "map_stats FD => %d.", map_stats);
|
||||
|
||||
// Pin BPF maps to file system if we need to.
|
||||
if (cfg.pin_maps)
|
||||
{
|
||||
LogMsg(&cfg, 2, 0, "Pinning BPF maps...");
|
||||
log_msg(&cfg, 2, 0, "Pinning BPF maps...");
|
||||
|
||||
struct bpf_object* obj = GetBpfObj(prog);
|
||||
struct bpf_object* obj = get_bpf_obj(prog);
|
||||
|
||||
// There are times where the BPF maps from the last run weren't cleaned up properly.
|
||||
// So it's best to attempt to unpin the maps before pinning while ignoring errors.
|
||||
UnpinNeededMaps(&cfg, obj, 1);
|
||||
unpin_needed_maps(&cfg, obj, 1);
|
||||
|
||||
// Pin the block maps.
|
||||
if ((ret = PinBpfMap(obj, XDP_MAP_PIN_DIR, "map_block")) != 0)
|
||||
if ((ret = pin_bpf_map(obj, XDP_MAP_PIN_DIR, "map_block")) != 0)
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "[WARNING] Failed to pin 'map_block' to file system (%d)...", ret);
|
||||
log_msg(&cfg, 1, 0, "[WARNING] Failed to pin 'map_block' to file system (%d)...", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMsg(&cfg, 3, 0, "BPF map 'map_block' pinned to '%s/map_block'.", XDP_MAP_PIN_DIR);
|
||||
log_msg(&cfg, 3, 0, "BPF map 'map_block' pinned to '%s/map_block'.", XDP_MAP_PIN_DIR);
|
||||
}
|
||||
|
||||
if ((ret = PinBpfMap(obj, XDP_MAP_PIN_DIR, "map_block6")) != 0)
|
||||
if ((ret = pin_bpf_map(obj, XDP_MAP_PIN_DIR, "map_block6")) != 0)
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "[WARNING] Failed to pin 'map_block6' to file system (%d)...", ret);
|
||||
log_msg(&cfg, 1, 0, "[WARNING] Failed to pin 'map_block6' to file system (%d)...", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMsg(&cfg, 3, 0, "BPF map 'map_block6' pinned to '%s/map_block6'.", XDP_MAP_PIN_DIR);
|
||||
log_msg(&cfg, 3, 0, "BPF map 'map_block6' pinned to '%s/map_block6'.", XDP_MAP_PIN_DIR);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IP_RANGE_DROP
|
||||
// Pin the IPv4 range drop map.
|
||||
if ((ret = PinBpfMap(obj, XDP_MAP_PIN_DIR, "map_range_drop")) != 0)
|
||||
if ((ret = pin_bpf_map(obj, XDP_MAP_PIN_DIR, "map_range_drop")) != 0)
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "[WARNING] Failed to pin 'map_range_drop' to file system (%d)...", ret);
|
||||
log_msg(&cfg, 1, 0, "[WARNING] Failed to pin 'map_range_drop' to file system (%d)...", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMsg(&cfg, 3, 0, "BPF map 'map_range_drop' pinned to '%s/map_range_drop'.", XDP_MAP_PIN_DIR);
|
||||
log_msg(&cfg, 3, 0, "BPF map 'map_range_drop' pinned to '%s/map_range_drop'.", XDP_MAP_PIN_DIR);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FILTERS
|
||||
// Pin the filters map.
|
||||
if ((ret = PinBpfMap(obj, XDP_MAP_PIN_DIR, "map_filters")) != 0)
|
||||
if ((ret = pin_bpf_map(obj, XDP_MAP_PIN_DIR, "map_filters")) != 0)
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "[WARNING] Failed to pin 'map_filters' to file system (%d)...", ret);
|
||||
log_msg(&cfg, 1, 0, "[WARNING] Failed to pin 'map_filters' to file system (%d)...", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMsg(&cfg, 3, 0, "BPF map 'map_filters' pinned to '%s/map_filters'.", XDP_MAP_PIN_DIR);
|
||||
log_msg(&cfg, 3, 0, "BPF map 'map_filters' pinned to '%s/map_filters'.", XDP_MAP_PIN_DIR);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_FILTER_LOGGING
|
||||
// Pin the filters log map.
|
||||
if ((ret = PinBpfMap(obj, XDP_MAP_PIN_DIR, "map_filter_log")) != 0)
|
||||
if ((ret = pin_bpf_map(obj, XDP_MAP_PIN_DIR, "map_filter_log")) != 0)
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "[WARNING] Failed to pin 'map_filter_log' to file system (%d)...", ret);
|
||||
log_msg(&cfg, 1, 0, "[WARNING] Failed to pin 'map_filter_log' to file system (%d)...", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMsg(&cfg, 3, 0, "BPF map 'map_filter_log' pinned to '%s/map_filter_log'.", XDP_MAP_PIN_DIR);
|
||||
log_msg(&cfg, 3, 0, "BPF map 'map_filter_log' pinned to '%s/map_filter_log'.", XDP_MAP_PIN_DIR);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_FILTERS
|
||||
LogMsg(&cfg, 2, 0, "Updating filters...");
|
||||
log_msg(&cfg, 2, 0, "Updating filters...");
|
||||
|
||||
// Update filters.
|
||||
UpdateFilters(map_filters, &cfg);
|
||||
update_filters(map_filters, &cfg);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_IP_RANGE_DROP
|
||||
if (map_range_drop > -1)
|
||||
{
|
||||
LogMsg(&cfg, 2, 0, "Updating IP drop ranges...");
|
||||
log_msg(&cfg, 2, 0, "Updating IP drop ranges...");
|
||||
|
||||
// Update IP range drops.
|
||||
UpdateRangeDrops(map_range_drop, &cfg);
|
||||
update_range_drops(map_range_drop, &cfg);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Signal.
|
||||
signal(SIGINT, SignalHndl);
|
||||
signal(SIGTERM, SignalHndl);
|
||||
signal(SIGINT, hdl_signal);
|
||||
signal(SIGTERM, hdl_signal);
|
||||
|
||||
// Receive CPU count for stats map parsing.
|
||||
int cpus = get_nprocs_conf();
|
||||
|
||||
LogMsg(&cfg, 4, 0, "Retrieved %d CPUs on host.", cpus);
|
||||
log_msg(&cfg, 4, 0, "Retrieved %d CPUs on host.", cpus);
|
||||
|
||||
unsigned int end_time = (cmd.time > 0) ? time(NULL) + cmd.time : 0;
|
||||
unsigned int end_time = (cli.time > 0) ? time(NULL) + cli.time : 0;
|
||||
|
||||
// Create last updated variables.
|
||||
time_t last_update_check = time(NULL);
|
||||
@@ -398,27 +424,39 @@ int main(int argc, char *argv[])
|
||||
// Check for auto-update.
|
||||
if (cfg.update_time > 0 && (cur_time - last_update_check) > cfg.update_time)
|
||||
{
|
||||
log_msg(&cfg, 6, 0, "Checking for config updates...");
|
||||
|
||||
// Check if config file have been modified
|
||||
if (stat(cmd.cfg_file, &conf_stat) == 0 && conf_stat.st_mtime > last_config_check) {
|
||||
if (stat(cli.cfg_file, &conf_stat) == 0 && conf_stat.st_mtime > last_config_check) {
|
||||
log_msg(&cfg, 3, 0, "Config file change detected during update. Attempting to reload config...");
|
||||
|
||||
// Reload config.
|
||||
if ((ret = LoadConfig(&cfg, cmd.cfg_file, &cfg_overrides)) != 0)
|
||||
if ((ret = load_cfg(&cfg, cli.cfg_file, 1, &cfg_overrides)) != 0)
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "[WARNING] Failed to load config after update check (%d)...\n", ret);
|
||||
log_msg(&cfg, 1, 0, "[WARNING] Failed to load config after update check (%d)...\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_msg(&cfg, 4, 0, "Config reloaded successfully...");
|
||||
|
||||
#ifdef ENABLE_FILTERS
|
||||
// Update filters.
|
||||
UpdateFilters(map_filters, &cfg);
|
||||
#endif
|
||||
|
||||
// Update last check timer
|
||||
last_config_check = time(NULL);
|
||||
|
||||
// Make sure we set doing stats if needed.
|
||||
// Make sure we set doing_stats properly.
|
||||
if (!cfg.no_stats && !doing_stats)
|
||||
{
|
||||
doing_stats = 1;
|
||||
}
|
||||
else if (cfg.no_stats && doing_stats)
|
||||
{
|
||||
doing_stats = 0;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_FILTERS
|
||||
// Update filters.
|
||||
update_filters(map_filters, &cfg);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Update last check timer
|
||||
last_config_check = time(NULL);
|
||||
}
|
||||
|
||||
// Update last updated variable.
|
||||
@@ -428,14 +466,14 @@ int main(int argc, char *argv[])
|
||||
// Calculate and display stats if enabled.
|
||||
if (!cfg.no_stats)
|
||||
{
|
||||
if (CalculateStats(map_stats, cpus, cfg.stats_per_second))
|
||||
if (calc_stats(map_stats, cpus, cfg.stats_per_second))
|
||||
{
|
||||
LogMsg(&cfg, 1, 0, "[WARNING] Failed to calculate packet stats. Stats map FD => %d...\n", map_stats);
|
||||
log_msg(&cfg, 1, 0, "[WARNING] Failed to calculate packet stats. Stats map FD => %d...\n", map_stats);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(ENABLE_FILTERS) && defined(ENABLE_FILTER_LOGGING)
|
||||
PollFiltersRb(rb);
|
||||
poll_filters_rb(rb);
|
||||
#endif
|
||||
|
||||
usleep(sleep_time);
|
||||
@@ -443,7 +481,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
LogMsg(&cfg, 2, 0, "Cleaning up...");
|
||||
log_msg(&cfg, 2, 0, "Cleaning up...");
|
||||
|
||||
#if defined(ENABLE_FILTERS) && defined(ENABLE_FILTER_LOGGING)
|
||||
if (rb)
|
||||
@@ -452,28 +490,38 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
// Detach XDP program.
|
||||
if (AttachXdp(prog, &mode_used, ifidx, 1, cmd.skb, cmd.offload))
|
||||
// Detach XDP program from interfaces.
|
||||
for (int i = 0; i < MAX_INTERFACES; i++)
|
||||
{
|
||||
LogMsg(&cfg, 0, 1, "[ERROR] Failed to detach XDP program from interface '%s'.\n", cfg.interface);
|
||||
const char* interface = cfg.interfaces[i];
|
||||
|
||||
return EXIT_FAILURE;
|
||||
if (!interface)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
char* mode_used = NULL;
|
||||
|
||||
if (attach_xdp(prog, &mode_used, if_idx[i], 1, cli.skb, cli.offload))
|
||||
{
|
||||
log_msg(&cfg, 0, 0, "[WARNING] Failed to detach XDP program from interface '%s'.\n", interface);
|
||||
}
|
||||
}
|
||||
|
||||
// Unpin maps from file system.
|
||||
if (cfg.pin_maps)
|
||||
{
|
||||
LogMsg(&cfg, 2, 0, "Un-pinning BPF maps from file system...");
|
||||
log_msg(&cfg, 2, 0, "Un-pinning BPF maps from file system...");
|
||||
|
||||
struct bpf_object* obj = GetBpfObj(prog);
|
||||
struct bpf_object* obj = get_bpf_obj(prog);
|
||||
|
||||
UnpinNeededMaps(&cfg, obj, 0);
|
||||
unpin_needed_maps(&cfg, obj, 0);
|
||||
}
|
||||
|
||||
// Lastly, close the XDP program.
|
||||
xdp_program__close(prog);
|
||||
|
||||
LogMsg(&cfg, 1, 0, "Exiting.\n");
|
||||
log_msg(&cfg, 1, 0, "Exiting.\n");
|
||||
|
||||
// Exit program successfully.
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <loader/utils/cmdline.h>
|
||||
#include <loader/utils/cli.h>
|
||||
|
||||
const struct option opts[] =
|
||||
{
|
||||
@@ -22,13 +22,13 @@ const struct option opts[] =
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the command line and stores values in the cmdline structure.
|
||||
* Parses the command line and stores values in the cli structure.
|
||||
*
|
||||
* @param cmd A pointer to the cmdline structure.
|
||||
* @param cli A pointer to the cli structure.
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
void ParseCommandLine(cmdline_t *cmd, int argc, char *argv[])
|
||||
void parse_cli(cli_t *cli, int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
|
||||
@@ -37,72 +37,72 @@ void ParseCommandLine(cmdline_t *cmd, int argc, char *argv[])
|
||||
switch (c)
|
||||
{
|
||||
case 'c':
|
||||
cmd->cfg_file = optarg;
|
||||
cli->cfg_file = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
cmd->offload = 1;
|
||||
cli->offload = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 's':
|
||||
cmd->skb = 1;
|
||||
cli->skb = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 't':
|
||||
cmd->time = atoi(optarg);
|
||||
cli->time = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
cmd->list = 1;
|
||||
cli->list = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
cmd->help = 1;
|
||||
cli->help = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
cmd->verbose = atoi(optarg);
|
||||
cli->verbose = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 0:
|
||||
cmd->log_file = optarg;
|
||||
cli->log_file = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
cmd->interface = optarg;
|
||||
cli->interface = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
cmd->pin_maps = atoi(optarg);
|
||||
cli->pin_maps = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
cmd->update_time = atoi(optarg);
|
||||
cli->update_time = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
cmd->no_stats = atoi(optarg);
|
||||
cli->no_stats = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
cmd->stats_per_second = atoi(optarg);
|
||||
cli->stats_per_second = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cmd->stdout_update_time = atoi(optarg);
|
||||
cli->stdout_update_time = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
|
||||
struct cmdline
|
||||
struct cli
|
||||
{
|
||||
char *cfg_file;
|
||||
unsigned int offload : 1;
|
||||
@@ -21,6 +21,6 @@ struct cmdline
|
||||
int no_stats;
|
||||
int stats_per_second;
|
||||
int stdout_update_time;
|
||||
} typedef cmdline_t;
|
||||
} typedef cli_t;
|
||||
|
||||
void ParseCommandLine(cmdline_t *cmd, int argc, char *argv[]);
|
||||
void parse_cli(cli_t *cli, int argc, char *argv[]);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,19 +13,93 @@
|
||||
|
||||
#define CONFIG_DEFAULT_PATH "/etc/xdpfw/xdpfw.conf"
|
||||
|
||||
struct filter_rule_ip_opts
|
||||
{
|
||||
char* src_ip;
|
||||
char* dst_ip;
|
||||
|
||||
char* src_ip6;
|
||||
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;
|
||||
char *log_file;
|
||||
char *interface;
|
||||
unsigned int pin_maps : 1;
|
||||
int update_time;
|
||||
unsigned int no_stats : 1;
|
||||
unsigned int stats_per_second : 1;
|
||||
int stdout_update_time;
|
||||
|
||||
filter_t filters[MAX_FILTERS];
|
||||
const char* drop_ranges[MAX_IP_RANGES];
|
||||
int interfaces_cnt;
|
||||
char* interfaces[MAX_INTERFACES];
|
||||
|
||||
int filters_cnt;
|
||||
filter_rule_cfg_t filters[MAX_FILTERS];
|
||||
|
||||
int drop_ranges_cnt;
|
||||
char* drop_ranges[MAX_IP_RANGES];
|
||||
} typedef config__t; // config_t is taken by libconfig -.-
|
||||
|
||||
struct config_overrides
|
||||
@@ -40,21 +114,21 @@ struct config_overrides
|
||||
int stdout_update_time;
|
||||
} typedef config_overrides_t;
|
||||
|
||||
void SetCfgDefaults(config__t *cfg);
|
||||
void SetFilterDefaults(filter_t* filter);
|
||||
void set_cfg_defaults(config__t *cfg);
|
||||
void set_filter_defaults(filter_rule_cfg_t* filter);
|
||||
|
||||
void PrintConfig(config__t* cfg);
|
||||
void PrintFilter(filter_t* filter, int idx);
|
||||
void print_cfg(config__t* cfg);
|
||||
void print_filter(filter_rule_cfg_t* filter, int idx);
|
||||
|
||||
int LoadConfig(config__t *cfg, const char* cfg_file, config_overrides_t* overrides);
|
||||
int SaveCfg(config__t* cfg, const char* file_path);
|
||||
int load_cfg(config__t *cfg, const char* cfg_file, int load_defaults, config_overrides_t* overrides);
|
||||
int save_cfg(config__t* cfg, const char* file_path);
|
||||
|
||||
int OpenCfg(FILE** file, const char *file_name);
|
||||
int CloseCfg(FILE* file);
|
||||
int ReadCfg(FILE* file, char** buffer);
|
||||
int ParseCfg(config__t *cfg, const char* data, config_overrides_t* overrides);
|
||||
int open_cfg(FILE** file, const char *file_name);
|
||||
int close_cfg(FILE* file);
|
||||
int read_cfg(FILE* file, char** buffer);
|
||||
int parse_cfg(config__t *cfg, const char* data, config_overrides_t* overrides);
|
||||
|
||||
int GetNextAvailableFilterIndex(config__t* cfg);
|
||||
int GetNextAvailableIpDropRangeIndex(config__t* cfg);
|
||||
int get_next_filter_idx(config__t* cfg);
|
||||
int get_next_ip_drop_range_idx(config__t* cfg);
|
||||
|
||||
#include <loader/utils/logging.h>
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void PrintHelpMenu()
|
||||
void print_help_menu()
|
||||
{
|
||||
printf("Usage: xdpfw [OPTIONS]\n\n");
|
||||
|
||||
@@ -31,7 +31,7 @@ void PrintHelpMenu()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void SignalHndl(int code)
|
||||
void hdl_signal(int code)
|
||||
{
|
||||
cont = 0;
|
||||
}
|
||||
@@ -43,7 +43,7 @@ void SignalHndl(int code)
|
||||
*
|
||||
* @return Returns an IP structure with IP and CIDR.
|
||||
*/
|
||||
ip_range_t ParseIpCidr(const char *ip)
|
||||
ip_range_t parse_ip_range(const char *ip)
|
||||
{
|
||||
ip_range_t ret = {0};
|
||||
ret.cidr = 32;
|
||||
@@ -52,7 +52,7 @@ ip_range_t ParseIpCidr(const char *ip)
|
||||
strncpy(ip_copy, ip, sizeof(ip_copy) - 1);
|
||||
ip_copy[sizeof(ip_copy) - 1] = '\0';
|
||||
|
||||
char *token = strtok((char *) ip_copy, "/");
|
||||
char *token = strtok(ip_copy, "/");
|
||||
|
||||
if (token)
|
||||
{
|
||||
@@ -76,7 +76,7 @@ ip_range_t ParseIpCidr(const char *ip)
|
||||
*
|
||||
* @return The protocol string.
|
||||
*/
|
||||
const char* GetProtocolStrById(int id)
|
||||
const char* get_protocol_str_by_id(int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
@@ -98,7 +98,7 @@ const char* GetProtocolStrById(int id)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void PrintToolInfo()
|
||||
void print_tool_info()
|
||||
{
|
||||
printf(
|
||||
" __ ______ ____ _____ _ _ _ \n"
|
||||
@@ -115,7 +115,7 @@ void PrintToolInfo()
|
||||
*
|
||||
* @return The current nanoseconds since the system last booted.
|
||||
*/
|
||||
u64 GetBootNanoTime()
|
||||
u64 get_boot_nano_time()
|
||||
{
|
||||
struct sysinfo sys;
|
||||
sysinfo(&sys);
|
||||
|
||||
@@ -17,9 +17,9 @@ struct ip_range
|
||||
|
||||
extern int cont;
|
||||
|
||||
void PrintHelpMenu();
|
||||
void SignalHndl(int code);
|
||||
ip_range_t ParseIpCidr(const char* ip);
|
||||
const char* GetProtocolStrById(int id);
|
||||
void PrintToolInfo();
|
||||
u64 GetBootNanoTime();
|
||||
void print_help_menu();
|
||||
void hdl_signal(int code);
|
||||
ip_range_t parse_ip_range(const char* ip);
|
||||
const char* get_protocol_str_by_id(int id);
|
||||
void print_tool_info();
|
||||
u64 get_boot_nano_time();
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static void LogMsgRaw(int req_lvl, int cur_lvl, int error, const char* log_path, const char* msg, va_list args)
|
||||
static void log_msg_raw(int req_lvl, int cur_lvl, int error, const char* log_path, const char* msg, va_list args)
|
||||
{
|
||||
if (cur_lvl < req_lvl)
|
||||
{
|
||||
@@ -86,7 +86,7 @@ static void LogMsgRaw(int req_lvl, int cur_lvl, int error, const char* log_path,
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a log message using LogMsgRaw().
|
||||
* Prints a log message using log_msg_raw().
|
||||
*
|
||||
* @param cfg A pointer to the config structure.
|
||||
* @param req_lvl The required level for this message.
|
||||
@@ -95,12 +95,12 @@ static void LogMsgRaw(int req_lvl, int cur_lvl, int error, const char* log_path,
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void LogMsg(config__t* cfg, int req_lvl, int error, const char* msg, ...)
|
||||
void log_msg(config__t* cfg, int req_lvl, int error, const char* msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
|
||||
LogMsgRaw(req_lvl, cfg->verbose, error, (const char*)cfg->log_file, msg, args);
|
||||
log_msg_raw(req_lvl, cfg->verbose, error, (const char*)cfg->log_file, msg, args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
@@ -112,7 +112,7 @@ void LogMsg(config__t* cfg, int req_lvl, int error, const char* msg, ...)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void PollFiltersRb(struct ring_buffer* rb)
|
||||
void poll_filters_rb(struct ring_buffer* rb)
|
||||
{
|
||||
if (rb)
|
||||
{
|
||||
@@ -129,12 +129,12 @@ void PollFiltersRb(struct ring_buffer* rb)
|
||||
*
|
||||
* @return 0 on success or 1 on failure.
|
||||
*/
|
||||
int HandleRbEvent(void* ctx, void* data, size_t sz)
|
||||
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)
|
||||
{
|
||||
@@ -161,9 +161,9 @@ int HandleRbEvent(void* ctx, void* data, size_t sz)
|
||||
action = "Passed";
|
||||
}
|
||||
|
||||
const char* protocol_str = GetProtocolStrById(e->protocol);
|
||||
const char* protocol_str = get_protocol_str_by_id(e->protocol);
|
||||
|
||||
LogMsg(cfg, 0, 0, "[FILTER %d] %s %s packet '%s:%d' => '%s:%d' (PPS => %llu, BPS => %llu, Filter Block Time => %llu)...", e->filter_id + 1, action, protocol_str, src_ip_str, htons(e->src_port), dst_ip_str, htons(e->dst_port), e->pps, e->bps, filter->block_time);
|
||||
log_msg(cfg, 0, 0, "[FILTER %d] %s %s packet '%s:%d' => '%s:%d' (PPS => %llu, BPS => %llu, Filter Block Time => %llu, length => %d)...", e->filter_id + 1, action, protocol_str, src_ip_str, htons(e->src_port), dst_ip_str, htons(e->dst_port), e->pps, e->bps, filter->block_time, e->length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
extern int doing_stats;
|
||||
|
||||
void LogMsg(config__t* cfg, int req_lvl, int error, const char* msg, ...);
|
||||
void log_msg(config__t* cfg, int req_lvl, int error, const char* msg, ...);
|
||||
|
||||
void PollFiltersRb(struct ring_buffer* rb);
|
||||
int HandleRbEvent(void* ctx, void* data, size_t sz);
|
||||
void poll_filters_rb(struct ring_buffer* rb);
|
||||
int hdl_filters_rb_event(void* ctx, void* data, size_t sz);
|
||||
@@ -15,7 +15,7 @@ u64 last_passed = 0;
|
||||
*
|
||||
* @return 0 on success or 1 on failure.
|
||||
*/
|
||||
int CalculateStats(int map_stats, int cpus, int per_second)
|
||||
int calc_stats(int map_stats, int cpus, int per_second)
|
||||
{
|
||||
u32 key = 0;
|
||||
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
int CalculateStats(int map_stats, int cpus, int per_second);
|
||||
int calc_stats(int map_stats, int cpus, int per_second);
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* @return The map's FD.
|
||||
*/
|
||||
int FindMapFd(struct xdp_program *prog, const char *map_name)
|
||||
int get_map_fd(struct xdp_program *prog, const char *map_name)
|
||||
{
|
||||
int fd = -1;
|
||||
|
||||
@@ -45,7 +45,7 @@ int FindMapFd(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;
|
||||
}
|
||||
@@ -57,11 +57,11 @@ static int LibBPFSilent(enum libbpf_print_level level, const char *format, va_li
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void SetLibBPFLogMode(int silent)
|
||||
void set_libbpf_log_mode(int silent)
|
||||
{
|
||||
if (silent)
|
||||
{
|
||||
libbpf_set_print(LibBPFSilent);
|
||||
libbpf_set_print(libbpf_silent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ void SetLibBPFLogMode(int silent)
|
||||
*
|
||||
* @return XDP program structure (pointer) or NULL.
|
||||
*/
|
||||
struct xdp_program *LoadBpfObj(const char *file_name)
|
||||
struct xdp_program *load_bpf_obj(const char *file_name)
|
||||
{
|
||||
struct xdp_program *prog = xdp_program__open_file(file_name, "xdp_prog", NULL);
|
||||
|
||||
@@ -92,7 +92,7 @@ struct xdp_program *LoadBpfObj(const char *file_name)
|
||||
*
|
||||
* @return The BPF object.
|
||||
*/
|
||||
struct bpf_object* GetBpfObj(struct xdp_program* prog)
|
||||
struct bpf_object* get_bpf_obj(struct xdp_program* prog)
|
||||
{
|
||||
return xdp_program__bpf_obj(prog);
|
||||
}
|
||||
@@ -109,7 +109,7 @@ struct bpf_object* GetBpfObj(struct xdp_program* prog)
|
||||
*
|
||||
* @return 0 on success and 1 on error.
|
||||
*/
|
||||
int AttachXdp(struct xdp_program *prog, char** mode, int ifidx, int detach, int force_skb, int force_offload)
|
||||
int attach_xdp(struct xdp_program *prog, char** mode, int ifidx, int detach, int force_skb, int force_offload)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -197,7 +197,7 @@ int AttachXdp(struct xdp_program *prog, char** mode, int ifidx, int detach, int
|
||||
*
|
||||
* @return 0 on success or the error value of bpf_map_delete_elem().
|
||||
*/
|
||||
int DeleteFilter(int map_filters, u32 idx)
|
||||
int delete_filter(int map_filters, u32 idx)
|
||||
{
|
||||
return bpf_map_delete_elem(map_filters, &idx);
|
||||
}
|
||||
@@ -209,11 +209,11 @@ int DeleteFilter(int map_filters, u32 idx)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void DeleteFilters(int map_filters)
|
||||
void delete_filters(int map_filters)
|
||||
{
|
||||
for (int i = 0; i < MAX_FILTERS; i++)
|
||||
{
|
||||
DeleteFilter(map_filters, i);
|
||||
delete_filter(map_filters, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,21 +221,239 @@ void DeleteFilters(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 UpdateFilter(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);
|
||||
@@ -249,19 +467,19 @@ int UpdateFilter(int map_filters, filter_t* filter, int idx)
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
void UpdateFilters(int map_filters, config__t *cfg)
|
||||
void update_filters(int map_filters, config__t *cfg)
|
||||
{
|
||||
int ret;
|
||||
int cur_idx = 0;
|
||||
|
||||
// Add a filter to the filter maps.
|
||||
for (int i = 0; i < MAX_FILTERS; i++)
|
||||
for (int i = 0; i < cfg->filters_cnt; i++)
|
||||
{
|
||||
// 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.
|
||||
DeleteFilter(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.
|
||||
if (!filter->set || !filter->enabled)
|
||||
@@ -270,7 +488,7 @@ void UpdateFilters(int map_filters, config__t *cfg)
|
||||
}
|
||||
|
||||
// Attempt to update filter.
|
||||
if ((ret = UpdateFilter(map_filters, filter, cur_idx)) != 0)
|
||||
if ((ret = update_filter(map_filters, filter, cur_idx)) != 0)
|
||||
{
|
||||
fprintf(stderr, "[WARNING] Failed to update filter #%d due to BPF update error (%d)...\n", cur_idx, ret);
|
||||
|
||||
@@ -290,7 +508,7 @@ void UpdateFilters(int map_filters, config__t *cfg)
|
||||
*
|
||||
* @return 0 on success or value of bpf_map__pin() on error.
|
||||
*/
|
||||
int PinBpfMap(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)
|
||||
{
|
||||
struct bpf_map* map = bpf_object__find_map_by_name(obj, map_name);
|
||||
|
||||
@@ -314,7 +532,7 @@ int PinBpfMap(struct bpf_object* obj, const char* pin_dir, const char* map_name)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int UnpinBpfMap(struct bpf_object* obj, const char* pin_dir, const char* map_name)
|
||||
int unpin_bpf_map(struct bpf_object* obj, const char* pin_dir, const char* map_name)
|
||||
{
|
||||
struct bpf_map* map = bpf_object__find_map_by_name(obj, map_name);
|
||||
|
||||
@@ -337,7 +555,7 @@ int UnpinBpfMap(struct bpf_object* obj, const char* pin_dir, const char* map_nam
|
||||
*
|
||||
* @return The map FD or -1 on error.
|
||||
*/
|
||||
int GetMapPinFd(const char* pin_dir, const char* map_name)
|
||||
int get_map_fd_pin(const char* pin_dir, const char* map_name)
|
||||
{
|
||||
char full_path[255];
|
||||
snprintf(full_path, sizeof(full_path), "%s/%s", pin_dir, map_name);
|
||||
@@ -353,7 +571,7 @@ int GetMapPinFd(const char* pin_dir, const char* map_name)
|
||||
*
|
||||
* @return 0 on success or error value of bpf_map_delete_elem().
|
||||
*/
|
||||
int DeleteBlock(int map_block, u32 ip)
|
||||
int delete_block(int map_block, u32 ip)
|
||||
{
|
||||
return bpf_map_delete_elem(map_block, &ip);
|
||||
}
|
||||
@@ -367,7 +585,7 @@ int DeleteBlock(int map_block, u32 ip)
|
||||
*
|
||||
* @return 0 on success or error value of bpf_map_update_elem().
|
||||
*/
|
||||
int AddBlock(int map_block, u32 ip, u64 expires)
|
||||
int add_block(int map_block, u32 ip, u64 expires)
|
||||
{
|
||||
return bpf_map_update_elem(map_block, &ip, &expires, BPF_ANY);
|
||||
}
|
||||
@@ -380,7 +598,7 @@ int AddBlock(int map_block, u32 ip, u64 expires)
|
||||
*
|
||||
* @return 0 on success or error value of bpf_map_delete_elem().
|
||||
*/
|
||||
int DeleteBlock6(int map_block6, u128 ip)
|
||||
int delete_block6(int map_block6, u128 ip)
|
||||
{
|
||||
return bpf_map_delete_elem(map_block6, &ip);
|
||||
}
|
||||
@@ -394,7 +612,7 @@ int DeleteBlock6(int map_block6, u128 ip)
|
||||
*
|
||||
* @return 0 on success or error value of bpf_map_update_elem().
|
||||
*/
|
||||
int AddBlock6(int map_block6, u128 ip, u64 expires)
|
||||
int add_block6(int map_block6, u128 ip, u64 expires)
|
||||
{
|
||||
return bpf_map_update_elem(map_block6, &ip, &expires, BPF_ANY);
|
||||
}
|
||||
@@ -408,7 +626,7 @@ int AddBlock6(int map_block6, u128 ip, u64 expires)
|
||||
*
|
||||
* @return 0 on success or error value of bpf_map_delete_elem().
|
||||
*/
|
||||
int DeleteRangeDrop(int map_range_drop, u32 net, u8 cidr)
|
||||
int delete_range_drop(int map_range_drop, u32 net, u8 cidr)
|
||||
{
|
||||
u32 bit_mask = ( ~( (1 << (32 - cidr) ) - 1) );
|
||||
u32 start = net & bit_mask;
|
||||
@@ -429,7 +647,7 @@ int DeleteRangeDrop(int map_range_drop, u32 net, u8 cidr)
|
||||
*
|
||||
* @return 0 on success or error value of bpf_map_update_elem().
|
||||
*/
|
||||
int AddRangeDrop(int map_range_drop, u32 net, u8 cidr)
|
||||
int add_range_drop(int map_range_drop, u32 net, u8 cidr)
|
||||
{
|
||||
u32 bit_mask = ( ~( (1 << (32 - cidr) ) - 1) );
|
||||
u32 start = net & bit_mask;
|
||||
@@ -451,7 +669,7 @@ int AddRangeDrop(int map_range_drop, u32 net, u8 cidr)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void UpdateRangeDrops(int map_range_drop, config__t* cfg)
|
||||
void update_range_drops(int map_range_drop, config__t* cfg)
|
||||
{
|
||||
for (int i = 0; i < MAX_IP_RANGES; i++)
|
||||
{
|
||||
@@ -463,8 +681,8 @@ void UpdateRangeDrops(int map_range_drop, config__t* cfg)
|
||||
}
|
||||
|
||||
// Parse IP range string and return network IP and CIDR.
|
||||
ip_range_t t = ParseIpCidr(range);
|
||||
ip_range_t t = parse_ip_range(range);
|
||||
|
||||
AddRangeDrop(map_range_drop, t.ip, t.cidr);
|
||||
add_range_drop(map_range_drop, t.ip, t.cidr);
|
||||
}
|
||||
}
|
||||
@@ -10,30 +10,30 @@
|
||||
#define XDP_OBJ_PATH "/etc/xdpfw/xdp_prog.o"
|
||||
#define XDP_MAP_PIN_DIR "/sys/fs/bpf/xdpfw"
|
||||
|
||||
int FindMapFd(struct xdp_program *prog, const char *map_name);
|
||||
void SetLibBPFLogMode(int silent);
|
||||
int get_map_fd(struct xdp_program *prog, const char *map_name);
|
||||
void set_libbpf_log_mode(int silent);
|
||||
|
||||
struct xdp_program *LoadBpfObj(const char *file_name);
|
||||
struct bpf_object* GetBpfObj(struct xdp_program* prog);
|
||||
struct xdp_program *load_bpf_obj(const char *file_name);
|
||||
struct bpf_object* get_bpf_obj(struct xdp_program* prog);
|
||||
|
||||
int AttachXdp(struct xdp_program *prog, char** mode, int ifidx, int detach, int force_skb, int force_offload);
|
||||
int attach_xdp(struct xdp_program *prog, char** mode, int ifidx, int detach, int force_skb, int force_offload);
|
||||
|
||||
int DeleteFilter(int map_filters, u32 idx);
|
||||
void DeleteFilters(int map_filters);
|
||||
int delete_filter(int map_filters, u32 idx);
|
||||
void delete_filters(int map_filters);
|
||||
|
||||
int UpdateFilter(int map_filters, filter_t* filter, int idx);
|
||||
void UpdateFilters(int map_filters, config__t *cfg);
|
||||
int update_filter(int map_filters, filter_rule_cfg_t* filter, int idx);
|
||||
void update_filters(int map_filters, config__t *cfg);
|
||||
|
||||
int PinBpfMap(struct bpf_object* obj, const char* pin_dir, const char* map_name);
|
||||
int UnpinBpfMap(struct bpf_object* obj, const char* pin_dir, const char* map_name);
|
||||
int GetMapPinFd(const char* pin_dir, const char* map_name);
|
||||
int pin_bpf_map(struct bpf_object* obj, const char* pin_dir, const char* map_name);
|
||||
int unpin_bpf_map(struct bpf_object* obj, const char* pin_dir, const char* map_name);
|
||||
int get_map_fd_pin(const char* pin_dir, const char* map_name);
|
||||
|
||||
int DeleteBlock(int map_block, u32 ip);
|
||||
int AddBlock(int map_block, u32 ip, u64 expires);
|
||||
int delete_block(int map_block, u32 ip);
|
||||
int add_block(int map_block, u32 ip, u64 expires);
|
||||
|
||||
int DeleteBlock6(int map_block6, u128 ip);
|
||||
int AddBlock6(int map_block6, u128 ip, u64 expires);
|
||||
int delete_block6(int map_block6, u128 ip);
|
||||
int add_block6(int map_block6, u128 ip, u64 expires);
|
||||
|
||||
int DeleteRangeDrop(int map_range_drop, u32 net, u8 cidr);
|
||||
int AddRangeDrop(int map_range_drop, u32 net, u8 cidr);
|
||||
void UpdateRangeDrops(int map_range_drop, config__t* cfg);
|
||||
int delete_range_drop(int map_range_drop, u32 net, u8 cidr);
|
||||
int add_range_drop(int map_range_drop, u32 net, u8 cidr);
|
||||
void update_range_drops(int map_range_drop, config__t* cfg);
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <loader/utils/xdp.h>
|
||||
#include <loader/utils/config.h>
|
||||
|
||||
#include <rule_add/utils/cmdline.h>
|
||||
#include <rule_add/utils/cli.h>
|
||||
|
||||
// These are required due to being extern with Loader.
|
||||
// To Do: Figure out a way to not require the below without requiring separate object files.
|
||||
@@ -19,46 +19,46 @@ int main(int argc, char *argv[])
|
||||
int ret;
|
||||
|
||||
// Parse command line.
|
||||
cmdline_t cmd = {0};
|
||||
cmd.cfg_file = CONFIG_DEFAULT_PATH;
|
||||
cli_t cli = {0};
|
||||
cli.cfg_file = CONFIG_DEFAULT_PATH;
|
||||
|
||||
// We need to set integers for dynamic filters to -1 since we consider -1 as 'unset'.
|
||||
cmd.enabled = -1;
|
||||
cmd.action = -1;
|
||||
cmd.log = -1;
|
||||
cli.enabled = -1;
|
||||
cli.action = -1;
|
||||
cli.log = -1;
|
||||
|
||||
cmd.min_ttl = -1;
|
||||
cmd.max_ttl = -1;
|
||||
cmd.min_len = -1;
|
||||
cmd.max_len = -1;
|
||||
cmd.tos = -1;
|
||||
cli.min_ttl = -1;
|
||||
cli.max_ttl = -1;
|
||||
cli.min_len = -1;
|
||||
cli.max_len = -1;
|
||||
cli.tos = -1;
|
||||
|
||||
cmd.pps = -1;
|
||||
cmd.bps = -1;
|
||||
cli.pps = -1;
|
||||
cli.bps = -1;
|
||||
|
||||
cmd.tcp_enabled = -1;
|
||||
cmd.tcp_sport = -1;
|
||||
cmd.tcp_dport = -1;
|
||||
cmd.tcp_urg = -1;
|
||||
cmd.tcp_ack = -1;
|
||||
cmd.tcp_rst = -1;
|
||||
cmd.tcp_psh = -1;
|
||||
cmd.tcp_syn = -1;
|
||||
cmd.tcp_fin = -1;
|
||||
cmd.tcp_ece = -1;
|
||||
cmd.tcp_cwr = -1;
|
||||
cli.tcp_enabled = -1;
|
||||
cli.tcp_sport = -1;
|
||||
cli.tcp_dport = -1;
|
||||
cli.tcp_urg = -1;
|
||||
cli.tcp_ack = -1;
|
||||
cli.tcp_rst = -1;
|
||||
cli.tcp_psh = -1;
|
||||
cli.tcp_syn = -1;
|
||||
cli.tcp_fin = -1;
|
||||
cli.tcp_ece = -1;
|
||||
cli.tcp_cwr = -1;
|
||||
|
||||
cmd.udp_enabled = -1;
|
||||
cmd.udp_sport = -1;
|
||||
cmd.udp_dport = -1;
|
||||
cli.udp_enabled = -1;
|
||||
cli.udp_sport = -1;
|
||||
cli.udp_dport = -1;
|
||||
|
||||
cmd.icmp_enabled = -1;
|
||||
cmd.icmp_code = -1;
|
||||
cmd.icmp_type = -1;
|
||||
cli.icmp_enabled = -1;
|
||||
cli.icmp_code = -1;
|
||||
cli.icmp_type = -1;
|
||||
|
||||
ParseCommandLine(&cmd, argc, argv);
|
||||
parse_cli(&cli, argc, argv);
|
||||
|
||||
if (!cmd.help)
|
||||
if (!cli.help)
|
||||
{
|
||||
printf("Parsed command line...\n");
|
||||
}
|
||||
@@ -118,7 +118,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Check for config file path.
|
||||
if ((cmd.save || cmd.mode == 0) && (!cmd.cfg_file || strlen(cmd.cfg_file) < 1))
|
||||
if ((cli.save || cli.mode == 0) && (!cli.cfg_file || strlen(cli.cfg_file) < 1))
|
||||
{
|
||||
fprintf(stderr, "[ERROR] CFG file not specified or empty. This is required for filters mode or when saving config.\n");
|
||||
|
||||
@@ -128,11 +128,11 @@ int main(int argc, char *argv[])
|
||||
// Load config.
|
||||
config__t cfg = {0};
|
||||
|
||||
if (cmd.save || cmd.mode == 0)
|
||||
if (cli.save || cli.mode == 0)
|
||||
{
|
||||
if ((ret = LoadConfig(&cfg, cmd.cfg_file, NULL)) != 0)
|
||||
if ((ret = load_cfg(&cfg, cli.cfg_file, 1, NULL)) != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] Failed to load config at '%s' (%d)\n", cmd.cfg_file, ret);
|
||||
fprintf(stderr, "[ERROR] Failed to load config at '%s' (%d)\n", cli.cfg_file, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -141,12 +141,12 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Handle filters mode.
|
||||
if (cmd.mode == 0)
|
||||
if (cli.mode == 0)
|
||||
{
|
||||
printf("Using filters mode (0)...\n");
|
||||
|
||||
// Retrieve filters map FD.
|
||||
int map_filters = GetMapPinFd(XDP_MAP_PIN_DIR, "map_filters");
|
||||
int map_filters = get_map_fd_pin(XDP_MAP_PIN_DIR, "map_filters");
|
||||
|
||||
if (map_filters < 0)
|
||||
{
|
||||
@@ -158,21 +158,21 @@ int main(int argc, char *argv[])
|
||||
printf("Using 'map_filters' FD => %d...\n", map_filters);
|
||||
|
||||
// Create new base filter and set its defaults.
|
||||
filter_t new_filter = {0};
|
||||
SetFilterDefaults(&new_filter);
|
||||
filter_rule_cfg_t new_filter = {0};
|
||||
set_filter_defaults(&new_filter);
|
||||
|
||||
new_filter.set = 1;
|
||||
|
||||
// Determine what index we'll be storing this filter at.
|
||||
int idx = -1;
|
||||
|
||||
if (cmd.idx > 0)
|
||||
if (cli.idx > 0)
|
||||
{
|
||||
idx = cmd.idx - 1;
|
||||
idx = cli.idx - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
idx = GetNextAvailableFilterIndex(&cfg);
|
||||
idx = get_next_filter_idx(&cfg);
|
||||
}
|
||||
|
||||
if (idx < 0)
|
||||
@@ -183,211 +183,166 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Fill out new filter.
|
||||
if (cmd.enabled > -1)
|
||||
if (cli.enabled > -1)
|
||||
{
|
||||
new_filter.enabled = cmd.enabled;
|
||||
new_filter.enabled = cli.enabled;
|
||||
}
|
||||
|
||||
if (cmd.action > -1)
|
||||
if (cli.action > -1)
|
||||
{
|
||||
new_filter.action = cmd.action;
|
||||
new_filter.action = cli.action;
|
||||
}
|
||||
|
||||
if (cmd.log > -1)
|
||||
if (cli.log > -1)
|
||||
{
|
||||
new_filter.log = cmd.log;
|
||||
new_filter.log = cli.log;
|
||||
}
|
||||
|
||||
if (cmd.block_time > -1)
|
||||
if (cli.block_time > -1)
|
||||
{
|
||||
new_filter.block_time = cmd.block_time;
|
||||
new_filter.block_time = cli.block_time;
|
||||
}
|
||||
|
||||
if (cmd.src_ip)
|
||||
if (cli.src_ip)
|
||||
{
|
||||
ip_range_t range = ParseIpCidr(cmd.src_ip);
|
||||
|
||||
new_filter.src_ip = range.ip;
|
||||
new_filter.src_cidr = range.cidr;
|
||||
new_filter.ip.src_ip = cli.src_ip;
|
||||
}
|
||||
|
||||
if (cmd.dst_ip)
|
||||
if (cli.dst_ip)
|
||||
{
|
||||
ip_range_t range = ParseIpCidr(cmd.dst_ip);
|
||||
|
||||
new_filter.dst_ip = range.ip;
|
||||
new_filter.dst_cidr = range.cidr;
|
||||
new_filter.ip.dst_ip = cli.dst_ip;
|
||||
}
|
||||
|
||||
if (cmd.src_ip6)
|
||||
if (cli.src_ip6)
|
||||
{
|
||||
struct in6_addr addr;
|
||||
|
||||
if ((ret = inet_pton(AF_INET6, cmd.src_ip6, &addr)) != 1)
|
||||
{
|
||||
fprintf(stderr, "Failed to convert source IPv6 address to decimal (%d).\n", ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
new_filter.ip.src_ip6 = cli.src_ip6;
|
||||
}
|
||||
|
||||
memcpy(new_filter.src_ip6, addr.s6_addr, sizeof(new_filter.src_ip6));
|
||||
}
|
||||
|
||||
if (cmd.dst_ip6)
|
||||
if (cli.dst_ip6)
|
||||
{
|
||||
struct in6_addr addr;
|
||||
|
||||
if ((ret = inet_pton(AF_INET6, cmd.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));
|
||||
new_filter.ip.dst_ip6 = cli.dst_ip6;
|
||||
}
|
||||
|
||||
// To Do: See if I can create a macro for below.
|
||||
// As long as the naming convention lines up, it should be easily possible.
|
||||
if (cmd.pps > -1)
|
||||
if (cli.pps > -1)
|
||||
{
|
||||
new_filter.do_pps = 1;
|
||||
new_filter.pps = cmd.pps;
|
||||
new_filter.pps = cli.pps;
|
||||
}
|
||||
|
||||
if (cmd.bps > -1)
|
||||
if (cli.bps > -1)
|
||||
{
|
||||
new_filter.do_bps = 1;
|
||||
new_filter.bps = cmd.bps;
|
||||
new_filter.bps = cli.bps;
|
||||
}
|
||||
|
||||
if (cmd.min_ttl > -1)
|
||||
if (cli.min_ttl > -1)
|
||||
{
|
||||
new_filter.do_min_ttl = 1;
|
||||
new_filter.min_ttl = cmd.min_ttl;
|
||||
new_filter.ip.min_ttl = cli.min_ttl;
|
||||
}
|
||||
|
||||
if (cmd.max_ttl > -1)
|
||||
if (cli.max_ttl > -1)
|
||||
{
|
||||
new_filter.do_max_ttl = 1;
|
||||
new_filter.max_ttl = cmd.max_ttl;
|
||||
new_filter.ip.max_ttl = cli.max_ttl;
|
||||
}
|
||||
|
||||
if (cmd.min_len > -1)
|
||||
if (cli.min_len > -1)
|
||||
{
|
||||
new_filter.do_min_len = 1;
|
||||
new_filter.min_len = cmd.min_len;
|
||||
new_filter.ip.min_len = cli.min_len;
|
||||
}
|
||||
|
||||
if (cmd.max_len > -1)
|
||||
if (cli.max_len > -1)
|
||||
{
|
||||
new_filter.do_max_len = 1;
|
||||
new_filter.max_len = cmd.max_len;
|
||||
new_filter.ip.max_len = cli.max_len;
|
||||
}
|
||||
|
||||
if (cmd.tos > -1)
|
||||
if (cli.tos > -1)
|
||||
{
|
||||
new_filter.do_tos = 1;
|
||||
new_filter.tos = cmd.tos;
|
||||
new_filter.ip.tos = cli.tos;
|
||||
}
|
||||
|
||||
if (cmd.tcp_enabled > -1)
|
||||
if (cli.tcp_enabled > -1)
|
||||
{
|
||||
new_filter.tcpopts.enabled = cmd.tcp_enabled;
|
||||
new_filter.tcp.enabled = cli.tcp_enabled;
|
||||
}
|
||||
|
||||
if (cmd.tcp_sport > -1)
|
||||
if (cli.tcp_sport > -1)
|
||||
{
|
||||
new_filter.tcpopts.do_sport = 1;
|
||||
new_filter.tcpopts.sport = cmd.tcp_sport;
|
||||
new_filter.tcp.sport = cli.tcp_sport;
|
||||
}
|
||||
|
||||
if (cmd.tcp_dport > -1)
|
||||
if (cli.tcp_dport > -1)
|
||||
{
|
||||
new_filter.tcpopts.do_dport = 1;
|
||||
new_filter.tcpopts.dport = cmd.tcp_dport;
|
||||
new_filter.tcp.dport = cli.tcp_dport;
|
||||
}
|
||||
|
||||
if (cmd.tcp_urg > -1)
|
||||
if (cli.tcp_urg > -1)
|
||||
{
|
||||
new_filter.tcpopts.do_urg = 1;
|
||||
new_filter.tcpopts.urg = cmd.tcp_urg;
|
||||
new_filter.tcp.urg = cli.tcp_urg;
|
||||
}
|
||||
|
||||
if (cmd.tcp_ack > -1)
|
||||
if (cli.tcp_ack > -1)
|
||||
{
|
||||
new_filter.tcpopts.do_ack = 1;
|
||||
new_filter.tcpopts.ack = cmd.tcp_ack;
|
||||
new_filter.tcp.ack = cli.tcp_ack;
|
||||
}
|
||||
|
||||
if (cmd.tcp_rst > -1)
|
||||
if (cli.tcp_rst > -1)
|
||||
{
|
||||
new_filter.tcpopts.do_rst = 1;
|
||||
new_filter.tcpopts.rst = cmd.tcp_rst;
|
||||
new_filter.tcp.rst = cli.tcp_rst;
|
||||
}
|
||||
|
||||
if (cmd.tcp_psh > -1)
|
||||
if (cli.tcp_psh > -1)
|
||||
{
|
||||
new_filter.tcpopts.do_psh = 1;
|
||||
new_filter.tcpopts.psh = cmd.tcp_psh;
|
||||
new_filter.tcp.psh = cli.tcp_psh;
|
||||
}
|
||||
|
||||
if (cmd.tcp_syn > -1)
|
||||
if (cli.tcp_syn > -1)
|
||||
{
|
||||
new_filter.tcpopts.do_syn = 1;
|
||||
new_filter.tcpopts.syn = cmd.tcp_syn;
|
||||
new_filter.tcp.syn = cli.tcp_syn;
|
||||
}
|
||||
|
||||
if (cmd.tcp_fin > -1)
|
||||
if (cli.tcp_fin > -1)
|
||||
{
|
||||
new_filter.tcpopts.do_fin = 1;
|
||||
new_filter.tcpopts.fin = cmd.tcp_fin;
|
||||
new_filter.tcp.fin = cli.tcp_fin;
|
||||
}
|
||||
|
||||
if (cmd.tcp_ece > -1)
|
||||
if (cli.tcp_ece > -1)
|
||||
{
|
||||
new_filter.tcpopts.do_ece = 1;
|
||||
new_filter.tcpopts.ece = cmd.tcp_ece;
|
||||
new_filter.tcp.ece = cli.tcp_ece;
|
||||
}
|
||||
|
||||
if (cmd.tcp_cwr > -1)
|
||||
if (cli.tcp_cwr > -1)
|
||||
{
|
||||
new_filter.tcpopts.do_cwr = 1;
|
||||
new_filter.tcpopts.cwr = cmd.tcp_cwr;
|
||||
new_filter.tcp.cwr = cli.tcp_cwr;
|
||||
}
|
||||
|
||||
if (cmd.udp_enabled > -1)
|
||||
if (cli.udp_enabled > -1)
|
||||
{
|
||||
new_filter.udpopts.enabled = cmd.udp_enabled;
|
||||
new_filter.udp.enabled = cli.udp_enabled;
|
||||
}
|
||||
|
||||
if (cmd.udp_sport > -1)
|
||||
if (cli.udp_sport > -1)
|
||||
{
|
||||
new_filter.udpopts.do_sport = 1;
|
||||
new_filter.udpopts.sport = cmd.udp_sport;
|
||||
new_filter.udp.sport = cli.udp_sport;
|
||||
}
|
||||
|
||||
if (cmd.udp_dport > -1)
|
||||
if (cli.udp_dport > -1)
|
||||
{
|
||||
new_filter.udpopts.do_dport = 1;
|
||||
new_filter.udpopts.dport = cmd.udp_dport;
|
||||
new_filter.udp.dport = cli.udp_dport;
|
||||
}
|
||||
|
||||
if (cmd.icmp_enabled > -1)
|
||||
if (cli.icmp_enabled > -1)
|
||||
{
|
||||
new_filter.icmpopts.enabled = cmd.icmp_enabled;
|
||||
new_filter.icmp.enabled = cli.icmp_enabled;
|
||||
}
|
||||
|
||||
if (cmd.icmp_code > -1)
|
||||
if (cli.icmp_code > -1)
|
||||
{
|
||||
new_filter.icmpopts.do_code = 1;
|
||||
new_filter.icmpopts.code = cmd.icmp_code;
|
||||
new_filter.icmp.code = cli.icmp_code;
|
||||
}
|
||||
|
||||
if (cmd.icmp_type > -1)
|
||||
if (cli.icmp_type > -1)
|
||||
{
|
||||
new_filter.icmpopts.do_type = 1;
|
||||
new_filter.icmpopts.type = cmd.icmp_type;
|
||||
new_filter.icmp.type = cli.icmp_type;
|
||||
}
|
||||
|
||||
// Set filter at index.
|
||||
@@ -396,15 +351,15 @@ int main(int argc, char *argv[])
|
||||
// Update filters.
|
||||
fprintf(stdout, "Updating filters (index %d)...\n", idx);
|
||||
|
||||
UpdateFilters(map_filters, &cfg);
|
||||
update_filters(map_filters, &cfg);
|
||||
}
|
||||
// Handle IPv4 range drop mode.
|
||||
else if (cmd.mode == 1)
|
||||
else if (cli.mode == 1)
|
||||
{
|
||||
printf("Using IPv4 range drop mode (1)...\n");
|
||||
|
||||
// Make sure IP range is specified.
|
||||
if (!cmd.ip)
|
||||
if (!cli.ip)
|
||||
{
|
||||
fprintf(stderr, "No IP address or range specified. Please set an IP range using -d, --ip arguments.\n");
|
||||
|
||||
@@ -412,7 +367,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Get range map.
|
||||
int map_range_drop = GetMapPinFd(XDP_MAP_PIN_DIR, "map_range_drop");
|
||||
int map_range_drop = get_map_fd_pin(XDP_MAP_PIN_DIR, "map_range_drop");
|
||||
|
||||
if (map_range_drop < 0)
|
||||
{
|
||||
@@ -424,22 +379,22 @@ int main(int argc, char *argv[])
|
||||
printf("Using 'map_range_drop' FD => %d.\n", map_range_drop);
|
||||
|
||||
// Parse IP range.
|
||||
ip_range_t range = ParseIpCidr(cmd.ip);
|
||||
ip_range_t range = parse_ip_range(cli.ip);
|
||||
|
||||
// Attempt to add range.
|
||||
if ((ret = AddRangeDrop(map_range_drop, range.ip, range.cidr)) != 0)
|
||||
if ((ret = add_range_drop(map_range_drop, range.ip, range.cidr)) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error adding range to BPF map (%d).\n", ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Added IP range '%s' to IP range drop map...\n", cmd.ip);
|
||||
printf("Added IP range '%s' to IP range drop map...\n", cli.ip);
|
||||
|
||||
if (cmd.save)
|
||||
if (cli.save)
|
||||
{
|
||||
// Get next available index.
|
||||
int idx = GetNextAvailableIpDropRangeIndex(&cfg);
|
||||
int idx = get_next_ip_drop_range_idx(&cfg);
|
||||
|
||||
if (idx < 0)
|
||||
{
|
||||
@@ -448,7 +403,7 @@ int main(int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
cfg.drop_ranges[idx] = strdup(cmd.ip);
|
||||
cfg.drop_ranges[idx] = strdup(cli.ip);
|
||||
}
|
||||
}
|
||||
// Handle block map mode.
|
||||
@@ -456,7 +411,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
printf("Using source IP block mode (2)...\n");
|
||||
|
||||
if (!cmd.ip)
|
||||
if (!cli.ip)
|
||||
{
|
||||
fprintf(stderr, "No source IP address specified. Please set an IP using -s, --ip arguments.\n");
|
||||
|
||||
@@ -465,15 +420,15 @@ int main(int argc, char *argv[])
|
||||
|
||||
u64 expires_rel = 0;
|
||||
|
||||
if (cmd.expires > 0)
|
||||
if (cli.expires > 0)
|
||||
{
|
||||
expires_rel = GetBootNanoTime() + ((u64)cmd.expires * 1e9);
|
||||
expires_rel = get_boot_nano_time() + ((u64)cli.expires * 1e9);
|
||||
}
|
||||
|
||||
int map_block = GetMapPinFd(XDP_MAP_PIN_DIR, "map_block");
|
||||
int map_block6 = GetMapPinFd(XDP_MAP_PIN_DIR, "map_block6");
|
||||
int map_block = get_map_fd_pin(XDP_MAP_PIN_DIR, "map_block");
|
||||
int map_block6 = get_map_fd_pin(XDP_MAP_PIN_DIR, "map_block6");
|
||||
|
||||
if (cmd.v6)
|
||||
if (cli.v6)
|
||||
{
|
||||
if (map_block6 < 0)
|
||||
{
|
||||
@@ -486,9 +441,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
struct in6_addr addr;
|
||||
|
||||
if ((ret = inet_pton(AF_INET6, cmd.ip, &addr)) != 1)
|
||||
if ((ret = inet_pton(AF_INET6, cli.ip, &addr)) != 1)
|
||||
{
|
||||
fprintf(stderr, "Failed to convert IPv6 address '%s' to decimal (%d).\n", cmd.ip, ret);
|
||||
fprintf(stderr, "Failed to convert IPv6 address '%s' to decimal (%d).\n", cli.ip, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -500,9 +455,9 @@ int main(int argc, char *argv[])
|
||||
ip = (ip << 8) | addr.s6_addr[i];
|
||||
}
|
||||
|
||||
if ((ret = AddBlock6(map_block6, ip, expires_rel)) != 0)
|
||||
if ((ret = add_block6(map_block6, ip, expires_rel)) != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to add IP '%s' to BPF map (%d).\n", cmd.ip, ret);
|
||||
fprintf(stderr, "Failed to add IP '%s' to BPF map (%d).\n", cli.ip, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -520,37 +475,37 @@ int main(int argc, char *argv[])
|
||||
|
||||
struct in_addr addr;
|
||||
|
||||
if ((ret = inet_pton(AF_INET, cmd.ip, &addr)) != 1)
|
||||
if ((ret = inet_pton(AF_INET, cli.ip, &addr)) != 1)
|
||||
{
|
||||
fprintf(stderr, "Failed to convert IP address '%s' to decimal (%d).\n", cmd.ip, ret);
|
||||
fprintf(stderr, "Failed to convert IP address '%s' to decimal (%d).\n", cli.ip, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if ((ret = AddBlock(map_block, addr.s_addr, expires_rel)) != 0)
|
||||
if ((ret = add_block(map_block, addr.s_addr, expires_rel)) != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to add IP '%s' too BPF map (%d).\n", cmd.ip, ret);
|
||||
fprintf(stderr, "Failed to add IP '%s' too BPF map (%d).\n", cli.ip, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (cmd.expires > 0)
|
||||
if (cli.expires > 0)
|
||||
{
|
||||
printf("Added '%s' to block map for %lld seconds...\n", cmd.ip, cmd.expires);
|
||||
printf("Added '%s' to block map for %lld seconds...\n", cli.ip, cli.expires);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Added '%s' to block map indefinitely...\n", cmd.ip);
|
||||
printf("Added '%s' to block map indefinitely...\n", cli.ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.save)
|
||||
if (cli.save)
|
||||
{
|
||||
// Save config.
|
||||
printf("Saving config...\n");
|
||||
|
||||
if ((ret = SaveCfg(&cfg, cmd.cfg_file)) != 0)
|
||||
if ((ret = save_cfg(&cfg, cli.cfg_file)) != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] Failed to save config.\n");
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <rule_add/utils/cmdline.h>
|
||||
#include <rule_add/utils/cli.h>
|
||||
|
||||
const struct option opts[] =
|
||||
{
|
||||
@@ -56,7 +56,7 @@ const struct option opts[] =
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
void ParseCommandLine(cmdline_t* cmd, int argc, char* argv[])
|
||||
void parse_cli(cli_t* cli, int argc, char* argv[])
|
||||
{
|
||||
int c;
|
||||
|
||||
@@ -65,202 +65,202 @@ void ParseCommandLine(cmdline_t* cmd, int argc, char* argv[])
|
||||
switch (c)
|
||||
{
|
||||
case 'c':
|
||||
cmd->cfg_file = optarg;
|
||||
cli->cfg_file = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
cmd->help = 1;
|
||||
cli->help = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 's':
|
||||
cmd->save = 1;
|
||||
cli->save = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
cmd->mode = atoi(optarg);
|
||||
cli->mode = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
cmd->idx = atoi(optarg);
|
||||
cli->idx = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
cmd->ip = optarg;
|
||||
cli->ip = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
cmd->v6 = atoi(optarg);
|
||||
cli->v6 = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
cmd->expires = strtoll(optarg, NULL, 10);
|
||||
cli->expires = strtoll(optarg, NULL, 10);
|
||||
|
||||
break;
|
||||
|
||||
case 28:
|
||||
cmd->enabled = atoi(optarg);
|
||||
cli->enabled = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 29:
|
||||
cmd->action = atoi(optarg);
|
||||
cli->action = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 30:
|
||||
cmd->log = atoi(optarg);
|
||||
cli->log = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 31:
|
||||
cmd->block_time = strtoll(optarg, NULL, 10);
|
||||
cli->block_time = strtoll(optarg, NULL, 10);
|
||||
|
||||
break;
|
||||
|
||||
case 0:
|
||||
cmd->src_ip = optarg;
|
||||
cli->src_ip = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
cmd->dst_ip = optarg;
|
||||
cli->dst_ip = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cmd->src_ip6 = optarg;
|
||||
cli->src_ip6 = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
cmd->dst_ip6 = optarg;
|
||||
cli->dst_ip6 = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
cmd->min_ttl = atoi(optarg);
|
||||
cli->min_ttl = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 5:
|
||||
cmd->max_ttl = atoi(optarg);
|
||||
cli->max_ttl = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 6:
|
||||
cmd->min_len = atoi(optarg);
|
||||
cli->min_len = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 7:
|
||||
cmd->max_len = atoi(optarg);
|
||||
cli->max_len = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 8:
|
||||
cmd->tos = atoi(optarg);
|
||||
cli->tos = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 9:
|
||||
cmd->pps = strtoll(optarg, NULL, 10);
|
||||
cli->pps = strtoll(optarg, NULL, 10);
|
||||
|
||||
break;
|
||||
|
||||
case 10:
|
||||
cmd->bps = strtoll(optarg, NULL, 10);
|
||||
cli->bps = strtoll(optarg, NULL, 10);
|
||||
|
||||
break;
|
||||
|
||||
case 11:
|
||||
cmd->tcp_enabled = atoi(optarg);
|
||||
cli->tcp_enabled = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 12:
|
||||
cmd->tcp_sport = atoi(optarg);
|
||||
cli->tcp_sport = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 13:
|
||||
cmd->tcp_dport = atoi(optarg);
|
||||
cli->tcp_dport = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 14:
|
||||
cmd->tcp_urg = atoi(optarg);
|
||||
cli->tcp_urg = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 15:
|
||||
cmd->tcp_ack = atoi(optarg);
|
||||
cli->tcp_ack = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 16:
|
||||
cmd->tcp_rst = atoi(optarg);
|
||||
cli->tcp_rst = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 17:
|
||||
cmd->tcp_psh = atoi(optarg);
|
||||
cli->tcp_psh = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 18:
|
||||
cmd->tcp_syn = atoi(optarg);
|
||||
cli->tcp_syn = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 19:
|
||||
cmd->tcp_fin = atoi(optarg);
|
||||
cli->tcp_fin = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 20:
|
||||
cmd->tcp_ece = atoi(optarg);
|
||||
cli->tcp_ece = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 21:
|
||||
cmd->tcp_cwr = atoi(optarg);
|
||||
cli->tcp_cwr = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 22:
|
||||
cmd->udp_enabled = atoi(optarg);
|
||||
cli->udp_enabled = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 23:
|
||||
cmd->udp_sport = atoi(optarg);
|
||||
cli->udp_sport = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 24:
|
||||
cmd->udp_dport = atoi(optarg);
|
||||
cli->udp_dport = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 25:
|
||||
cmd->icmp_enabled = atoi(optarg);
|
||||
cli->icmp_enabled = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 26:
|
||||
cmd->icmp_code = atoi(optarg);
|
||||
cli->icmp_code = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 27:
|
||||
cmd->icmp_type = atoi(optarg);
|
||||
cli->icmp_type = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct cmdline
|
||||
struct cli
|
||||
{
|
||||
const char* cfg_file;
|
||||
char* cfg_file;
|
||||
|
||||
int help;
|
||||
|
||||
@@ -20,7 +20,7 @@ struct cmdline
|
||||
|
||||
int idx;
|
||||
|
||||
const char* ip;
|
||||
char* ip;
|
||||
int v6;
|
||||
|
||||
s64 expires;
|
||||
@@ -30,11 +30,11 @@ struct cmdline
|
||||
int action;
|
||||
s64 block_time;
|
||||
|
||||
const char* src_ip;
|
||||
const char* dst_ip;
|
||||
char* src_ip;
|
||||
char* dst_ip;
|
||||
|
||||
const char* src_ip6;
|
||||
const char* dst_ip6;
|
||||
char* src_ip6;
|
||||
char* dst_ip6;
|
||||
|
||||
s64 pps;
|
||||
s64 bps;
|
||||
@@ -64,6 +64,6 @@ struct cmdline
|
||||
int icmp_enabled;
|
||||
int icmp_code;
|
||||
int icmp_type;
|
||||
} typedef cmdline_t;
|
||||
} typedef cli_t;
|
||||
|
||||
void ParseCommandLine(cmdline_t* cmd, int argc, char* argv[]);
|
||||
void parse_cli(cli_t* cli, int argc, char* argv[]);
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <loader/utils/xdp.h>
|
||||
#include <loader/utils/config.h>
|
||||
|
||||
#include <rule_del/utils/cmdline.h>
|
||||
#include <rule_del/utils/cli.h>
|
||||
|
||||
// These are required due to being extern with Loader.
|
||||
// To Do: Figure out a way to not require the below without requiring separate object files.
|
||||
@@ -19,12 +19,12 @@ int main(int argc, char *argv[])
|
||||
int ret;
|
||||
|
||||
// Parse command line.
|
||||
cmdline_t cmd = {0};
|
||||
cmd.cfg_file = CONFIG_DEFAULT_PATH;
|
||||
cli_t cli = {0};
|
||||
cli.cfg_file = CONFIG_DEFAULT_PATH;
|
||||
|
||||
ParseCommandLine(&cmd, argc, argv);
|
||||
parse_cli(&cli, argc, argv);
|
||||
|
||||
if (!cmd.help)
|
||||
if (!cli.help)
|
||||
{
|
||||
printf("Parsed command line...\n");
|
||||
} else
|
||||
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Check for config file path.
|
||||
if ((cmd.save || cmd.mode == 0) && (!cmd.cfg_file || strlen(cmd.cfg_file) < 1))
|
||||
if ((cli.save || cli.mode == 0) && (!cli.cfg_file || strlen(cli.cfg_file) < 1))
|
||||
{
|
||||
fprintf(stderr, "[ERROR] CFG file not specified or empty. This is required for current mode or options set.\n");
|
||||
|
||||
@@ -52,11 +52,11 @@ int main(int argc, char *argv[])
|
||||
// Load config.
|
||||
config__t cfg = {0};
|
||||
|
||||
if (cmd.save || cmd.mode == 0)
|
||||
if (cli.save || cli.mode == 0)
|
||||
{
|
||||
if ((ret = LoadConfig(&cfg, cmd.cfg_file, NULL)) != 0)
|
||||
if ((ret = load_cfg(&cfg, cli.cfg_file, 1, NULL)) != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] Failed to load config at '%s' (%d)\n", cmd.cfg_file, ret);
|
||||
fprintf(stderr, "[ERROR] Failed to load config at '%s' (%d)\n", cli.cfg_file, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -65,12 +65,12 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Handle filters mode.
|
||||
if (cmd.mode == 0)
|
||||
if (cli.mode == 0)
|
||||
{
|
||||
printf("Using filters mode (0)...\n");
|
||||
|
||||
// Check index.
|
||||
if (cmd.idx < 1)
|
||||
if (cli.idx < 1)
|
||||
{
|
||||
fprintf(stderr, "Invalid filter index. Index must start from 1.\n");
|
||||
|
||||
@@ -78,7 +78,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Retrieve filters map FD.
|
||||
int map_filters = GetMapPinFd(XDP_MAP_PIN_DIR, "map_filters");
|
||||
int map_filters = get_map_fd_pin(XDP_MAP_PIN_DIR, "map_filters");
|
||||
|
||||
if (map_filters < 0)
|
||||
{
|
||||
@@ -90,7 +90,7 @@ int main(int argc, char *argv[])
|
||||
printf("Using 'map_filters' FD => %d...\n", map_filters);
|
||||
|
||||
int idx = -1;
|
||||
int cfg_idx = cmd.idx - 1;
|
||||
int cfg_idx = cli.idx - 1;
|
||||
int cur_idx = 0;
|
||||
|
||||
// This is where things are a bit tricky due to the layout of our filtering system in XDP.
|
||||
@@ -99,7 +99,7 @@ int main(int argc, char *argv[])
|
||||
// So we need to loop through each and ignore disabled rules.
|
||||
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)
|
||||
{
|
||||
@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Unset affected filter in config.
|
||||
if (cmd.save)
|
||||
if (cli.save)
|
||||
{
|
||||
cfg.filters[cfg_idx].set = 0;
|
||||
}
|
||||
@@ -132,15 +132,15 @@ int main(int argc, char *argv[])
|
||||
// Update filters.
|
||||
fprintf(stdout, "Updating filters...\n");
|
||||
|
||||
UpdateFilters(map_filters, &cfg);
|
||||
update_filters(map_filters, &cfg);
|
||||
}
|
||||
// Handle IPv4 range drop mode.
|
||||
else if (cmd.mode == 1)
|
||||
else if (cli.mode == 1)
|
||||
{
|
||||
printf("Using IPv4 range drop mode (1)...\n");
|
||||
|
||||
// Make sure IP range is specified.
|
||||
if (!cmd.ip)
|
||||
if (!cli.ip)
|
||||
{
|
||||
fprintf(stderr, "No IP address or range specified. Please set an IP range using -s, --ip arguments.\n");
|
||||
|
||||
@@ -148,7 +148,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Get range map.
|
||||
int map_range_drop = GetMapPinFd(XDP_MAP_PIN_DIR, "map_range_drop");
|
||||
int map_range_drop = get_map_fd_pin(XDP_MAP_PIN_DIR, "map_range_drop");
|
||||
|
||||
if (map_range_drop < 0)
|
||||
{
|
||||
@@ -160,19 +160,19 @@ int main(int argc, char *argv[])
|
||||
printf("Using 'map_range_drop' FD => %d.\n", map_range_drop);
|
||||
|
||||
// Parse IP range.
|
||||
ip_range_t range = ParseIpCidr(cmd.ip);
|
||||
ip_range_t range = parse_ip_range(cli.ip);
|
||||
|
||||
// Attempt to delete range.
|
||||
if ((ret = DeleteRangeDrop(map_range_drop, range.ip, range.cidr)) != 0)
|
||||
if ((ret = delete_range_drop(map_range_drop, range.ip, range.cidr)) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error deleting range from BPF map (%d).\n", ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Removed IP range '%s'...\n", cmd.ip);
|
||||
printf("Removed IP range '%s'...\n", cli.ip);
|
||||
|
||||
if (cmd.save)
|
||||
if (cli.save)
|
||||
{
|
||||
// Loop through IP drop ranges and unset if found.
|
||||
for (int i = 0; i < MAX_IP_RANGES; i++)
|
||||
@@ -184,7 +184,7 @@ int main(int argc, char *argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(cur_range, cmd.ip) != 0)
|
||||
if (strcmp(cur_range, cli.ip) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -199,17 +199,17 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
printf("Using source IP block mode (2)...\n");
|
||||
|
||||
if (!cmd.ip)
|
||||
if (!cli.ip)
|
||||
{
|
||||
fprintf(stderr, "No source IP address specified. Please set an IP using -s, --ip arguments.\n");
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int map_block = GetMapPinFd(XDP_MAP_PIN_DIR, "map_block");
|
||||
int map_block6 = GetMapPinFd(XDP_MAP_PIN_DIR, "map_block6");
|
||||
int map_block = get_map_fd_pin(XDP_MAP_PIN_DIR, "map_block");
|
||||
int map_block6 = get_map_fd_pin(XDP_MAP_PIN_DIR, "map_block6");
|
||||
|
||||
if (cmd.v6)
|
||||
if (cli.v6)
|
||||
{
|
||||
if (map_block6 < 0)
|
||||
{
|
||||
@@ -222,9 +222,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
struct in6_addr addr;
|
||||
|
||||
if ((ret = inet_pton(AF_INET6, cmd.ip, &addr)) != 1)
|
||||
if ((ret = inet_pton(AF_INET6, cli.ip, &addr)) != 1)
|
||||
{
|
||||
fprintf(stderr, "Failed to convert IPv6 address '%s' to decimal (%d).\n", cmd.ip, ret);
|
||||
fprintf(stderr, "Failed to convert IPv6 address '%s' to decimal (%d).\n", cli.ip, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -236,9 +236,9 @@ int main(int argc, char *argv[])
|
||||
ip = (ip << 8) | addr.s6_addr[i];
|
||||
}
|
||||
|
||||
if ((ret = DeleteBlock6(map_block6, ip)) != 0)
|
||||
if ((ret = delete_block6(map_block6, ip)) != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to delete IP '%s' from BPF map (%d).\n", cmd.ip, ret);
|
||||
fprintf(stderr, "Failed to delete IP '%s' from BPF map (%d).\n", cli.ip, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -256,30 +256,30 @@ int main(int argc, char *argv[])
|
||||
|
||||
struct in_addr addr;
|
||||
|
||||
if ((ret = inet_pton(AF_INET, cmd.ip, &addr)) != 1)
|
||||
if ((ret = inet_pton(AF_INET, cli.ip, &addr)) != 1)
|
||||
{
|
||||
fprintf(stderr, "Failed to convert IP address '%s' to decimal (%d).\n", cmd.ip, ret);
|
||||
fprintf(stderr, "Failed to convert IP address '%s' to decimal (%d).\n", cli.ip, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if ((ret = DeleteBlock(map_block, addr.s_addr)) != 0)
|
||||
if ((ret = delete_block(map_block, addr.s_addr)) != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to delete IP '%s' from BPF map (%d).\n", cmd.ip, ret);
|
||||
fprintf(stderr, "Failed to delete IP '%s' from BPF map (%d).\n", cli.ip, ret);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Deleted IP '%s'...\n", cmd.ip);
|
||||
printf("Deleted IP '%s'...\n", cli.ip);
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.save)
|
||||
if (cli.save)
|
||||
{
|
||||
// Save config.
|
||||
printf("Saving config...\n");
|
||||
|
||||
if ((ret = SaveCfg(&cfg, cmd.cfg_file)) != 0)
|
||||
if ((ret = save_cfg(&cfg, cli.cfg_file)) != 0)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] Failed to save config.\n");
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <rule_del/utils/cmdline.h>
|
||||
#include <rule_del/utils/cli.h>
|
||||
|
||||
const struct option opts[] =
|
||||
{
|
||||
@@ -16,7 +16,7 @@ const struct option opts[] =
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
void ParseCommandLine(cmdline_t* cmd, int argc, char* argv[])
|
||||
void parse_cli(cli_t* cli, int argc, char* argv[])
|
||||
{
|
||||
int c;
|
||||
|
||||
@@ -25,37 +25,37 @@ void ParseCommandLine(cmdline_t* cmd, int argc, char* argv[])
|
||||
switch (c)
|
||||
{
|
||||
case 'c':
|
||||
cmd->cfg_file = optarg;
|
||||
cli->cfg_file = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
cmd->help = 1;
|
||||
cli->help = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 's':
|
||||
cmd->save = 1;
|
||||
cli->save = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
cmd->mode = atoi(optarg);
|
||||
cli->mode = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
cmd->idx = atoi(optarg);
|
||||
cli->idx = atoi(optarg);
|
||||
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
cmd->ip = optarg;
|
||||
cli->ip = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
cmd->v6 = 1;
|
||||
cli->v6 = 1;
|
||||
|
||||
break;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
|
||||
struct cmdline
|
||||
struct cli
|
||||
{
|
||||
const char* cfg_file;
|
||||
|
||||
@@ -18,6 +18,6 @@ struct cmdline
|
||||
|
||||
const char* ip;
|
||||
int v6;
|
||||
} typedef cmdline_t;
|
||||
} typedef cli_t;
|
||||
|
||||
void ParseCommandLine(cmdline_t* cmd, int argc, char* argv[]);
|
||||
void parse_cli(cli_t* cli, int argc, char* argv[]);
|
||||
149
src/xdp/prog.c
149
src/xdp/prog.c
@@ -10,12 +10,13 @@
|
||||
|
||||
#include <common/all.h>
|
||||
|
||||
#include <xdp/utils/maps.h>
|
||||
|
||||
#include <xdp/utils/rl.h>
|
||||
#include <xdp/utils/logging.h>
|
||||
#include <xdp/utils/stats.h>
|
||||
#include <xdp/utils/helpers.h>
|
||||
|
||||
#include <xdp/utils/maps.h>
|
||||
|
||||
struct
|
||||
{
|
||||
__uint(priority, 10);
|
||||
@@ -29,18 +30,26 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
void *data_end = (void *)(long)ctx->data_end;
|
||||
void *data = (void *)(long)ctx->data;
|
||||
|
||||
// Retrieve stats map value.
|
||||
u32 key = 0;
|
||||
stats_t* stats = bpf_map_lookup_elem(&map_stats, &key);
|
||||
|
||||
// Scan ethernet header.
|
||||
struct ethhdr *eth = data;
|
||||
|
||||
// Check if the ethernet header is valid.
|
||||
if (unlikely(eth + 1 > (struct ethhdr *)data_end))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
|
||||
return XDP_DROP;
|
||||
}
|
||||
|
||||
// Check Ethernet protocol.
|
||||
if (unlikely(eth->h_proto != htons(ETH_P_IP) && eth->h_proto != htons(ETH_P_IPV6)))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_PASSED);
|
||||
|
||||
return XDP_PASS;
|
||||
}
|
||||
|
||||
@@ -56,6 +65,8 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
|
||||
if (unlikely(iph6 + 1 > (struct ipv6hdr *)data_end))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
|
||||
return XDP_DROP;
|
||||
}
|
||||
|
||||
@@ -67,6 +78,8 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
|
||||
if (unlikely(iph + 1 > (struct iphdr *)data_end))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
|
||||
return XDP_DROP;
|
||||
}
|
||||
}
|
||||
@@ -74,13 +87,11 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
// We only want to process TCP, UDP, and ICMP packets.
|
||||
if ((iph6 && iph6->nexthdr != IPPROTO_UDP && iph6->nexthdr != IPPROTO_TCP && iph6->nexthdr != IPPROTO_ICMP) && (iph && iph->protocol != IPPROTO_UDP && iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_ICMP))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_PASSED);
|
||||
|
||||
return XDP_PASS;
|
||||
}
|
||||
|
||||
// Retrieve stats map value.
|
||||
u32 key = 0;
|
||||
stats_t*stats = bpf_map_lookup_elem(&map_stats, &key);
|
||||
|
||||
// Retrieve nanoseconds since system boot as timestamp.
|
||||
u64 now = bpf_ktime_get_ns();
|
||||
|
||||
@@ -114,10 +125,7 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
{
|
||||
#ifdef DO_STATS_ON_BLOCK_MAP
|
||||
// Increase blocked stats entry.
|
||||
if (stats)
|
||||
{
|
||||
stats->dropped++;
|
||||
}
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
#endif
|
||||
|
||||
// They're still blocked. Drop the packet.
|
||||
@@ -126,13 +134,10 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IP_RANGE_DROP
|
||||
if (iph && CheckIpRangeDrop(iph->saddr))
|
||||
if (iph && check_ip_range_drop(iph->saddr))
|
||||
{
|
||||
#ifdef DO_STATS_ON_IP_RANGE_DROP_MAP
|
||||
if (stats)
|
||||
{
|
||||
stats->dropped++;
|
||||
}
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
#endif
|
||||
|
||||
return XDP_DROP;
|
||||
@@ -170,6 +175,8 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
// Check TCP header.
|
||||
if (unlikely(tcph + 1 > (struct tcphdr *)data_end))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
|
||||
return XDP_DROP;
|
||||
}
|
||||
|
||||
@@ -188,6 +195,8 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
// Check TCP header.
|
||||
if (unlikely(udph + 1 > (struct udphdr *)data_end))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
|
||||
return XDP_DROP;
|
||||
}
|
||||
|
||||
@@ -206,6 +215,8 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
// Check ICMPv6 header.
|
||||
if (unlikely(icmp6h + 1 > (struct icmp6hdr *)data_end))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
|
||||
return XDP_DROP;
|
||||
}
|
||||
|
||||
@@ -225,6 +236,8 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
// Check TCP header.
|
||||
if (unlikely(tcph + 1 > (struct tcphdr *)data_end))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
|
||||
return XDP_DROP;
|
||||
}
|
||||
|
||||
@@ -243,6 +256,8 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
// Check UDP header.
|
||||
if (unlikely(udph + 1 > (struct udphdr *)data_end))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
|
||||
return XDP_DROP;
|
||||
}
|
||||
|
||||
@@ -261,6 +276,8 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
// Check ICMP header.
|
||||
if (unlikely(icmph + 1 > (struct icmphdr *)data_end))
|
||||
{
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
|
||||
return XDP_DROP;
|
||||
}
|
||||
|
||||
@@ -274,11 +291,11 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
|
||||
if (iph6)
|
||||
{
|
||||
UpdateIp6Stats(&pps, &bps, &src_ip6, src_port, protocol, pkt_len, now);
|
||||
update_ip6_stats(&pps, &bps, &src_ip6, src_port, protocol, pkt_len, now);
|
||||
}
|
||||
else if (iph)
|
||||
{
|
||||
UpdateIpStats(&pps, &bps, iph->saddr, src_port, protocol, pkt_len, now);
|
||||
update_ip_stats(&pps, &bps, iph->saddr, src_port, protocol, pkt_len, now);
|
||||
}
|
||||
|
||||
int action = 0;
|
||||
@@ -290,7 +307,6 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
|
||||
filter_t *filter = bpf_map_lookup_elem(&map_filters, &key);
|
||||
|
||||
// Check if ID is above 0 (if 0, it's an invalid rule).
|
||||
if (!filter || !filter->set)
|
||||
{
|
||||
break;
|
||||
@@ -300,44 +316,44 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
if (iph6)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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 < pkt_len)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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 > pkt_len)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -345,66 +361,66 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
else if (iph)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (!IsIpInRange(iph->saddr, filter->src_ip, filter->src_cidr))
|
||||
if (!is_ip_in_range(iph->saddr, filter->ip.src_ip, filter->ip.src_cidr))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (!IsIpInRange(iph->daddr, filter->dst_ip, filter->dst_cidr))
|
||||
if (!is_ip_in_range(iph->daddr, filter->ip.dst_ip, filter->ip.dst_cidr))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
|
||||
// TOS.
|
||||
if (filter->do_tos && filter->tos != iph->tos)
|
||||
if (filter->ip.do_tos && filter->ip.tos != iph->tos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Max TTL length.
|
||||
if (filter->do_max_ttl && filter->max_ttl < iph->ttl)
|
||||
// Max TTL.
|
||||
if (filter->ip.do_max_ttl && filter->ip.max_ttl < iph->ttl)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Min TTL length.
|
||||
if (filter->do_min_ttl && filter->min_ttl > iph->ttl)
|
||||
// Min TTL.
|
||||
if (filter->ip.do_min_ttl && filter->ip.min_ttl > iph->ttl)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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 < pkt_len)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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 > pkt_len)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -423,7 +439,7 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
}
|
||||
|
||||
// Do TCP options.
|
||||
if (filter->tcpopts.enabled)
|
||||
if (filter->tcp.enabled)
|
||||
{
|
||||
if (!tcph)
|
||||
{
|
||||
@@ -431,66 +447,66 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
}
|
||||
|
||||
// Source port.
|
||||
if (filter->tcpopts.do_sport && htons(filter->tcpopts.sport) != tcph->source)
|
||||
if (filter->tcp.do_sport && filter->tcp.sport != tcph->source)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Destination port.
|
||||
if (filter->tcpopts.do_dport && htons(filter->tcpopts.dport) != tcph->dest)
|
||||
if (filter->tcp.do_dport && filter->tcp.dport != tcph->dest)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// URG flag.
|
||||
if (filter->tcpopts.do_urg && filter->tcpopts.urg != tcph->urg)
|
||||
if (filter->tcp.do_urg && filter->tcp.urg != tcph->urg)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// ACK flag.
|
||||
if (filter->tcpopts.do_ack && filter->tcpopts.ack != tcph->ack)
|
||||
if (filter->tcp.do_ack && filter->tcp.ack != tcph->ack)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// RST flag.
|
||||
if (filter->tcpopts.do_rst && filter->tcpopts.rst != tcph->rst)
|
||||
if (filter->tcp.do_rst && filter->tcp.rst != tcph->rst)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// PSH flag.
|
||||
if (filter->tcpopts.do_psh && filter->tcpopts.psh != tcph->psh)
|
||||
if (filter->tcp.do_psh && filter->tcp.psh != tcph->psh)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// SYN flag.
|
||||
if (filter->tcpopts.do_syn && filter->tcpopts.syn != tcph->syn)
|
||||
if (filter->tcp.do_syn && filter->tcp.syn != tcph->syn)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIN flag.
|
||||
if (filter->tcpopts.do_fin && filter->tcpopts.fin != tcph->fin)
|
||||
if (filter->tcp.do_fin && filter->tcp.fin != tcph->fin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// ECE flag.
|
||||
if (filter->tcpopts.do_ece && filter->tcpopts.ece != tcph->ece)
|
||||
if (filter->tcp.do_ece && filter->tcp.ece != tcph->ece)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// CWR flag.
|
||||
if (filter->tcpopts.do_cwr && filter->tcpopts.cwr != tcph->cwr)
|
||||
if (filter->tcp.do_cwr && filter->tcp.cwr != tcph->cwr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (filter->udpopts.enabled)
|
||||
else if (filter->udp.enabled)
|
||||
{
|
||||
if (!udph)
|
||||
{
|
||||
@@ -498,30 +514,30 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
}
|
||||
|
||||
// Source port.
|
||||
if (filter->udpopts.do_sport && htons(filter->udpopts.sport) != udph->source)
|
||||
if (filter->udp.do_sport && filter->udp.sport != udph->source)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Destination port.
|
||||
if (filter->udpopts.do_dport && htons(filter->udpopts.dport) != udph->dest)
|
||||
if (filter->udp.do_dport && filter->udp.dport != udph->dest)
|
||||
{
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (filter->icmpopts.enabled)
|
||||
else if (filter->icmp.enabled)
|
||||
{
|
||||
if (icmph)
|
||||
{
|
||||
// Code.
|
||||
if (filter->icmpopts.do_code && filter->icmpopts.code != icmph->code)
|
||||
if (filter->icmp.do_code && filter->icmp.code != icmph->code)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Type.
|
||||
if (filter->icmpopts.do_type && filter->icmpopts.type != icmph->type)
|
||||
if (filter->icmp.do_type && filter->icmp.type != icmph->type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -529,13 +545,13 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
else if (icmp6h)
|
||||
{
|
||||
// Code.
|
||||
if (filter->icmpopts.do_code && filter->icmpopts.code != icmp6h->icmp6_code)
|
||||
if (filter->icmp.do_code && filter->icmp.code != icmp6h->icmp6_code)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Type.
|
||||
if (filter->icmpopts.do_type && filter->icmpopts.type != icmp6h->icmp6_type)
|
||||
if (filter->icmp.do_type && filter->icmp.type != icmp6h->icmp6_type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -549,7 +565,7 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
#ifdef ENABLE_FILTER_LOGGING
|
||||
if (filter->log > 0)
|
||||
{
|
||||
LogFilterMsg(iph, iph6, src_port, dst_port, protocol, now, pps, bps, i);
|
||||
log_filter_msg(iph, iph6, src_port, dst_port, protocol, now, pps, bps, pkt_len, i);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -561,10 +577,7 @@ int xdp_prog_main(struct xdp_md *ctx)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (stats)
|
||||
{
|
||||
stats->passed++;
|
||||
}
|
||||
inc_pkt_stats(stats, STATS_TYPE_PASSED);
|
||||
|
||||
return XDP_PASS;
|
||||
|
||||
@@ -587,19 +600,13 @@ matched:
|
||||
}
|
||||
}
|
||||
|
||||
if (stats)
|
||||
{
|
||||
stats->dropped++;
|
||||
}
|
||||
inc_pkt_stats(stats, STATS_TYPE_DROPPED);
|
||||
|
||||
return XDP_DROP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stats)
|
||||
{
|
||||
stats->allowed++;
|
||||
}
|
||||
inc_pkt_stats(stats, STATS_TYPE_ALLOWED);
|
||||
}
|
||||
|
||||
return XDP_PASS;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
* @return 1 on yes, 0 on no.
|
||||
*/
|
||||
static __always_inline int IsIpInRange(u32 src_ip, u32 net_ip, u8 cidr)
|
||||
static __always_inline int is_ip_in_range(u32 src_ip, u32 net_ip, u8 cidr)
|
||||
{
|
||||
return !((src_ip ^ net_ip) & htonl(0xFFFFFFFFu << (32 - cidr)));
|
||||
}
|
||||
@@ -24,7 +24,7 @@ static __always_inline int IsIpInRange(u32 src_ip, u32 net_ip, u8 cidr)
|
||||
*
|
||||
* @return 1 on yes or 0 on no.
|
||||
*/
|
||||
static __always_inline int CheckIpRangeDrop(u32 ip)
|
||||
static __always_inline int check_ip_range_drop(u32 ip)
|
||||
{
|
||||
LpmTrieKey key =
|
||||
{
|
||||
|
||||
@@ -32,10 +32,10 @@
|
||||
#define memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n))
|
||||
#endif
|
||||
|
||||
static __always_inline int IsIpInRange(u32 src_ip, u32 net_ip, u8 cidr);
|
||||
static __always_inline int is_ip_in_range(u32 src_ip, u32 net_ip, u8 cidr);
|
||||
|
||||
#ifdef ENABLE_IP_RANGE_DROP
|
||||
static __always_inline int CheckIpRangeDrop(u32 ip);
|
||||
static __always_inline int check_ip_range_drop(u32 ip);
|
||||
#endif
|
||||
|
||||
// The source file is included directly below instead of compiled and linked as an object because when linking, there is no guarantee the compiler will inline the function (which is crucial for performance).
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
* @param now The timestamp.
|
||||
* @param pps The current PPS rate.
|
||||
* @param bps The current BPS rate.
|
||||
* @param pkt_len The full packet length.
|
||||
* @param filter_id The filter ID that matched.
|
||||
*
|
||||
* @return always 0
|
||||
*/
|
||||
static __always_inline int LogFilterMsg(struct iphdr* iph, struct ipv6hdr* iph6, u16 src_port, u16 dst_port, u8 protocol, u64 now, u64 pps, u64 bps, int filter_id)
|
||||
static __always_inline int log_filter_msg(struct iphdr* iph, struct ipv6hdr* iph6, u16 src_port, u16 dst_port, u8 protocol, u64 now, u64 pps, u64 bps, int pkt_len, int filter_id)
|
||||
{
|
||||
filter_log_event_t* e = bpf_ringbuf_reserve(&map_filter_log, sizeof(*e), 0);
|
||||
|
||||
@@ -47,6 +48,8 @@ static __always_inline int LogFilterMsg(struct iphdr* iph, struct ipv6hdr* iph6,
|
||||
e->pps = pps;
|
||||
e->bps = bps;
|
||||
|
||||
e->length = pkt_len;
|
||||
|
||||
bpf_ringbuf_submit(e, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <xdp/prog_dispatcher.h>
|
||||
|
||||
#if defined(ENABLE_FILTERS) && defined(ENABLE_FILTER_LOGGING)
|
||||
static __always_inline int LogFilterMsg(struct iphdr* iph, struct ipv6hdr* iph6, u16 src_port, u16 dst_port, u8 protocol, u64 now, u64 pps, u64 bps, int filter_id);
|
||||
static __always_inline int log_filter_msg(struct iphdr* iph, struct ipv6hdr* iph6, u16 src_port, u16 dst_port, u8 protocol, u64 now, u64 pps, u64 bps, int pkt_len, int filter_id);
|
||||
#endif
|
||||
|
||||
// The source file is included directly below instead of compiled and linked as an object because when linking, there is no guarantee the compiler will inline the function (which is crucial for performance).
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static __always_inline void UpdateIpStats(u64 *pps, u64 *bps, u32 ip, u16 port, u8 protocol, u16 pkt_len, u64 now)
|
||||
static __always_inline void update_ip_stats(u64 *pps, u64 *bps, u32 ip, u16 port, u8 protocol, u16 pkt_len, u64 now)
|
||||
{
|
||||
#ifdef USE_FLOW_RL
|
||||
flow_t key = {0};
|
||||
@@ -79,7 +79,7 @@ static __always_inline void UpdateIpStats(u64 *pps, u64 *bps, u32 ip, u16 port,
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static __always_inline void UpdateIp6Stats(u64 *pps, u64 *bps, u128 *ip, u16 port, u8 protocol, u16 pkt_len, u64 now)
|
||||
static __always_inline void update_ip6_stats(u64 *pps, u64 *bps, u128 *ip, u16 port, u8 protocol, u16 pkt_len, u64 now)
|
||||
{
|
||||
#ifdef USE_FLOW_RL
|
||||
flow6_t key = {0};
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <xdp/utils/maps.h>
|
||||
|
||||
#ifdef ENABLE_FILTERS
|
||||
static __always_inline void UpdateIpStats(u64 *pps, u64 *bps, u32 ip, u16 port, u8 protocol, u16 pkt_len, u64 now);
|
||||
static __always_inline void UpdateIp6Stats(u64 *pps, u64 *bps, u128 *ip, u16 port, u8 protocol, u16 pkt_len, u64 now);
|
||||
static __always_inline void update_ip_stats(u64 *pps, u64 *bps, u32 ip, u16 port, u8 protocol, u16 pkt_len, u64 now);
|
||||
static __always_inline void update_ip6_stats(u64 *pps, u64 *bps, u128 *ip, u16 port, u8 protocol, u16 pkt_len, u64 now);
|
||||
#endif
|
||||
|
||||
// The source file is included directly below instead of compiled and linked as an object because when linking, there is no guarantee the compiler will inline the function (which is crucial for performance).
|
||||
|
||||
29
src/xdp/utils/stats.c
Normal file
29
src/xdp/utils/stats.c
Normal file
@@ -0,0 +1,29 @@
|
||||
#include <xdp/utils/stats.h>
|
||||
|
||||
static __always_inline int inc_pkt_stats(stats_t* stats, STATS_TYPE_T type)
|
||||
{
|
||||
if (!stats)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case STATS_TYPE_ALLOWED:
|
||||
stats->allowed++;
|
||||
|
||||
break;
|
||||
|
||||
case STATS_TYPE_PASSED:
|
||||
stats->passed++;
|
||||
|
||||
break;
|
||||
|
||||
case STATS_TYPE_DROPPED:
|
||||
stats->dropped++;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
22
src/xdp/utils/stats.h
Normal file
22
src/xdp/utils/stats.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/all.h>
|
||||
|
||||
#include <linux/bpf.h>
|
||||
|
||||
#include <xdp/xdp_helpers.h>
|
||||
#include <xdp/prog_dispatcher.h>
|
||||
|
||||
enum STATS_TYPE
|
||||
{
|
||||
STATS_TYPE_ALLOWED = 0,
|
||||
STATS_TYPE_PASSED,
|
||||
STATS_TYPE_DROPPED
|
||||
} typedef STATS_TYPE_T;
|
||||
|
||||
static __always_inline int inc_pkt_stats(stats_t* stats, STATS_TYPE_T type);
|
||||
|
||||
// The source file is included directly below instead of compiled and linked as an object because when linking, there is no guarantee the compiler will inline the function (which is crucial for performance).
|
||||
// I'd prefer not to include the function logic inside of the header file.
|
||||
// More Info: https://stackoverflow.com/questions/24289599/always-inline-does-not-work-when-function-is-implemented-in-different-file
|
||||
#include "stats.c"
|
||||
@@ -1,6 +1,6 @@
|
||||
verbose = 2;
|
||||
log_file = "/var/log/xdpfw.log";
|
||||
interface = "ens18";
|
||||
interfaces = "ens18";
|
||||
update_time = 15;
|
||||
no_stats = false;
|
||||
stats_per_second = false;
|
||||
|
||||
Reference in New Issue
Block a user