### Set and get an XDP chain Source: https://bpfilter.io/_sources/usage/bfcli.rst.txt This example demonstrates setting up a new XDP chain named 'my_xdp_chain' and then retrieving its configuration using 'bfcli chain get'. ```shell sudo bfcli chain set --from-str "chain my_xdp_chain BF_HOOK_XDP ACCEPT" sudo bfcli chain get --name my_xdp_chain ``` -------------------------------- ### Setup socket creation Source: https://bpfilter.io/developers/tests.html Sets up the environment for creating test sockets. ```c btf_setup_create_sockets() ``` -------------------------------- ### Install Build Dependencies on Ubuntu Source: https://bpfilter.io/_sources/developers/build.rst.txt Installs all required packages for a full bpfilter build on Ubuntu 24.04+ using apt-get. ```shell sudo apt-get install -y \ autoconf \ automake \ bison \ clang \ clang-tidy \ clang-format \ cmake \ doxygen \ flex \ furo \ g++ \ git \ iproute2 \ iputils-ping \ lcov \ libbenchmark-dev \ libbpf-dev \ libc-dev \ libcmocka-dev \ libclang-rt-20-dev \ libfuzzer-20-dev \ libgit2-dev \ libtool \ linux-tools-common \ make \ pkgconf \ procps \ python3-breathe \ python3-dateutil \ python3-git \ python3-pip \ python3-scapy \ python3-sphinx \ sed \ xxd ``` -------------------------------- ### Example: Define and Use DNS Set Source: https://bpfilter.io/usage/bfcli.html This example demonstrates defining a named set for DNS source IP addresses and then using it in a rule to accept matching packets. ```plaintext set dns (ip4.saddr) in { 1.1.1.1; 1.0.0.1 } rule (ip4.saddr) in dns counter ACCEPT ``` -------------------------------- ### Setup temporary directory creation Source: https://bpfilter.io/developers/tests.html Sets up the environment for creating temporary directories for testing. ```c btf_setup_create_tmpdir() ``` -------------------------------- ### Install bpfilter using DNF Source: https://bpfilter.io/_sources/usage/index.rst.txt Install the bpfilter package on Fedora or EPEL systems using the dnf package manager. ```bash > sudo dnf install -y bpfilter ``` -------------------------------- ### Install Build Dependencies on Fedora Source: https://bpfilter.io/_sources/developers/build.rst.txt Installs all required packages for a full bpfilter build on Fedora 40+ using dnf. ```shell sudo dnf -y install \ autoconf \ automake \ gawk \ bpftool \ bison \ clang \ clang-tools-extra \ cmake \ compiler-rt \ doxygen \ flex \ gcc \ gcc-c++ \ git-core \ google-benchmark-devel \ iproute \ iputils \ jq \ lcov \ libbpf-devel \ libcmocka-devel \ libgit2-devel \ libtool \ procps-ng \ python3-breathe \ python3-dateutil \ python3-furo \ python3-GitPython \ python3-linuxdoc \ python3-scapy \ python3-sphinx \ sed \ xxd ``` -------------------------------- ### Setup stream redirection Source: https://bpfilter.io/developers/tests.html Sets up redirection for standard output and standard error streams. ```c btf_setup_redirect_streams() ``` -------------------------------- ### Context Setup and Teardown Source: https://bpfilter.io/developers/modules/libbpfilter/libbpfilter.html Initializes and tears down the libbpfilter context. Initialization must be called before any other API function. ```APIDOC ## Context Management ### Description Initializes the libbpfilter context. This must be called before any other libbpfilter API function. Tears down the libbpfilter context. This should be called when done using the library. ### Functions #### `bf_ctx_setup` ```c int bf_ctx_setup(bool log_level, const char *bpf_path, int flags) ``` **Description:** Initializes the libbpfilter context. **Parameters:** - `log_level` (bool): Controls the logging level. - `bpf_path` (const char*): Path to the BPF filesystem. - `flags` (int): Flags for context setup. **Returns:** 0 on success, negative error value on failure. #### `bf_ctx_teardown` ```c void bf_ctx_teardown(void) ``` **Description:** Tears down the libbpfilter context. **Note:** Calling any API function before `bf_ctx_setup` succeeds returns -EINVAL. ``` -------------------------------- ### Install bpfilter using DNF Source: https://bpfilter.io/usage/index.html Installs the bpfilter package on Fedora 40+ and EPEL 9+ systems. Ensure you have the necessary package manager privileges. ```bash > sudo dnf install -y bpfilter ``` -------------------------------- ### Setup BTF Loading Source: https://bpfilter.io/external/coverage/libbpfilter/btf.c.gcov.html Initializes the global BTF structure by loading vmlinux BTF. Call this before using other BTF functions. Returns an error if loading fails. ```c int bf_btf_setup(void) { _bf_btf = btf__load_vmlinux_btf(); if (!_bf_btf) return bf_err_r(errno, "failed to load vmlinux BTF"); return 0; } ``` -------------------------------- ### Include Ordering Example Source: https://bpfilter.io/_sources/developers/style.rst.txt Group and order include directives: system headers, external library headers, and local project headers, separated by blank lines. ```c #include #include #include #include #include "cgen/program.h" #include "ctx.h" ``` -------------------------------- ### Setup BPFilter Context Source: https://bpfilter.io/external/coverage/libbpfilter/ctx.c.gcov.html Initializes and sets up the global BPFilter context. It creates a new context, acquires a lock on the pin directory, and discovers existing BPF chains. ```c int bf_ctx_setup(bool with_bpf_token, const char *bpffs_path, uint16_t verbose) { _cleanup_close_ int pindir_fd = -1; int r; r = _bf_ctx_new(&_bf_global_ctx, with_bpf_token, bpffs_path, verbose); if (r) return bf_err_r(r, "failed to create new context"); pindir_fd = bf_ctx_get_pindir_fd(); if (pindir_fd < 0) { _bf_ctx_free(&_bf_global_ctx); return bf_err_r(pindir_fd, "failed to get pin directory FD"); } r = flock(pindir_fd, LOCK_EX | LOCK_NB); if (r) { _bf_ctx_free(&_bf_global_ctx); return bf_err_r(-errno, "failed to lock pin directory"); } r = _bf_ctx_discover(); if (r) { _bf_ctx_free(&_bf_global_ctx); return bf_err_r(r, "failed to discover chains"); } _bf_global_ctx->lock_fd = TAKE_FD(pindir_fd); return 0; } ``` -------------------------------- ### Add New Matcher Test Example Source: https://bpfilter.io/_sources/developers/tests.rst.txt Example of how to create a new matcher test using the MatcherTestsSuite. This involves defining a test function and registering it with the suite. ```cpp #include "Chain.hpp" #include "Matcher.hpp" #include "Rule.hpp" #include "test.hpp" extern "C" { #include } static void my_matcher_eq(void **state) { auto *test = static_cast(*state); BFT_CHAIN_SET( bf::Chain("test_chain", test->hook(), BF_VERDICT_ACCEPT) << bf::Rule(BF_VERDICT_DROP, true, {}, {bf::Matcher(BF_MATCHER_MY_TYPE, BF_MATCHER_EQ, {42})})); // Packet matching the rule -> DROP bft_assert_prog_run( "test_chain", test->hook(), bft::Ethernet() / bft::IPv4 {.saddr = "127.0.0.1", .daddr = "127.0.0.2"} / bft::TCP {.dport = 42}, test->verdictDrop()); // Packet not matching -> ACCEPT (policy) bft_assert_prog_run( "test_chain", test->hook(), bft::Ethernet() / bft::IPv4 {.saddr = "127.0.0.1", .daddr = "127.0.0.2"} / bft::TCP {.dport = 80}, test->verdictAccept()); } int main() { auto suite = MatcherTestsSuite(BF_MATCHER_MY_TYPE); suite << MatcherTest(BF_MATCHER_MY_TYPE, BF_MATCHER_EQ, my_matcher_eq); return suite.run(); } ``` -------------------------------- ### Mock get Source: https://bpfilter.io/developers/tests.html Retrieves a mock object. ```c bft_mock_get ``` -------------------------------- ### Initialize and Teardown libbpfilter Context Source: https://bpfilter.io/developers/modules/libbpfilter/libbpfilter.html Always initialize the library context before using any other libbpfilter functions and tear it down when done. Calling other APIs before successful setup returns -EINVAL. ```c int r = bf_ctx_setup(false, "/sys/fs/bpf", 0); if (r < 0) // handle error // use bf_ruleset_*, bf_chain_*, ... bf_ctx_teardown(); ``` -------------------------------- ### Create an End-to-End Test Sandbox Source: https://bpfilter.io/developers/tests.html Example of an end-to-end test script that sets up a sandboxed environment using e2e_test_util.sh. Any shell command failure will immediately stop the test. ```bash #!/usr/bin/env bash set -eux set -o pipefail . "$(dirname "$0")"/../e2e_test_util.sh make_sandbox # Ping the sandbox's IPv4 address from the sandboxed namespace ${FROM_NS} ping -c 1 -W 0.1 ${NS_IP_ADDR} ``` -------------------------------- ### bf_ctx_setup Source: https://bpfilter.io/external/coverage/libbpfilter/ctx.c.gcov.html Sets up a new BPFilter context. This function initializes the context, discovers available chains, and acquires necessary locks for the pin directory. ```APIDOC ## bf_ctx_setup ### Description Initializes and sets up the BPFilter context. It creates a new context, obtains a file descriptor for the pin directory, locks it, and discovers available chains. ### Parameters - **with_bpf_token** (bool) - Flag to indicate if BPF token should be used. - **bpffs_path** (const char *) - Path to the BPF filesystem. - **verbose** (uint16_t) - Verbosity level for context operations. ### Returns - **int** - 0 on success, or a negative error code on failure. ``` -------------------------------- ### Set XDP Chain from String Source: https://bpfilter.io/usage/bfcli.html Create a new XDP chain using a string definition. This example creates an empty chain without attaching it to a hook. Requires sudo privileges. ```bash $ sudo bfcli chain set --from-str "chain my_xdp_chain BF_HOOK_XDP ACCEPT" ``` -------------------------------- ### Example: Anonymous Set with Multiple Key Components Source: https://bpfilter.io/usage/bfcli.html This example shows an anonymous set used in a rule, where the key consists of both IP address and protocol, with elements defined as comma-separated pairs. ```plaintext rule (ip4.saddr, ip4.proto) in { 192.168.1.1, tcp 192.168.1.10, udp # More can be added... } ACCEPT ``` -------------------------------- ### bf_program_error_counter_idx Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/program.h.gcov.html Gets the index of the counter used for errors. ```APIDOC ## bf_program_error_counter_idx ### Description Gets the index of the counter used for errors. ### Parameters #### Path Parameters - **program** (`const struct bf_program *`) - Not Applicable #### Query Parameters None #### Request Body None ### Return Value - The index of the error counter. ``` -------------------------------- ### bf_swich_init Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/swich.c.gcov.html Initializes a BPF switch structure with a given program and register. It also initializes a list for options and sets the default option to NULL. ```APIDOC ## bf_swich_init ### Description Initializes a BPF switch structure with a given program and register. It also initializes a list for options and sets the default option to NULL. ### Signature int bf_swich_init(struct bf_swich *swich, struct bf_program *program, int reg) ``` -------------------------------- ### bf_program_chain_counter_idx Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/program.h.gcov.html Gets the index of the counter used for the chain. ```APIDOC ## bf_program_chain_counter_idx ### Description Gets the index of the counter used for the chain. ### Parameters #### Path Parameters - **program** (`const struct bf_program *`) - Not Applicable #### Query Parameters None #### Request Body None ### Return Value - The index of the chain counter. ``` -------------------------------- ### Enable btf__load_vmlinux_btf mock Source: https://bpfilter.io/developers/tests.html Enables mocking of the btf__load_vmlinux_btf function. ```c bft_mock_btf__load_vmlinux_btf_enable() ``` -------------------------------- ### bf_program_error_counter_idx Source: https://bpfilter.io/developers/generation.html Gets the index of the error counter for the BPF program. ```APIDOC ## bf_program_error_counter_idx ### Description Gets the index of the error counter for the BPF program. ### Signature `size_t bf_program_error_counter_idx(const struct bf_program *program)` ``` -------------------------------- ### Generate XDP Program Prologue Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/xdp.c.gcov.html Generates the initial instructions for an XDP program, including packet size and interface index calculation. It relies on helper functions for dynamic pointer setup and header parsing. ```c static int _bf_xdp_gen_inline_prologue(struct bf_program *program) { int r; assert(program); // Calculate the packet size and store it into the runtime context EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data))); EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data_end))); EMIT(program, BPF_ALU64_REG(BPF_SUB, BPF_REG_3, BPF_REG_2)); EMIT(program, BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, BF_PROG_CTX_OFF(pkt_size))); // Store the ingress ifindex into the runtime context EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, ingress_ifindex))); EMIT(program, BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, BF_PROG_CTX_OFF(ifindex))); r = bf_stub_make_ctx_xdp_dynptr(program, BPF_REG_1); if (r) return r; r = bf_stub_parse_l2_ethhdr(program); if (r) return r; r = bf_stub_parse_l3_hdr(program); if (r) return r; r = bf_stub_parse_l4_hdr(program); if (r) return r; return 0; } ``` -------------------------------- ### bf_program_chain_counter_idx Source: https://bpfilter.io/developers/generation.html Gets the index of the chain counter for the BPF program. ```APIDOC ## bf_program_chain_counter_idx ### Description Gets the index of the chain counter for the BPF program. ### Signature `size_t bf_program_chain_counter_idx(const struct bf_program *program)` ``` -------------------------------- ### chain get Source: https://bpfilter.io/usage/bfcli.html Prints a specified chain, including its configuration and counters. ```APIDOC ## `chain get` ### Description Print a chain. ### Method GET (conceptual, CLI command) ### Endpoint N/A (CLI command) ### Parameters #### Query Parameters - **--name NAME** (string) - Required - name of the chain to print. ``` -------------------------------- ### Hashset Initialization and Includes Source: https://bpfilter.io/external/coverage/libbpfilter/core/hashset.c.gcov.html Includes necessary headers for hashset operations and defines constants for initial capacity, load factor, and maximum capacity. This forms the foundation for the hashset implementation. ```c #include "bpfilter/core/hashset.h" #include #include #include "bpfilter/helper.h" #include "bpfilter/logger.h" #define _BF_HASHSET_TOMBSTONE ((bf_hashset_elem *)1) #define _BF_HASHSET_INIT_CAP 16UL /* Maximum load factor before growing. Lowering this number reduces collisions * but causes higher memory usage. */ #define _BF_HASHSET_MAX_LOAD_NUM 5 #define _BF_HASHSET_MAX_LOAD_DEN 10 /* Largest power-of-two element count (2^60) that still leaves headroom for * load-factor arithmetic (slots_in_use * 10, cap * 5) without overflowing * size_t. */ #define _BF_HASHSET_MAX_CAP (SIZE_MAX / 16 + 1) ``` -------------------------------- ### Get Error Counter Index Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/program.h.gcov.html Returns the index of the counter used for program errors. ```c size_t bf_program_error_counter_idx(const struct bf_program *program); ``` -------------------------------- ### Load and Attach XDP Chain Source: https://bpfilter.io/usage/bfcli.html Demonstrates the sequence of loading an XDP chain and then attaching it to a specific interface index. ```bash sudo bfcli chain load --from-str "chain my_xdp_chain BF_HOOK_XDP ACCEPT" sudo bfcli chain attach --name my_xdp_chain --option ifindex=2 ``` -------------------------------- ### Get BPF Program Counter Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/program.h.gcov.html Retrieves a specific counter associated with a BPF program. ```c int bf_program_get_counter(const struct bf_program *program, uint32_t counter_idx, struct bf_counter *counter); ``` -------------------------------- ### Build 64-bit Immediate Comparison Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/matcher/cmp.c.gcov.html Builds a 64-bit comparison using immediate values, returning an error code if it fails. ```c r = _bf_cmp_build_imm64(program, BPF_REG_3, BPF_REG_4, _bf_read_u64(masked_hi)) ``` -------------------------------- ### bf_swich_init Source: https://bpfilter.io/developers/generation.html Initializes a bf_swich object, preparing it for adding cases and generating bytecode. ```APIDOC ## bf_swich_init(struct bf_swich *swich, struct bf_program *program, int reg) ### Description Initialise a bf_swich object. ### Parameters * **swich** – bf_swich object to initialize, can’t be NULL. * **program** – bf_program object to generate the switch-case for. Can’t be NULL. * **reg** – Register to compare to the cases of the switch. ### Returns 0 on success, or negative errno value on failure. ``` -------------------------------- ### Rule Mark Operations Source: https://bpfilter.io/developers/modules/libbpfilter/libbpfilter.html Functions for setting, getting, and checking if a mark is set on a rule. ```APIDOC ## bf_rule_mark_set ### Description Set a mark on the rule. ### Parameters * **rule** – Rule to set the mark on. * **mark** – The mark value to set. ## bf_rule_mark_get ### Description Get the mark set on the rule. ### Parameters * **rule** – Rule to get the mark from. ### Returns The mark value. ## bf_rule_mark_is_set ### Description Check if a mark is set on the rule. ### Parameters * **rule** – Rule to check. ### Returns True if a mark is set, false otherwise. ``` -------------------------------- ### Get syscall return value Source: https://bpfilter.io/developers/tests.html Retrieves the configured return value for mocked syscalls. ```c bft_mock_syscall_get_retval() ``` -------------------------------- ### Prepare and Allocate eBPF Stub Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/elfstub.c.gcov.html Prepares an eBPF stub by calling _bf_elfstub_prepare and allocates the stub using TAKE_PTR. Returns an error code if preparation fails. ```c r = _bf_elfstub_prepare(_stub, &_bf_rawstubs[id]); if (r) return r; *stub = TAKE_PTR(_stub); return 0; } ``` -------------------------------- ### Create New bpfilter Context Source: https://bpfilter.io/external/coverage/libbpfilter/ctx.c.gcov.html Initializes a new bpfilter context. It allocates memory, sets up BTF, and optionally creates a BPF token if requested. Errors during setup are returned as negative errno values. ```c static int _bf_ctx_new(struct bf_ctx **ctx, bool with_bpf_token, const char *bpffs_path, uint16_t verbose) { _free_bf_ctx_ struct bf_ctx *_ctx = NULL; int r; assert(ctx); assert(bpffs_path); _ctx = calloc(1, sizeof(*_ctx)); if (!_ctx) return -ENOMEM; r = bf_btf_setup(); if (r) return bf_err_r(r, "failed to load vmlinux BTF"); _ctx->with_bpf_token = with_bpf_token; _ctx->bpffs_path = bpffs_path; _ctx->verbose = verbose; _ctx->lock_fd = -1; _ctx->token_fd = -1; if (_ctx->with_bpf_token) { _cleanup_close_ int token_fd = -1; r = bf_btf_kernel_has_token(); if (r == -ENOENT) { bf_err( "--with-bpf-token requested, but this kernel doesn't support BPF token"); return r; } if (r) return bf_err_r(r, "failed to check for BPF token support"); token_fd = _bf_ctx_gen_token(_ctx->bpffs_path); if (token_fd < 0) return bf_err_r(token_fd, "failed to generate a BPF token"); _ctx->token_fd = TAKE_FD(token_fd); } _ctx->cgens = bf_list_default(bf_cgen_free, bf_cgen_pack); for (enum bf_elfstub_id id = 0; id < _BF_ELFSTUB_MAX; ++id) { r = bf_elfstub_new(&_ctx->stubs[id], id); if (r) return bf_err_r(r, "failed to create elfstub %d", id); } *ctx = _ctx; return 0; } ``` -------------------------------- ### Load New Ruleset Source: https://bpfilter.io/developers/modules/libbpfilter/libbpfilter.html Installs a new ruleset by flushing the existing one and applying the chains and hook options provided. Hook options must correspond to chains. Returns 0 on success or a negative error value on failure. ```c int bf_ruleset_set(bf_list *chains, bf_list *hookopts); ``` -------------------------------- ### Get a Netfilter Chain Source: https://bpfilter.io/usage/bfcli.html Prints a specified Netfilter chain. Requires the chain to be previously set. ```bash sudo bfcli chain get --name my_input_chain ``` -------------------------------- ### Initialize BPF Program Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/program.h.gcov.html Allocates and initializes a new `bf_program` object. Requires a valid program pointer, chain, and handle. ```c int bf_program_new(struct bf_program **program, const struct bf_chain *chain, struct bf_handle *handle); ``` -------------------------------- ### Get Chain Counter Index Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/program.h.gcov.html Returns the index of the counter used for the program's chain. ```c size_t bf_program_chain_counter_idx(const struct bf_program *program); ``` -------------------------------- ### Initialize BPF Switch Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/swich.c.gcov.html Initializes a BPF switch structure with a program and register. Sets up the options list. ```c int bf_swich_init(struct bf_swich *swich, struct bf_program *program, int reg) { assert(swich); assert(program); swich->program = program; swich->reg = reg; bf_list_init( &swich->options, (bf_list_ops[]) {{.free = (bf_list_ops_free)_bf_swich_option_free}}); swich->default_opt = NULL; return 0; } ``` -------------------------------- ### Create a test list with dummy data Source: https://bpfilter.io/developers/tests.html Creates a test list filled with dummy data. The list elements are pointers to size_t values ranging from 0 to len-1. It includes populated free and pack callbacks. ```c bf_list *bft_list_dummy(size_t len, bft_list_dummy_inserter inserter) ``` -------------------------------- ### Get Printer Message Length Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/printer.c.gcov.html Returns the length of a `bf_printer_msg`. Asserts that the message pointer is valid. ```c size_t bf_printer_msg_len(const struct bf_printer_msg *msg) { assert(msg); return msg->len; } ``` -------------------------------- ### Get Printer Message Offset Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/printer.c.gcov.html Returns the offset of a `bf_printer_msg`. Asserts that the message pointer is valid. ```c size_t bf_printer_msg_offset(const struct bf_printer_msg *msg) { assert(msg); return msg->offset; } ``` -------------------------------- ### Chain Operations Source: https://bpfilter.io/developers/modules/libbpfilter/libbpfilter.html Functions for setting, getting, loading, attaching, and updating individual BPF chains. ```APIDOC ## Chain Management ### Description Functions for managing individual BPF chains, including setting, retrieving, loading, attaching, and updating them. ### Functions #### `bf_chain_set` ```c int bf_chain_set(struct bf_chain *chain, struct bf_hookopts *hookopts) ``` **Description:** Sets a chain. If a chain with the same name exists, it is detached and unloaded before the new chain is loaded and attached (if `hookopts` are provided). **Parameters:** - `chain` (struct bf_chain*): The chain to set. Cannot be NULL. - `hookopts` (struct bf_hookopts*): Hook options to attach the chain. If NULL, the chain is not attached. **Returns:** 0 on success, or a negative errno value on failure. #### `bf_chain_get` ```c int bf_chain_get(const char *name, struct bf_chain **chain, struct bf_hookopts **hookopts, bf_list *counters) ``` **Description:** Retrieves a chain by its name. Populates the provided pointers with the chain, its hook options (if attached), and its rule counters. **Parameters:** - `name` (const char*): The name of the chain to look for. Cannot be NULL. - `chain` (struct bf_chain**): On success, points to the retrieved chain. The caller is responsible for freeing it. Cannot be NULL. - `hookopts` (struct bf_hookopts**): On success, points to the chain's hook options if attached, otherwise NULL. The caller is responsible for freeing it. Cannot be NULL. - `counters` (bf_list*): On success, this list will contain counters for each rule, plus policy and error counters. The caller is responsible for freeing it. Cannot be NULL. **Returns:** 0 on success, or a negative errno value on failure, including -ENOENT if no chain is found. #### `bf_chain_prog_fd` ```c int bf_chain_prog_fd(const char *name) ``` **Description:** Gets the file descriptor of a chain's BPF program. **Warning:** This function is intended for end-to-end tests and should be considered unstable. Direct manipulation of the BPF program may cause issues. This API may be disabled for non-test use cases in the future. **Parameters:** - `name` (const char*): The name of the chain to get the program from. **Preconditions:** - `name` is a non-NULL pointer to a C-string. **Returns:** File descriptor of the chain’s program, or a negative error value on failure. The caller owns the file descriptor and must close it. #### `bf_chain_logs_fd` ```c int bf_chain_logs_fd(const char *name) ``` **Description:** Gets the file descriptor of a chain's logs buffer. **Parameters:** - `name` (const char*): The name of the chain to get the log buffer from. **Preconditions:** - `name` is a non-NULL pointer to a C-string. **Returns:** File descriptor of the chain’s logs buffer, or a negative error value on failure. The caller owns the file descriptor and must close it. #### `bf_chain_load` ```c int bf_chain_load(struct bf_chain *chain) ``` **Description:** Loads a chain. If a chain with the same name already exists, -EEXIST is returned. **Parameters:** - `chain` (struct bf_chain*): The chain to load. Cannot be NULL. **Returns:** 0 on success, or a negative errno value on failure. #### `bf_chain_attach` ```c int bf_chain_attach(const char *name, const struct bf_hookopts *hookopts) ``` **Description:** Attaches a chain to a hook. If the chain does not exist, -ENOENT is returned. **Parameters:** - `name` (const char*): The name of the chain to attach. Cannot be NULL. - `hookopts` (const struct bf_hookopts*): Hook options to attach the chain. Cannot be NULL. **Returns:** 0 on success, or a negative errno value on failure, including -ENOENT (chain not found) and -EBUSY (chain already attached). #### `bf_chain_update` ```c int bf_chain_update(const struct bf_chain *chain) ``` **Description:** Updates an attached chain. The chain must exist and be attached to a hook. **Parameters:** - `chain` (const struct bf_chain*): The chain to update. Cannot be NULL. **Returns:** 0 on success, or a negative errno value on failure. ``` -------------------------------- ### Build with Nix Source: https://bpfilter.io/_sources/developers/build.rst.txt Commands to enter a Nix development environment or build the project using Nix flakes. This is an experimental feature. ```shell nix develop ``` ```shell nix build ``` -------------------------------- ### Get a randomly filled buffer Source: https://bpfilter.io/developers/tests.html Retrieves a buffer filled with random data of the specified length. ```c const void *bft_get_randomly_filled_buffer(size_t len) ``` -------------------------------- ### bfcli ruleset get Source: https://bpfilter.io/usage/bfcli.html Print the current ruleset, including all chains and rules with their associated counter values. ```APIDOC ## `ruleset get` Print the ruleset: request all the chains and rules with counters values. **Example** ``` $ sudo bfcli ruleset get chain my_tc_chain BF_HOOK_TC_INGRESS{ifindex=2} ACCEPT counters policy 87 packets 9085 bytes; error 0 packets 0 bytes rule ip4.saddr eq 0xc0 0xa8 0x01 0x01 0xff 0xff 0xff 0xff counters 2 packets 196 bytes ACCEPT ``` ``` -------------------------------- ### Load BPF Program Context and Initialize Dynamic Pointer Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/stub.c.gcov.html Loads the program context and prepares for dynamic pointer operations using BPF instructions. ```c EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_10, BF_PROG_CTX_OFF(l3_offset))); EMIT(program, BPF_MOV64_REG(BPF_REG_3, BPF_REG_10)); EMIT(program, BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, BF_PROG_CTX_OFF(l2))); EMIT_KFUNC_CALL(program, "bpf_dynptr_slice"); ``` -------------------------------- ### List Size and Emptiness Check Source: https://bpfilter.io/external/coverage/libbpfilter/include/bpfilter/core/list.h.gcov.html Utility functions to get the size of a list and check if it's empty. ```APIDOC ## bf_list_size ### Description Returns the number of nodes currently in the list. ### Parameters - **list** (const bf_list \*) - The initialized list. Must be non-NULL. ### Return Value Number of nodes in the list. ``` ```APIDOC ## bf_list_is_empty ### Description Checks if the list contains any nodes. ### Parameters - **list** (const bf_list \*) - The initialized list. Must be non-NULL. ### Return Value True if the list is empty, false otherwise. ``` -------------------------------- ### Get BPF Jump Context Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/matcher/cmp.c.gcov.html Retrieves the jump context for BPF instructions, used for conditional branching. ```c j0 = bf_jmpctx_get(program, BPF_JMP_REG(BPF_JNE, reg, BPF_REG_3, 0)) ``` ```c j1 = bf_jmpctx_get(program, BPF_JMP_REG(BPF_JNE, reg + 1, BPF_REG_3, 0)) ``` -------------------------------- ### Allocate and initialize a new printer context Source: https://bpfilter.io/developers/generation.html Allocates and initializes a new printer context. Returns 0 on success or a negative errno value on failure. ```c int bf_printer_new(struct bf_printer **printer) ``` -------------------------------- ### Forward Declaration Example Source: https://bpfilter.io/_sources/developers/style.rst.txt Use forward declarations for types when only a pointer is needed to reduce include dependencies. ```c struct bf_chain; struct bf_program; ``` -------------------------------- ### bf_hashset_init Source: https://bpfilter.io/external/coverage/libbpfilter/core/hashset.c.gcov.html Initializes an existing hashset structure. ```APIDOC ## bf_hashset_init ### Description Initializes an already allocated `bf_hashset` structure with the provided operations and context. ### Signature ```c void bf_hashset_init(bf_hashset *set, const bf_hashset_ops *ops, void *ctx) ``` ### Parameters - **set** (*bf_hashset *): A pointer to the `bf_hashset` structure to initialize. - **ops** (*const bf_hashset_ops *): A pointer to the hashset operations structure. - **ctx** (*void *): A generic context pointer. ``` -------------------------------- ### bf_program_new Source: https://bpfilter.io/developers/generation.html Allocates and initializes a new `bf_program` object. This function is essential for starting the bytecode generation process. ```APIDOC ## bf_program_new ### Description Allocate and initialize a new `bf_program` object. ### Parameters * **program** (struct bf_program **) - `bf_program` object to allocate and initialize. Can’t be NULL. * **chain** (const struct bf_chain *) - Chain the program is generated from. Can’t be NULL. * **handle** (struct bf_handle *) - Handle to store BPF object references in. The program borrows this pointer (non-owning). Can’t be NULL. ### Returns 0 on success, or a negative error value on failure. ``` -------------------------------- ### bf_list_default_from Source: https://bpfilter.io/external/coverage/libbpfilter/include/bpfilter/core/list.h.gcov.html Initializes a new `bf_list` by copying the operations from an existing list. ```APIDOC ## bf_list_default_from ### Description Returns an initialized `bf_list` from an existing list. The returned list will be initialized with the callbacks defined in the source `list`'s operations. ### Parameters - **list** (`bf_list`) - Source list to initialize from. ### Returns An initialized `bf_list`. ``` -------------------------------- ### Get Chain Logs Source: https://bpfilter.io/usage/bfcli.html Prints log entries for a specified chain. bfcli continuously prints logs until interrupted. ```bash sudo bfcli chain logs --name my_input_chain ``` -------------------------------- ### Implement a Unit Test with CMocka Source: https://bpfilter.io/developers/tests.html Example of a unit test for the bf_version() function using the CMocka testing library. All test files must include 'test.h', define a main function, and register tests with cmocka_run_group_tests. ```c /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ #include #include "test.h" static void get_version(void **state) { (void)state; assert_non_null(bf_version()); } int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(get_version), }; return cmocka_run_group_tests(tests, NULL, NULL); } ``` -------------------------------- ### Build 64-bit Immediate Value in BPF Program Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/matcher/cmp.c.gcov.html Emits a 4-instruction sequence to construct a 64-bit immediate value from 8 bytes. It uses a destination register, a scratch register, and the 64-bit data to load. ```c static int _bf_cmp_build_imm64(struct bf_program *program, int dst_reg, ``` -------------------------------- ### Get Node Data in bpfilter List Source: https://bpfilter.io/external/coverage/libbpfilter/include/bpfilter/core/list.h.gcov.html Retrieves the data associated with a list node. Asserts that the node is not NULL. ```c static inline void *bf_list_node_get_data(const bf_list_node *node) { assert(node); return node->data; } ``` -------------------------------- ### Get Element from Vector Source: https://bpfilter.io/external/coverage/libbpfilter/core/vector.c.gcov.html Retrieves a pointer to an element at a specific index in the vector. Returns NULL if the index is out of bounds. ```c void *bf_vector_get(const bf_vector *vec, size_t index) { assert(vec); if (index >= vec->size) return NULL; return vec->data + (index * vec->elem_size); } ``` -------------------------------- ### Prepare ELF Stub Structure Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/elfstub.c.gcov.html Initializes a `bf_elfstub` structure by parsing the provided raw ELF data. Validates the ELF header for size and magic number, and checks for 64-bit compatibility. ```c static int _bf_elfstub_prepare(struct bf_elfstub *stub, const struct bf_rawstub *raw) { const Elf64_Ehdr *ehdr = raw->elf; Elf64_Shdr *shstrtab; Elf64_Shdr *shdrs; Elf64_Shdr *symtab = NULL; Elf64_Shdr *symstrtab = NULL; Elf64_Shdr *rodata_shdr = NULL; Elf64_Sym *symbols; char *sym_strtab; size_t sym_count; char *strtab; int r; if (raw->len < sizeof(Elf64_Ehdr)) return bf_err_r(-EINVAL, "invalid ELF header (wrong header size)"); // Check ELF magic if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) return bf_err_r(-EINVAL, "invalid ELF header (wrong magic number)"); // Ensure 64-bit ELF if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) ``` -------------------------------- ### Flush Current Ruleset Source: https://bpfilter.io/developers/modules/libbpfilter/libbpfilter.html Removes the currently installed ruleset. Returns 0 on success or a negative error value on failure. ```c int bf_ruleset_flush(void); ``` -------------------------------- ### Create BPF Switch Option Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/swich.c.gcov.html Allocates and initializes a new BPF switch option. Ensure sufficient memory is available. ```c static struct bf_swich_option *_bf_swich_option_new(uint32_t imm, const struct bpf_insn *insns, size_t insns_len) { struct bf_swich_option *_option = NULL; int r; _option = malloc(sizeof(*_option) + (sizeof(struct bpf_insn) * insns_len)); if (!_option) return -ENOMEM; _option->imm = imm; _option->insns_len = insns_len; memcpy(_option->insns, insns, sizeof(struct bpf_insn) * insns_len); *option = TAKE_PTR(_option); return 0; } ``` -------------------------------- ### Initialize Source Port Matcher Metadata Source: https://bpfilter.io/external/coverage/libbpfilter/matcher.c.gcov.html Initializes the metadata for the source port matcher, including unsupported hooks and operations for equality and range checks. ```c [BF_MATCHER_META_SPORT] = { .layer = BF_MATCHER_NO_LAYER, .unsupported_hooks = BF_FLAGS(_BF_HOOKS_CGROUP_SOCK_ADDR_ALL), .ops = { BF_MATCHER_OPS(BF_MATCHER_EQ, sizeof(uint16_t), _bf_parse_l4_port, _bf_print_l4_port), BF_MATCHER_OPS(BF_MATCHER_RANGE, 2 * sizeof(uint16_t), _bf_parse_l4_port_range, _bf_print_l4_port_range), }, } ``` -------------------------------- ### Get TC Chain Source: https://bpfilter.io/usage/bfcli.html Retrieve and display the definition and counters for a specific TC chain by its name. Requires sudo privileges. ```bash $ sudo bfcli chain get --name my_tc_chain chain my_tc_chain BF_HOOK_TC_INGRESS{ifindex=2} ACCEPT counters policy 35 packets 4091 bytes; error 0 packets 0 bytes ``` -------------------------------- ### Get XDP Chain Source: https://bpfilter.io/usage/bfcli.html Retrieve and display the definition and counters for a specific XDP chain by its name. Requires sudo privileges. ```bash $ sudo bfcli chain get --name my_xdp_chain chain my_xdp_chain BF_HOOK_XDP ACCEPT counters policy 0 packets 0 bytes; error 0 packets 0 bytes ``` -------------------------------- ### Initialize bf_swich Object Source: https://bpfilter.io/developers/generation.html Use bf_swich_get to simplify the creation and initialization of a bf_swich object. This object holds the program and the register for comparison. ```c #include struct bf_program *program; struct bf_swich *swich; swich = bf_swich_get(program, 1); ``` -------------------------------- ### Get Ruleset Source: https://bpfilter.io/_sources/usage/bfcli.rst.txt Retrieves and prints the current ruleset, including all chains, rules, and their associated counter values. Requires sudo privileges. ```shell $ sudo bfcli ruleset get ``` -------------------------------- ### Create a dummy chain Source: https://bpfilter.io/developers/tests.html Creates a dummy bf_chain structure. Optionally includes rules. ```c struct bf_chain *bft_chain_dummy(bool with_rules) ``` -------------------------------- ### Create new temporary directory Source: https://bpfilter.io/developers/tests.html Creates a new temporary directory for testing purposes. ```c bft_tmpdir_new() ``` -------------------------------- ### Get BPFilter Matcher Metadata Source: https://bpfilter.io/external/coverage/libbpfilter/matcher.c.gcov.html Retrieves the metadata for a BPFilter matcher based on its type. Returns NULL if the type is out of bounds or if the matcher is undefined. ```c const struct bf_matcher_meta *bf_matcher_get_meta(enum bf_matcher_type type) { if (type < 0 || _BF_MATCHER_TYPE_MAX <= type) return NULL; return _bf_matcher_metas[type].layer == _BF_MATCHER_LAYER_UNDEFINED ? NULL : &_bf_matcher_metas[type]; } ``` -------------------------------- ### Get CGen Counters Source: https://bpfilter.io/external/coverage/libbpfilter/cgen/cgen.c.gcov.html Retrieves policy and error counters associated with a CGen chain. Handles iteration over rules and specific counter indices. ```c int bf_cgen_get_counters(const struct bf_cgen *cgen, bf_list *counters) { bf_list _counters; int r; assert(cgen); assert(counters); _counters = bf_list_default_from(*counters); /* Iterate over all the rules, then the policy counter (size(rules)) and * the errors counters (sizeof(rules) + 1)*/ for (size_t i = 0; i < bf_list_size(&cgen->chain->rules) + 2; ++i) { _free_bf_counter_ struct bf_counter *counter = NULL; ssize_t idx = (ssize_t)i; if (i == bf_list_size(&cgen->chain->rules)) idx = BF_COUNTER_POLICY; else if (i == bf_list_size(&cgen->chain->rules) + 1) idx = BF_COUNTER_ERRORS; r = bf_counter_new(&counter, 0, 0); if (r) return r; r = bf_cgen_get_counter(cgen, idx, counter); if (r) return r; r = bf_list_add_tail(&_counters, counter); if (r) return r; TAKE_PTR(counter); } *counters = bf_list_move(_counters); return 0; } ``` -------------------------------- ### Initialize a New Bf Wpack Structure Source: https://bpfilter.io/external/coverage/libbpfilter/pack.c.gcov.html Creates and initializes a new bf_wpack_t structure, which is used for packing data with mpack. It sets up the writer, a custom flush callback, and begins building a map. Ensure you handle the returned pointer to avoid memory leaks. ```c int bf_wpack_new(bf_wpack_t **pack) { bf_wpack_t *_pack = NULL; assert(pack); _pack = malloc(sizeof(*_pack)); if (!_pack) return -ENOMEM; _pack->data = NULL; _pack->data_cap = 0; _pack->data_len = 0; mpack_writer_init(&_pack->writer, _pack->buffer, 64); /* Use a custom flush function so we can control the flush * (e.g. when get_data() is called). */ mpack_writer_set_flush(&_pack->writer, _bf_wpack_writer_flush_cb); mpack_writer_set_context(&_pack->writer, _pack); mpack_build_map(&_pack->writer); *pack = TAKE_PTR(_pack); return 0; } ``` -------------------------------- ### Get bpfilter Codegen by Name Source: https://bpfilter.io/external/coverage/libbpfilter/ctx.c.gcov.html Retrieves a specific codegen from the bpfilter context by its name. It iterates through the list of codegens and returns the matching one. ```c static struct bf_cgen *_bf_ctx_get_cgen(const struct bf_ctx *ctx, const char *name) { assert(ctx); assert(name); bf_list_foreach (&ctx->cgens, cgen_node) { struct bf_cgen *cgen = bf_list_node_get_data(cgen_node); if (bf_streq(cgen->chain->name, name)) ``` -------------------------------- ### bf_fnv1a_init Source: https://bpfilter.io/external/coverage/libbpfilter/include/bpfilter/helper.h.gcov.html Initializes the FNV-1a 64-bit hash computation. ```APIDOC ## bf_fnv1a_init ### Description Provides the initial hash value for FNV-1a 64-bit hashing. ### Returns - **uint64_t** - The initial hash value to pass to `bf_fnv1a()`. ```