API reference#
-
struct bf_codegen#
-
Codegen are used to represent filtering rules to be applied for a given front, at a given location in the network stack. It contains a list of programs, which are BPF program aimed to be attached to a given interface. Hence, not all rules have to target all interfaces.
Public Members
-
enum bf_front front#
Source of the filtering rules.
-
enum bf_verdict policy#
Codegen policy: verdict to be applied by default by the codegen, unless one of the rules matches the packet.
-
enum bf_front front#
-
struct bf_context#
- #include </__w/bpfilter/bpfilter/src/core/context.h>
bpfilter working context. Only one context is used during the daemon’s lifetime.
Public Members
-
struct bf_codegen *codegens[_BF_HOOK_MAX][_BF_FRONT_MAX]#
Codegens used by bpfilter. One codegen per (hook, front) set.
-
struct bf_codegen *codegens[_BF_HOOK_MAX][_BF_FRONT_MAX]#
-
struct bf_counter#
- #include </__w/bpfilter/bpfilter/src/core/counter.h>
Counters assigne to each rule.
-
struct bf_fixup#
- #include </__w/bpfilter/bpfilter/src/generator/fixup.h>
Public Members
-
enum bf_fixup_type type#
-
size_t insn#
-
size_t offset#
-
enum bf_fixup_function function#
- union bf_fixup
-
enum bf_fixup_type type#
-
union bf_fixup_attr#
- #include </__w/bpfilter/bpfilter/src/generator/fixup.h>
Attributes to use when processing the fixups.
-
union bf_flavor_attach_attr#
- #include </__w/bpfilter/bpfilter/src/core/flavor.h>
Extra attribute to share between call during 2-steps attach.
Public Members
-
int pre_unload_link_fd#
File descriptor of the link created before the existing program has been detached.
-
int pre_unload_link_fd#
-
struct bf_flavor_ops#
- #include </__w/bpfilter/bpfilter/src/core/flavor.h>
Define a set of operations that can be performed for a specific BPF flavor.
Public Members
-
int (*gen_inline_prologue)(struct bf_program *program)#
Generate the flavor-specific prologue of the BPF program.
This function can assume BF_ARG_1 contains the first argument passed to the program, and BF_REG_CTX is properly set, pointing to an initialised context.
The purpose of this callback is to:
Ensure ctx.dynptr is a valid BPF dynptr to the packet data.
ctx.pkt_size contains the packet size.
BPF dynptr slices to layer 2, 3, and 4 (if relevant) are stored within the context, and BF_REG_L{2, 3, 4} are updated to contain the address of the relevant header.
-
int (*gen_inline_epilogue)(struct bf_program *program)#
Generate the epilogue of the BPF program.
-
int (*get_verdict)(enum bf_verdict verdict)#
-
int (*attach_prog_pre_unload)(struct bf_program *program, int *prog_fd, union bf_flavor_attach_attr *attr)#
Attach a loaded BPF program to the kernel, before unloading the out-of-date program.
There are two callbacks used to attach a program for a given flavor, which are used to ensure the new program is attached before the existing program (attached to the same hook) is detached. attach_prog_pre_unload is called before the existing program is detached and unloaded, attach_prog_post_unload is called once the existing program has been detached from the kernel and unloaded.
This 2-steps process is mandatory for specific flavor (e.g. netfilter), as we want to avoid downtime, while ensuring a given program (for a specific hook and interface) will always use the same priority.
- Param program:
Program to attach.
- Param prog_fd:
File descriptor of the loaded program.
- Param attr:
Extra attribute to share between call during 2-steps attach.
- Return:
0 on success, negative ernno code on failure.
-
int (*attach_prog_post_unload)(struct bf_program *program, int *prog_fd, union bf_flavor_attach_attr *attr)#
Attach a loaded BPF program to the kernel, after the out-of-date program has been detached.
See attach_prog_pre_unload for details.
- Param program:
Program to attach.
- Param prog_fd:
File descriptor of the loaded program.
- Param attr:
Extra attribute to share between call during 2-steps attach.
- Return:
0 on success, negative ernno code on failure.
-
int (*detach_prog)(struct bf_program *program)#
-
int (*gen_inline_prologue)(struct bf_program *program)#
-
struct bf_front_ops#
- #include </__w/bpfilter/bpfilter/src/xlate/front.h>
Public Members
-
int (*setup)(void)#
struct bf_front_ops
- Todo:
Make bf_front_ops.request_handler take a const struct bf_request.
Setup the front.
-
int (*teardown)(void)#
Teardown the front.
-
int (*request_handler)(struct bf_request *request, struct bf_response **response)#
Handle a request.
-
int (*setup)(void)#
-
struct bf_ipt_cache#
-
struct bf_jmpctx
- #include </__w/bpfilter/bpfilter/src/generator/jmp.h>
Public Members
-
struct bf_program *program
A helper structure to manage jump instructions in the program.
The program to emit the jump instruction to.
-
size_t insn_idx
The index of the jump instruction in the program’s image.
-
struct bf_program *program
-
struct bf_list#
- #include </__w/bpfilter/bpfilter/src/core/list.h>
Base structure for the doubly-linked-list data structure.
Warning
From the user’s perspective, the inside of this structure should not be directly accessed. Directly modifying any of the fields should be considered undefined behavior.
Public Members
-
size_t len#
Number of elements in the list.
-
bf_list_node *head#
First element of the list, NULL if the list is empty.
-
bf_list_node *tail#
Last element of the list, NULL if the list is empty.
-
bf_list_ops ops#
-
size_t len#
-
struct bf_list_node#
- #include </__w/bpfilter/bpfilter/src/core/list.h>
Node composing a bf_list.
Warning
From the user’s perspective, the inside of this structure should not be directly accessed. Directly modifying any of the fields should be considered undefined behavior.
Public Members
-
void *data#
The node’s data.
-
bf_list_node *prev#
Pointer to the previous node. Can be NULL if node is first.
-
bf_list_node *next#
Pointer to the next node. Can be NULL if node is last.
-
void *data#
-
struct bf_list_ops#
- #include </__w/bpfilter/bpfilter/src/core/list.h>
Operation to manipulate bf_list data.
Public Members
-
bf_list_ops_free free#
Free the data stored in a node. Should be able to handle NULL data.
-
bf_list_ops_free free#
-
struct bf_marsh#
- #include </__w/bpfilter/bpfilter/src/core/marsh.h>
-
struct bf_match#
- #include </__w/bpfilter/bpfilter/src/core/match.h>
-
struct bf_match_ops#
- #include </__w/bpfilter/bpfilter/src/core/match.h>
-
struct bf_nfgroup#
-
struct bf_nfnest
- #include </__w/bpfilter/bpfilter/src/xlate/nft/nfmsg.h>
-
struct bf_options#
bpfilter runtime configuration
Public Members
-
bool transient#
If true, bpfilter won’t load or save its state to the filesystem, and all the loaded BPF programs will be unloaded before shuting down. Hence, as long as bpfilter is running, filtering rules will be applied. When bpfilter is stopped, everything is cleaned up.
-
unsigned int bpf_log_buf_len_pow#
Size of the log buffer when loading a BPF program, as a power of 2.
-
uint16_t fronts#
Bit flags for enabled fronts.
-
bool verbose#
If true, print debug log messages (bf_debug).
-
bool transient#
-
struct bf_program#
-
Public Members
-
uint32_t ifindex#
-
enum bf_front front#
-
char prog_name[BPF_OBJ_NAME_LEN]#
-
char map_name[BPF_OBJ_NAME_LEN]#
-
char prog_pin_path[PIN_PATH_LEN]#
-
char map_pin_path[PIN_PATH_LEN]#
-
size_t num_counters#
Number of counters in the counters map. Not all of them are used by the program, but this value is common for all the programs of a given codegen.
-
uint32_t functions_location[_BF_CODEGEN_FIXUP_FUNCTION_MAX]#
-
struct bpf_insn *img#
-
size_t img_size#
-
size_t img_cap#
-
int prog_fd#
File descriptor of the program.
-
int map_fd#
File descriptor of the counters map.
-
const struct bf_flavor_ops *ops#
Hook-specific ops to use to generate the program.
-
struct bf_program runtime#
Runtime data used to interact with the program and cache information. This data is not serialized.
-
uint32_t ifindex#
-
struct bf_program_context#
-
BPF program runtime context.
This structure is used to map data located in the first frame of the generated BPF program. Address to this structure will be stored in BF_REG_CTX register, and fields can be accessed using the convenience macro BF_PROG_CTX_OFF.
Layer 2, 3, and 4 headers are stored in an anonymous union, accessed through the field named
lXraw
. The various header structures stored in anonymous union are used to ensurelXraw
is big enough to store any supported header.Warning
A static assertion is defined to ensure this structure is aligned on 8-bytes boundaries. This is required by bf_stub_memclear.
Public Members
-
void *arg#
Argument passed to the BPF program, it content depends on the BPF program type.
-
struct bpf_dynptr dynptr#
BPF dynamic pointer representing the packet data. Dynamic pointers are used with every program type.
-
uint64_t pkt_size#
Total size of the packet.
-
uint32_t l3_offset#
Offset of the layer 3 header in the packet.
-
uint32_t l4_offset#
Offset of the layer 4 header in the packet.
-
uint8_t l4_proto#
Layer 4 protocol. Set when the L3 header is processed. Used to define how many bytes to read when processing the packet.
-
struct ethhdr _ethhdr#
-
char l2raw#
- union bf_program_context
Layer 2 header.
-
struct iphdr _iphdr#
-
char l3raw#
- union bf_program_context
Layer 3 header.
-
struct icmphdr _icmphdr#
-
struct udphdr _udphdr#
-
struct tcphdr _tcphdr#
-
char l4raw#
- union bf_program_context
Layer 4 header.
-
void *arg#
-
struct bf_rule#
- #include </__w/bpfilter/bpfilter/src/core/rule.h>
Represents a rule to match against packets.
- file bpf.c
- #include “core/bpf.h”#include <net/if.h>#include <linux/bpf.h>#include <linux/netfilter.h>#include <errno.h>#include <stdint.h>#include <stdio.h>#include <sys/syscall.h>#include <unistd.h>#include “core/logger.h”#include “generator/nf.h”#include “opts.h”#include “shared/helper.h”
Defines
-
_bf_ptr_to_u64(ptr)#
Functions
-
static int _bpf(enum bpf_cmd cmd, union bpf_attr *attr)#
BPF system call.
- Parameters:
cmd – BPF command to run.
attr – Attributes of the system call.
- Returns:
System call return value on success, or negative errno value on failure.
-
int bf_bpf_prog_load(const char *name, unsigned int prog_type, void *img, size_t img_len, enum bpf_attach_type attach_type, int *fd)#
Load a BPF program.
- Parameters:
name – Name of the BPF program. Can’t be NULL.
prog_type – BPF program type.
img – BPF program itself. Can’t be NULL.
img_len – Size of the BPF program, as a number of instructions.
expected_attach_type – Expected attach type of the BPF program. Use bf_hook_to_attach_type to get the proper attach type. 0 is a valid value.
fd – If the call succeed, this parameter will contain the loaded program’s file descriptor.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_map_create(const char *name, unsigned int type, size_t key_size, size_t value_size, size_t max_entries, uint32_t flags, int *fd)#
Create a BPF map.
- Parameters:
name – Name of the map. Can’t be NULL.
type – Map type.
key_size – Size of a key.
value_size – Size of a value.
max_entries – Number of entries in the map.
flags – Map creation flags.
fd – If the call succeed, this parameter will contain the map’s file descriptor.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_map_freeze(int fd)#
Freeze a BPF map.
A frozen map can’t be modified from userspace.
- Parameters:
fd – File descriptor of the map.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_map_lookup_elem(int fd, const void *key, void *value)#
Get an element from a map.
- Parameters:
fd – File descriptor of the map to search in.
key – Key to get the value for. Can’t be NULL.
value – Pointer to the value.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_map_update_elem(int fd, const void *key, void *value)#
Update (or insert) an element in a map.
- Parameters:
fd – File descriptor of the map to search in.
key – Key to get the value for. Can’t be NULL.
value – Pointer to the value.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_obj_pin(const char *path, int fd)#
Pin a BPF object to a given path.
- Parameters:
path – Path to pin the object to. Can’t be NULL.
fd – File descriptor of the map.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_obj_get(const char *path, int *fd)#
Get a BPF object, from a path.
- Parameters:
path – Path of the BPF object to get. Can’t be NULL.
fd – On success, contains a file descriptor to the BPF object.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_nf_link_create(int prog_fd, enum bf_hook hook, int priority, int *link_fd)#
Create a Netfilter BPF link.
- Parameters:
prog_fd – File descriptor of the program to attach to the link.
hook – Netfilter hook to attach the program to.
priority – Priority of the program on the hook.
link_fd – Link file descriptor, only valid if the return value of the function is 0.
- Returns:
0 on success or negative errno value on failure.
-
int bf_bpf_xdp_link_create(int prog_fd, int ifindex, int *link_fd, enum bf_xdp_attach_mode mode)#
Create a XDP BPF link.
- Parameters:
prog_fd – File descriptor of the program to attach to the link.
ifindex – Interface index to attach the program to.
link_fd – Link file descriptor, only valid if the return value of the function is 0.
mode – XDP program attach mode. See bf_xdp_attach_mode.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_link_detach(int link_fd)#
Detach a BPF link using its file descriptor.
- Parameters:
link_fd – File descriptor of the link to detach. You can get a file descriptor using bf_bpf_obj_get.
- Returns:
0 on success or negative errno value on failure.
-
_bf_ptr_to_u64(ptr)#
- file bpf.h
- #include <linux/if_link.h>#include <stddef.h>#include <stdint.h>#include “core/hook.h”
Enums
Functions
-
int bf_bpf_prog_load(const char *name, unsigned int prog_type, void *img, size_t img_len, enum bpf_attach_type attach_type, int *fd)
Load a BPF program.
- Parameters:
name – Name of the BPF program. Can’t be NULL.
prog_type – BPF program type.
img – BPF program itself. Can’t be NULL.
img_len – Size of the BPF program, as a number of instructions.
expected_attach_type – Expected attach type of the BPF program. Use bf_hook_to_attach_type to get the proper attach type. 0 is a valid value.
fd – If the call succeed, this parameter will contain the loaded program’s file descriptor.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_map_create(const char *name, unsigned int type, size_t key_size, size_t value_size, size_t max_entries, uint32_t flags, int *fd)
Create a BPF map.
- Parameters:
name – Name of the map. Can’t be NULL.
type – Map type.
key_size – Size of a key.
value_size – Size of a value.
max_entries – Number of entries in the map.
flags – Map creation flags.
fd – If the call succeed, this parameter will contain the map’s file descriptor.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_map_freeze(int fd)
Freeze a BPF map.
A frozen map can’t be modified from userspace.
- Parameters:
fd – File descriptor of the map.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_map_lookup_elem(int fd, const void *key, void *value)
Get an element from a map.
- Parameters:
fd – File descriptor of the map to search in.
key – Key to get the value for. Can’t be NULL.
value – Pointer to the value.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_map_update_elem(int fd, const void *key, void *value)
Update (or insert) an element in a map.
- Parameters:
fd – File descriptor of the map to search in.
key – Key to get the value for. Can’t be NULL.
value – Pointer to the value.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_obj_pin(const char *path, int fd)
Pin a BPF object to a given path.
- Parameters:
path – Path to pin the object to. Can’t be NULL.
fd – File descriptor of the map.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_obj_get(const char *path, int *fd)
Get a BPF object, from a path.
- Parameters:
path – Path of the BPF object to get. Can’t be NULL.
fd – On success, contains a file descriptor to the BPF object.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_nf_link_create(int prog_fd, enum bf_hook hook, int priority, int *link_fd)
Create a Netfilter BPF link.
- Parameters:
prog_fd – File descriptor of the program to attach to the link.
hook – Netfilter hook to attach the program to.
priority – Priority of the program on the hook.
link_fd – Link file descriptor, only valid if the return value of the function is 0.
- Returns:
0 on success or negative errno value on failure.
-
int bf_bpf_xdp_link_create(int prog_fd, int ifindex, int *link_fd, enum bf_xdp_attach_mode mode)
Create a XDP BPF link.
- Parameters:
prog_fd – File descriptor of the program to attach to the link.
ifindex – Interface index to attach the program to.
link_fd – Link file descriptor, only valid if the return value of the function is 0.
mode – XDP program attach mode. See bf_xdp_attach_mode.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_bpf_link_detach(int link_fd)
Detach a BPF link using its file descriptor.
- Parameters:
link_fd – File descriptor of the link to detach. You can get a file descriptor using bf_bpf_obj_get.
- Returns:
0 on success or negative errno value on failure.
-
int bf_bpf_prog_load(const char *name, unsigned int prog_type, void *img, size_t img_len, enum bpf_attach_type attach_type, int *fd)
- file btf.c
- #include “core/btf.h”#include <bpf/btf.h>#include <errno.h>#include <stdlib.h>#include “core/logger.h”#include “shared/helper.h”
Functions
-
int bf_btf_setup(void)#
Load current kernel’s BTF data.
This function has to be called early, so BPF program generation can access kernel’s BTF data and use the kfunc’s BTF ID.
- Returns:
0 on success, or negative errno value on failure.
-
void bf_btf_teardown(void)#
Free current kernel’s BTF data.
-
int bf_btf_get_id(const char *name)#
Get BTF ID of a kernel function.
Linux’ BTF data must be loaded with bf_btf_setup before calling this function.
- Parameters:
name – Name of the kernel function.
- Returns:
BTF ID on success, or negative errno value on failure.
-
int bf_btf_get_field_off(const char *struct_name, const char *field_name)#
Get the offset of a field in a kernel structure.
Use Linux’ BTF data to find the offset of a specific field in a structure. This function will fail if the offset of a bitfield is requested.
- Parameters:
struct_name – Name of the structure to find the offset in. Can’t be NULL.
field_name – Name of the field to get the offset of. Can’t be NULL.
- Returns:
Offset of
field_name
if found, negative error value on failure.
Variables
-
static struct btf *_btf = NULL#
-
int bf_btf_setup(void)#
- file btf.h
Functions
-
int bf_btf_setup(void)
Load current kernel’s BTF data.
This function has to be called early, so BPF program generation can access kernel’s BTF data and use the kfunc’s BTF ID.
- Returns:
0 on success, or negative errno value on failure.
-
void bf_btf_teardown(void)
Free current kernel’s BTF data.
-
int bf_btf_get_id(const char *name)
Get BTF ID of a kernel function.
Linux’ BTF data must be loaded with bf_btf_setup before calling this function.
- Parameters:
name – Name of the kernel function.
- Returns:
BTF ID on success, or negative errno value on failure.
-
int bf_btf_get_field_off(const char *struct_name, const char *field_name)
Get the offset of a field in a kernel structure.
Use Linux’ BTF data to find the offset of a specific field in a structure. This function will fail if the offset of a bitfield is requested.
- Parameters:
struct_name – Name of the structure to find the offset in. Can’t be NULL.
field_name – Name of the field to get the offset of. Can’t be NULL.
- Returns:
Offset of
field_name
if found, negative error value on failure.
-
int bf_btf_setup(void)
- file context.c
- #include “context.h”#include <errno.h>#include <stdlib.h>#include “core/logger.h”#include “core/marsh.h”#include “generator/codegen.h”#include “shared/helper.h”
Defines
-
_cleanup_bf_context_#
Functions
-
static void _bf_context_free(struct bf_context **context)#
Free a context.
If
context
points to a NULL pointer, this function does nothing. Once the function returns,context
points to a NULL pointer.- Parameters:
context – Context to free. Can’t be NULL.
-
static int _bf_context_new(struct bf_context **context)#
Create and initialize a new context.
On failure,
context
is left unchanged.- Parameters:
context – New context to create. Can’t be NULL.
- Returns:
0 on success, negative errno value on failure.
-
static void _bf_context_dump(const struct bf_context *context, prefix_t *prefix)#
See bf_context_dump for details.
-
static int _bf_context_marsh(const struct bf_context *context, struct bf_marsh **marsh)#
Marsh a context.
If the function succeeds,
marsh
will contain the marshalled context.- Parameters:
context – Context to marsh.
marsh – Marsh’d context.
- Returns:
0 on success, negative errno value on failure.
-
static int _bf_context_unmarsh(const struct bf_marsh *marsh, struct bf_context **context)#
Unmarsh a context.
marsh
is expected to be valid, that ismarsh.data_len
argument is within bound regarding actual size ofmarsh
.- Parameters:
marsh – Marsh’d context to restore.
context – Restored context.
- Returns:
0 on success, negative errno value on failure.
-
static struct bf_codegen *_bf_context_get_codegen(const struct bf_context *context, enum bf_hook hook, enum bf_front front)#
See bf_context_get_codegen for details.
-
static struct bf_codegen *_bf_context_take_codegen(struct bf_context *context, enum bf_hook hook, enum bf_front front)#
See bf_context_take_codegen for details.
-
static void _bf_context_delete_codegen(struct bf_context *context, enum bf_hook hook, enum bf_front front)#
See bf_context_delete_codegen for details.
-
static int _bf_context_set_codegen(struct bf_context *context, enum bf_hook hook, enum bf_front front, struct bf_codegen *codegen)#
See bf_context_set_codegen for details.
-
static void _bf_context_replace_codegen(struct bf_context *context, enum bf_hook hook, enum bf_front front, struct bf_codegen *codegen)#
See bf_context_replace_codegen for details.
-
int bf_context_setup(void)#
Initialise the global bpfilter context.
- Returns:
0 on success, negative error code on failure.
-
void bf_context_teardown(bool clear)#
Teardown the global bpfilter context.
- Parameters:
clear – If true, all the BPF programs will be unloaded before clearing the context.
-
int bf_context_save(struct bf_marsh **marsh)#
Marshel the global bpfilter context.
- Parameters:
marsh – bf_marsh structure to fill with the marshalled context.
- Returns:
0 on success, negative error code on failure.
-
int bf_context_load(const struct bf_marsh *marsh)#
Unmarshal the global bpfilter context.
Once this function completes, the global context has been restored from the marshalled context. On failure, the global context is left uninitialized.
- Parameters:
marsh – bf_marsh structure containing the marshalled context.
- Returns:
0 on success, negative error code on failure.
-
void bf_context_dump(prefix_t *prefix)#
Dump content of the context.
- Parameters:
prefix – Prefix to use for the dump.
-
struct bf_codegen *bf_context_get_codegen(enum bf_hook hook, enum bf_front front)#
Get codegen for a given (hook, front) set.
- Parameters:
hook – Hook to get the codegen from. Must be a valid hook.
front – Front-end to get the codegen from. Must be a valid front-end.
- Returns:
The codegen for the given hook and front-end, or NULL if there is no such codegen.
-
struct bf_codegen *bf_context_take_codegen(enum bf_hook hook, enum bf_front front)#
Take a codegen out of the context for a given (hook, front) set.
The codegen returned must then be freed by the caller. It’s not part of the context anymore.
- Parameters:
hook – Hook to get the codegen from. Must be a valid hook.
front – Front-end to get the codegen from. Must be a valid front-end.
- Returns:
The codegen for the given hook and front-end, or NULL if there is no such codegen.
-
void bf_context_delete_codegen(enum bf_hook hook, enum bf_front front)#
Delete a codegen from the context for a given (hook, front) set.
If a corresponding codegen has been found, then it is removed from the context and deleted. Otherwise the context remain unchanged.
- Parameters:
hook – Hook to get the codegen from. Must be a valid hook.
front – Front-end to get the codegen from. Must be a valid front-end.
-
int bf_context_set_codegen(enum bf_hook hook, enum bf_front front, struct bf_codegen *codegen)#
Add a codegen to the context.
- Parameters:
hook – Hook to add the codegen to. Must be a valid hook.
front – Front-end to add the codegen to. Must be a valid front-end.
codegen – Codegen to add to the context. Can’t be NULL.
- Returns:
0 on success, negative error code on failure. If a codegen already exists for the given (hook, front) set, then -EEXIST is returned.
-
void bf_context_replace_codegen(enum bf_hook hook, enum bf_front front, struct bf_codegen *codegen)#
Replace the codegen for a given (hook, front) set, if any.
If a codegen already exists for the given (hook, front) set, then it is deleted and replaced by
codegen
. Otherwise,codegen
is added to the context.- Parameters:
hook – Hook to update the codegen for. Must be a valid hook.
front – Front-end to update the codegen for. Must be a valid
codegen – Codegen to update the context with. Can’t be NULL.
Variables
-
static struct bf_context *_global_context = NULL#
Global daemon context. Hidden in this translation unit.
-
_cleanup_bf_context_#
- file context.h
- #include <stdbool.h>#include <stddef.h>#include “core/dump.h”#include “core/hook.h”#include “core/list.h”#include “shared/front.h”
bpfilter runtime context. This file contains the definition of the bf_context structure, which is the main structure used to store the daemon’s runtime context.
bf_context can be serialized and deserialized, including all of its fields. This way, bpfilter can be restarted without unloading the BPF programs and maps.
Like every other bf_* structure, most bf_* functions should expect a valid pointer to a bf_context structure. This is not exactly how it works for bf_context: public functions defined in this header do not require any bf_context, but those are only wrappers around private functions defined in context.c, which do expect a valid pointer to a bf_context. This is done to prevent the user from creating and manipulating multiple contexts, while keeping the API consistent with the other bf_* structures.
Functions
-
int bf_context_setup(void)
Initialise the global bpfilter context.
- Returns:
0 on success, negative error code on failure.
-
void bf_context_teardown(bool clear)
Teardown the global bpfilter context.
- Parameters:
clear – If true, all the BPF programs will be unloaded before clearing the context.
-
void bf_context_dump(prefix_t *prefix)
Dump content of the context.
- Parameters:
prefix – Prefix to use for the dump.
-
int bf_context_save(struct bf_marsh **marsh)
Marshel the global bpfilter context.
- Parameters:
marsh – bf_marsh structure to fill with the marshalled context.
- Returns:
0 on success, negative error code on failure.
-
int bf_context_load(const struct bf_marsh *marsh)
Unmarshal the global bpfilter context.
Once this function completes, the global context has been restored from the marshalled context. On failure, the global context is left uninitialized.
- Parameters:
marsh – bf_marsh structure containing the marshalled context.
- Returns:
0 on success, negative error code on failure.
-
struct bf_codegen *bf_context_get_codegen(enum bf_hook hook, enum bf_front front)
Get codegen for a given (hook, front) set.
- Parameters:
hook – Hook to get the codegen from. Must be a valid hook.
front – Front-end to get the codegen from. Must be a valid front-end.
- Returns:
The codegen for the given hook and front-end, or NULL if there is no such codegen.
-
struct bf_codegen *bf_context_take_codegen(enum bf_hook hook, enum bf_front front)
Take a codegen out of the context for a given (hook, front) set.
The codegen returned must then be freed by the caller. It’s not part of the context anymore.
- Parameters:
hook – Hook to get the codegen from. Must be a valid hook.
front – Front-end to get the codegen from. Must be a valid front-end.
- Returns:
The codegen for the given hook and front-end, or NULL if there is no such codegen.
-
void bf_context_delete_codegen(enum bf_hook hook, enum bf_front front)
Delete a codegen from the context for a given (hook, front) set.
If a corresponding codegen has been found, then it is removed from the context and deleted. Otherwise the context remain unchanged.
- Parameters:
hook – Hook to get the codegen from. Must be a valid hook.
front – Front-end to get the codegen from. Must be a valid front-end.
-
int bf_context_set_codegen(enum bf_hook hook, enum bf_front front, struct bf_codegen *codegen)
Add a codegen to the context.
- Parameters:
hook – Hook to add the codegen to. Must be a valid hook.
front – Front-end to add the codegen to. Must be a valid front-end.
codegen – Codegen to add to the context. Can’t be NULL.
- Returns:
0 on success, negative error code on failure. If a codegen already exists for the given (hook, front) set, then -EEXIST is returned.
-
void bf_context_replace_codegen(enum bf_hook hook, enum bf_front front, struct bf_codegen *codegen)
Replace the codegen for a given (hook, front) set, if any.
If a codegen already exists for the given (hook, front) set, then it is deleted and replaced by
codegen
. Otherwise,codegen
is added to the context.- Parameters:
hook – Hook to update the codegen for. Must be a valid hook.
front – Front-end to update the codegen for. Must be a valid
codegen – Codegen to update the context with. Can’t be NULL.
-
int bf_context_setup(void)
- file counter.h
- #include <stdint.h>#include “shared/helper.h”
Variables
-
struct bf_counter bf_packed#
-
struct bf_counter bf_packed#
- file flavor.c
- #include “core/flavor.h”#include “generator/nf.h”#include “generator/tc.h”#include “generator/xdp.h”#include “shared/helper.h”
Functions
-
const struct bf_flavor_ops *bf_flavor_ops_get(enum bf_flavor flavor)#
Get the operations structure for a given BPF flavor.
- Parameters:
type – BPF flavor. Must be valid.
- Returns:
Ops structure for a given BPF flavor.
-
const struct bf_flavor_ops *bf_flavor_ops_get(enum bf_flavor flavor)#
- file flavor.h
- #include “core/verdict.h”
“Flavor” as defined by bpfilter are types of BPF program, characterized by the prototype of the main function, the valid returns values, and the way they are attached to the kernel.
A flavor is used to defines specific part of the BPF program for a codegen. For example: access to the packet’s data, return value…
Enums
Functions
-
const struct bf_flavor_ops *bf_flavor_ops_get(enum bf_flavor flavor)
Get the operations structure for a given BPF flavor.
- Parameters:
type – BPF flavor. Must be valid.
- Returns:
Ops structure for a given BPF flavor.
-
const char *bf_flavor_to_str(enum bf_flavor flavor)
Convert a bpfilter flavor to a string.
- Parameters:
flavor – Flavor to convert. Must be valid.
- Returns:
String representation of
flavor
.
-
const struct bf_flavor_ops *bf_flavor_ops_get(enum bf_flavor flavor)
- file helper.c
- #include “core/helper.h”#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include “core/logger.h”#include “shared/helper.h”
Functions
-
int bf_read_file(const char *path, void **buf, size_t *len)#
Read the contents of a file into a buffer.
- Parameters:
path – Path to the file to read. Can’t be NULL.
buf – Pointer to a pointer to a buffer. The buffer will be allocated automatically. The caller is responsible to free it. If bf_read_file fails,
buf
is left unchanged.len – Length of the allocated buffer. Populated by the function.
- Returns:
0 on success, negative errno value on error.
-
int bf_write_file(const char *path, const void *buf, size_t len)#
Write the contents of a buffer into a file.
- Parameters:
path – Path to the file to write. Can’t be NULL.
buf – Buffer to write.
len – Number of bytes to write the to file.
- Returns:
0 on success, negative errno value on error.
-
int bf_read_file(const char *path, void **buf, size_t *len)#
- file helper.h
- #include <stddef.h>
Functions
-
int bf_read_file(const char *path, void **buf, size_t *len)
Read the contents of a file into a buffer.
- Parameters:
path – Path to the file to read. Can’t be NULL.
buf – Pointer to a pointer to a buffer. The buffer will be allocated automatically. The caller is responsible to free it. If bf_read_file fails,
buf
is left unchanged.len – Length of the allocated buffer. Populated by the function.
- Returns:
0 on success, negative errno value on error.
-
int bf_write_file(const char *path, const void *buf, size_t len)
Write the contents of a buffer into a file.
- Parameters:
path – Path to the file to write. Can’t be NULL.
buf – Buffer to write.
len – Number of bytes to write the to file.
- Returns:
0 on success, negative errno value on error.
-
int bf_read_file(const char *path, void **buf, size_t *len)
- file hook.c
- #include “core/hook.h”#include “shared/helper.h”
Functions
-
const char *bf_hook_to_str(enum bf_hook hook)#
Convert a bpfilter hook to a string.
- Parameters:
hook – The hook to convert. Must be a valid hook.
- Returns:
String representation of the hook.
-
unsigned int bf_hook_to_bpf_prog_type(enum bf_hook hook)#
Convert a bpfilter hook to a BPF program type.
- Parameters:
hook – The hook to convert. Must be a valid hook.
- Returns:
The BPF program type corresponding to
hook
.
-
const char *bf_hook_to_str(enum bf_hook hook)#
- file hook.h
- #include <linux/bpf.h>#include “core/flavor.h”
bpfilter’s BPF programs are attached to hooks in the kernel. This file contains the definitions for the hooks we support.
Enums
-
enum bf_hook#
Values:
-
enumerator BF_HOOK_NFT_INGRESS#
-
enumerator BF_HOOK_TC_INGRESS#
-
enumerator BF_HOOK_IPT_PRE_ROUTING#
-
enumerator BF_HOOK_IPT_LOCAL_IN#
-
enumerator BF_HOOK_IPT_FORWARD#
-
enumerator BF_HOOK_IPT_LOCAL_OUT#
-
enumerator BF_HOOK_IPT_POST_ROUTING#
-
enumerator BF_HOOK_TC_EGRESS#
-
enumerator _BF_HOOK_MAX#
-
enumerator BF_HOOK_NFT_INGRESS#
Functions
-
const char *bf_hook_to_str(enum bf_hook hook)
Convert a bpfilter hook to a string.
- Parameters:
hook – The hook to convert. Must be a valid hook.
- Returns:
String representation of the hook.
-
unsigned int bf_hook_to_bpf_prog_type(enum bf_hook hook)
Convert a bpfilter hook to a BPF program type.
- Parameters:
hook – The hook to convert. Must be a valid hook.
- Returns:
The BPF program type corresponding to
hook
.
-
enum bf_flavor bf_hook_to_flavor(enum bf_hook hook)
Get the expected flavor for a given hook.
- Parameters:
hook – BPF hook. Must be valid.
- Returns:
bpfilter flavor corresponding to
hook
.
-
enum bpf_attach_type bf_hook_to_attach_type(enum bf_hook hook)
Convert a bpfilter hook to a BPF attach type.
- Parameters:
hook – The hook to convert. Must be a valid hook.
- Returns:
The BPF attach type corresponding to
hook
.
-
enum bf_hook#
- file list.c
- #include “list.h”#include <errno.h>#include <stdlib.h>
Functions
-
static int bf_list_node_new(bf_list_node **node, void *data)#
Create a new list node, with the given data.
- Parameters:
node – New node pointer. Must be non-NULL.. If the function fails, this parameter remains unchanged.
data – Data to store in the new node. Can be NULL.
- Returns:
0 on success or negative errno code on failure.
-
static void bf_list_node_free(bf_list_node **node, void (*free_data)(void **data))#
Free a list node. Must be non-NULL.
The data contained in the node will also be freed using the function provided in the list’s ops.
- Parameters:
node – Node to free.
-
int bf_list_new(bf_list **list, const bf_list_ops *ops)#
Allocate and initialise a new list.
- Parameters:
list – Pointer to the list to initialise. Must be non-NULL.
ops – Operations to use to manipulate the list’s data. Must be non-NULL.
- Returns:
0 on success or negative errno code on failure.
-
void bf_list_free(bf_list **list)#
Free a list.
- Parameters:
list – Pointer to the list to free. Must be non-NULL.
-
void bf_list_init(bf_list *list, const bf_list_ops *ops)#
Initialize an allocated list.
- Parameters:
list – List to initialise. Must be non-NULL.
ops – Operations to use to manipulate the list’s data. Must be non-NULL.
ops
shouldn’t contain any NULL field.
-
void bf_list_clean(bf_list *list)#
Clean up a list.
Every node in the list is freed. The node’s data is freed using the function provided during initialisation (through bf_list_ops).
- Parameters:
list – Pointer to the initialised list to clean. Must be non-NULL.
-
int bf_list_add_head(bf_list *list, void *data)#
Add data at the beginning of the list.
- Parameters:
list – List to append data to. Must be initialised and non-NULL.
data – Data to append to the list. Can be NULL.
list
takes ownership of the data: it should not be freed.
- Returns:
0 on success or negative errno code on failure.
-
int bf_list_add_tail(bf_list *list, void *data)#
Add data at the end of the list.
- Parameters:
list – List to append data to. Must be initialised and non-NULL.
data – Data to append to the list. Can be NULL.
list
takes ownership of the data: it should not be freed.
- Returns:
0 on success or negative errno code on failure.
-
void bf_list_delete(bf_list *list, bf_list_node *node)#
Delete
node
fromlist
.node
is freed and shouldn’t be used once the function returns. The node’s data will be freed using the function provided during initialisation (through bf_list_ops).- Parameters:
list – List to remove node from. Must be non-NULL.
node – Node to remove from the list. Must be non-NULL.
-
static int bf_list_node_new(bf_list_node **node, void *data)#
- file list.h
- #include <stdbool.h>#include <stddef.h>#include “shared/helper.h”
Defines
-
_cleanup_bf_list_#
-
bf_list_foreach(list, node)#
Iterate over a bf_list.
Use a temporary variable to store the next node (if any). Hence, a node can be removed from the list during iteration.
- Parameters:
list – Pointer to the list to iterate over. Must be non-NULL.
node – Name of the variable containing the current node. This variable will be created automatically and the caller will be able to use it to access the node.
-
bf_list_foreach_rev(list, node)#
Reverse iterate over a bf_list.
Use a temporary variable to store the next node (if any). Hence, a node can be removed from the list during iteration.
- Parameters:
list – Pointer to the list to iterate over. Must be non-NULL.
node – Name of the variable containing the current node. This variable will be created automatically and the caller will be able to use it to access the node.
Functions
-
int bf_list_new(bf_list **list, const bf_list_ops *ops)
Allocate and initialise a new list.
- Parameters:
list – Pointer to the list to initialise. Must be non-NULL.
ops – Operations to use to manipulate the list’s data. Must be non-NULL.
- Returns:
0 on success or negative errno code on failure.
-
void bf_list_free(bf_list **list)
Free a list.
- Parameters:
list – Pointer to the list to free. Must be non-NULL.
-
void bf_list_init(bf_list *list, const bf_list_ops *ops)
Initialize an allocated list.
- Parameters:
list – List to initialise. Must be non-NULL.
ops – Operations to use to manipulate the list’s data. Must be non-NULL.
ops
shouldn’t contain any NULL field.
-
void bf_list_clean(bf_list *list)
Clean up a list.
Every node in the list is freed. The node’s data is freed using the function provided during initialisation (through bf_list_ops).
- Parameters:
list – Pointer to the initialised list to clean. Must be non-NULL.
-
static inline size_t bf_list_size(const bf_list *list)#
Get the number of nodes in the list.
- Parameters:
list – Initialised list. Must be non-NULL.
- Returns:
Number of nodes in the list.
-
static inline bool bf_list_is_empty(const bf_list *list)#
Check if a list is empty.
- Parameters:
list – Initialised list. Must be non-NULL.
- Returns:
True if the list is empty, false otherwise.
-
static inline bool bf_list_is_head(const bf_list *list, const bf_list_node *node)#
Check if
node
is the head oflist
.- Parameters:
list – List. Must be non NULL.
node – Node. Must be non NULL.
- Returns:
True if
node
is the head oflist
, false otherwise.
-
static inline bool bf_list_is_tail(const bf_list *list, const bf_list_node *node)#
Check if
node
is the tail oflist
.- Parameters:
list – List. Must be non NULL.
node – Node. Must be non NULL.
- Returns:
True if
node
is the tail oflist
, false otherwise.
-
int bf_list_add_head(bf_list *list, void *data)
Add data at the beginning of the list.
- Parameters:
list – List to append data to. Must be initialised and non-NULL.
data – Data to append to the list. Can be NULL.
list
takes ownership of the data: it should not be freed.
- Returns:
0 on success or negative errno code on failure.
-
int bf_list_add_tail(bf_list *list, void *data)
Add data at the end of the list.
- Parameters:
list – List to append data to. Must be initialised and non-NULL.
data – Data to append to the list. Can be NULL.
list
takes ownership of the data: it should not be freed.
- Returns:
0 on success or negative errno code on failure.
-
void bf_list_delete(bf_list *list, bf_list_node *node)
Delete
node
fromlist
.node
is freed and shouldn’t be used once the function returns. The node’s data will be freed using the function provided during initialisation (through bf_list_ops).- Parameters:
list – List to remove node from. Must be non-NULL.
node – Node to remove from the list. Must be non-NULL.
-
static inline bf_list_node *bf_list_get_head(const bf_list *list)#
Returns the first element of the list.
A
bf_list_node
object it returned. Use bf_list_node_get_data to get a pointer to the data.- Parameters:
list – Initialised list. Must be non-NULL.
- Returns:
Pointer to the first node of the list, or NULL if empty.
-
static inline bf_list_node *bf_list_get_tail(const bf_list *list)#
Returns the last element of the list.
A
bf_list_node
object it returned. Use bf_list_node_get_data to get a pointer to the data.- Parameters:
list – Initialised list. Must be non-NULL.
- Returns:
Pointer to the last node of the list, or NULL if empty.
-
static inline bf_list_node *bf_list_node_next(const bf_list_node *node)#
Get next node.
- Parameters:
node – Current node. Must be non-NULL.
- Returns:
Pointer to the next node, or NULL if end of list.
-
static inline bf_list_node *bf_list_node_prev(const bf_list_node *node)#
Get previous node.
- Parameters:
node – Current node. Must be non-NULL.
- Returns:
Pointer to the previous node, or NULL if end of list.
-
static inline void *bf_list_node_get_data(const bf_list_node *node)#
Get the node’s data.
Note that the pointer returned can be NULL, as nothing prevents NULL data to be stored in the node. The pointer returned is owned by the node and should not be freed.
- Parameters:
node – Current node. Must be non-NULL.
- Returns:
Pointer to the data stored in the iterator.
-
static inline void *bf_list_node_take_data(bf_list_node *node)#
Get the node’s data and remove it from the node.
Once the function returns, the node’s data is set to NULL. The pointer returned is then owned by the caller.
- Parameters:
node – Current node. Must be non-NULL.
- Returns:
Pointer to the data stored in the node.
-
_cleanup_bf_list_#
- file logger.c
- #include “core/logger.h”#include <stdbool.h>#include <unistd.h>
Functions
-
void bf_logger_setup(void)#
Initialise the logging system.
Defines whether the logging system will print in colors or not. If both
stdout
andstderr
are TTYs, then _can_print_color is set to true.
-
const char *bf_logger_get_color(enum bf_style style)#
Get color string for a given style.
style
can be a combination of bf_style weight and color. If _can_print_color is set to false, then an empty string will be returned so to not modify the output style.- Parameters:
style – Style to get the color of
- Returns:
Style string.
Variables
-
static bool _can_print_color = false#
If true, log messages will be printed in colors.
-
void bf_logger_setup(void)#
- file logger.h
- #include <stdio.h>#include “opts.h”#include “shared/helper.h”
Defines
-
_bf_log_impl(fmt, ...)#
Log an error message to stderr.
- Parameters:
fmt – Format string.
... – Format arguments.
-
bf_abort(fmt, ...)#
-
bf_err(fmt, ...)#
-
bf_warn(fmt, ...)#
-
bf_info(fmt, ...)#
-
bf_dbg(fmt, ...)#
-
_bf_log_code_impl(code, fmt, ...)#
Log an error message to stderr, append the detail of the error code provided and return the given error code.
Convenience function to be used during error checks. It will log the error message to stderr, append the detail of the error code provided and return the given error code as a negative value. For example:
if (ret < 0) return bf_err_code(ret, “failed to do something”);
- Parameters:
code – Error code, can be positive or negative.
fmt – Format string.
... – Format arguments.
- Returns:
The given error code, as a negative value.
-
bf_err_code(code, fmt, ...)#
-
bf_warn_code(code, fmt, ...)#
-
bf_info_code(code, fmt, ...)#
-
bf_dbg_code(code, fmt, ...)#
Enums
-
enum bf_style#
Values:
-
enumerator BF_STYLE_RESET = 0#
-
enumerator BF_STYLE_NORMAL = 0#
-
enumerator BF_STYLE_BOLD = 1#
-
enumerator BF_STYLE_DEFAULT = 1 << 1#
-
enumerator BF_STYLE_BLACK = 1 << 2#
-
enumerator BF_STYLE_RED = 1 << 3#
-
enumerator BF_STYLE_GREEN = 1 << 4#
-
enumerator BF_STYLE_YELLOW = 1 << 5#
-
enumerator BF_STYLE_BLUE = 1 << 6#
-
enumerator BF_STYLE_MAGENTA = 1 << 7#
-
enumerator BF_STYLE_CYAN = 1 << 8#
-
enumerator BF_STYLE_LIGHT_GRAY = 1 << 9#
-
enumerator BF_STYLE_DARK_GRAY = 1 << 10#
-
enumerator BF_STYLE_LIGHT_RED = 1 << 11#
-
enumerator BF_STYLE_LIGHT_GREEN = 1 << 12#
-
enumerator BF_STYLE_LIGHT_YELLOW = 1 << 13#
-
enumerator BF_STYLE_LIGHT_BLUE = 1 << 14#
-
enumerator BF_STYLE_LIGHT_MAGENTA = 1 << 15#
-
enumerator BF_STYLE_LIGHT_CYAN = 1 << 16#
-
enumerator BF_STYLE_WHITE = 1 << 17#
-
enumerator BF_STYLE_RESET = 0#
Functions
-
void bf_logger_setup(void)
Initialise the logging system.
Defines whether the logging system will print in colors or not. If both
stdout
andstderr
are TTYs, then _can_print_color is set to true.
-
const char *bf_logger_get_color(enum bf_style style)
Get color string for a given style.
style
can be a combination of bf_style weight and color. If _can_print_color is set to false, then an empty string will be returned so to not modify the output style.- Parameters:
style – Style to get the color of
- Returns:
Style string.
-
_bf_log_impl(fmt, ...)#
- file marsh.c
- #include “core/marsh.h”#include <errno.h>#include <stdlib.h>#include <string.h>
Functions
-
int bf_marsh_new(struct bf_marsh **marsh, const void *data, size_t data_len)#
Allocate and initialise a bf_marsh structure.
- Parameters:
marsh – Marsh to be allocated. On success, contains a pointer to the marsh structure, and is owned by the caller. If the function fails, it’s left unchanged.
data – Data to be marshalled.
data_len – Length of
data
.
- Returns:
0 on success, negative errno value on error.
-
void bf_marsh_free(struct bf_marsh **marsh)#
Free a marsh, including its data.
If
marsh
points to NULL, then nothing is done.- Parameters:
marsh – Marsh to free. Must not be NULL.
-
int bf_marsh_add_child_obj(struct bf_marsh **marsh, const struct bf_marsh *obj)#
Add a child to a marsh, from another marsh.
obj
will be added to the data inmarsh
.- Parameters:
marsh – Parent marsh. Must be non NULL.
obj – Marsh to be added as a child. Must be non NULL.
- Returns:
0 on success, negative errno value on error.
-
int bf_marsh_add_child_raw(struct bf_marsh **marsh, const void *data, size_t data_len)#
Add a child to a marsh, from raw data.
If
data
is NULL, nothing is done andmarsh
remain unchanged. In this case,data_len
must be 0.- Parameters:
marsh – Parent marsh. Must be non NULL.
data – Data to add to the marsh.
data_len – Length of the data to add to
marsh
.
- Returns:
0 on success, negative errno value on error.
-
int bf_marsh_new(struct bf_marsh **marsh, const void *data, size_t data_len)#
- file marsh.h
- #include <stdbool.h>#include <stddef.h>#include “shared/helper.h”
Defines
-
_cleanup_bf_marsh_#
Functions
-
static inline size_t bf_marsh_size(const struct bf_marsh *marsh)#
Get the total size of marshalled data.
- Parameters:
marsh – Marshalled data.
- Returns:
Total size of marshalled data, including the header.
-
static inline void *bf_marsh_end(const struct bf_marsh *marsh)#
Get pointer to the end of a bf_marsh structure.
“End” here, means the first byte after the content of the marshalled data.
- Parameters:
marsh – Marshalled data.
- Returns:
Pointer to the end of the marshalled data.
-
static inline bool bf_marsh_child_is_valid(const struct bf_marsh *marsh, const struct bf_marsh *child)#
Check if
child
is a valid child formarsh
.A valid marsh is defined by the following criteria:
It starts within its parent’s data.
Its full length (including the header) is within its parent’s data. A marsh can only be validated relative to its parent. By recursively validating all the children of a marsh, we can validate the whole marsh.
Warning
This function doesn’t check if the marshalled data is valid. It only checks if the marshalled data is within the parent’s data and can be accessed safely.
- Parameters:
marsh – Parent marsh, must be valid.
child – Child marsh to validate. Can be NULL.
- Returns:
true if
child
is a valid child ofmarsh
, false otherwise.
-
static inline struct bf_marsh *bf_marsh_next_child(const struct bf_marsh *marsh, const struct bf_marsh *child)#
Get
marsh
’s child located afterchild
.- Parameters:
marsh – Parent marsh, must be valid.
child – Child of
marsh
, must be a valid child ofmarsh
or NULL. Ifchild
is NULL, the first child ofmarsh
is returned.
- Returns:
Next child of
marsh
afterchild
, or NULL ifchild
is the last valid child ofmarsh
.
-
int bf_marsh_new(struct bf_marsh **marsh, const void *data, size_t data_len)
Allocate and initialise a bf_marsh structure.
- Parameters:
marsh – Marsh to be allocated. On success, contains a pointer to the marsh structure, and is owned by the caller. If the function fails, it’s left unchanged.
data – Data to be marshalled.
data_len – Length of
data
.
- Returns:
0 on success, negative errno value on error.
-
void bf_marsh_free(struct bf_marsh **marsh)
Free a marsh, including its data.
If
marsh
points to NULL, then nothing is done.- Parameters:
marsh – Marsh to free. Must not be NULL.
-
int bf_marsh_add_child_obj(struct bf_marsh **marsh, const struct bf_marsh *obj)
Add a child to a marsh, from another marsh.
obj
will be added to the data inmarsh
.- Parameters:
marsh – Parent marsh. Must be non NULL.
obj – Marsh to be added as a child. Must be non NULL.
- Returns:
0 on success, negative errno value on error.
-
int bf_marsh_add_child_raw(struct bf_marsh **marsh, const void *data, size_t data_len)
Add a child to a marsh, from raw data.
If
data
is NULL, nothing is done andmarsh
remain unchanged. In this case,data_len
must be 0.- Parameters:
marsh – Parent marsh. Must be non NULL.
data – Data to add to the marsh.
data_len – Length of the data to add to
marsh
.
- Returns:
0 on success, negative errno value on error.
Variables
-
struct bf_marsh bf_packed
-
_cleanup_bf_marsh_#
- file match.c
- #include “match.h”#include <errno.h>#include <stdlib.h>
- file match.h
- file rule.c
- #include “core/rule.h”#include <errno.h>#include <stdlib.h>#include <string.h>#include “core/list.h”#include “core/logger.h”#include “core/marsh.h”#include “core/match.h”#include “core/verdict.h”#include “shared/helper.h”
Functions
-
int bf_rule_new(struct bf_rule **rule)#
Allocated and initialise a new rule.
On failure,
rule
is left unchanged.- Parameters:
rule – On success, points to the allocated rule. Must be non NULL.
- Returns:
0 on success, or negative errno value on error.
-
void bf_rule_free(struct bf_rule **rule)#
Free a rule.
Free
rule
and set it to NULL. Ifrule
is NULL, nothing is done.- Parameters:
rule – Rule to free. Must be non-NULL.
-
int bf_rule_marsh(const struct bf_rule *rule, struct bf_marsh **marsh)#
Marsh a rule.
- Parameters:
rule – Rule to marsh. Can’t be NULL.
marsh – Output marshalled rule. Allocated by the function, owned by the caller once the function returns. Can’t be NULL.
- Returns:
0 on success, negative errno value on error.
-
int bf_rule_new(struct bf_rule **rule)#
- file rule.h
- #include <stdbool.h>#include <stdint.h>#include “core/dump.h”#include “core/list.h”#include “core/verdict.h”
Defines
-
_cleanup_bf_rule_#
Functions
-
int bf_rule_new(struct bf_rule **rule)
Allocated and initialise a new rule.
On failure,
rule
is left unchanged.- Parameters:
rule – On success, points to the allocated rule. Must be non NULL.
- Returns:
0 on success, or negative errno value on error.
-
void bf_rule_free(struct bf_rule **rule)
Free a rule.
Free
rule
and set it to NULL. Ifrule
is NULL, nothing is done.- Parameters:
rule – Rule to free. Must be non-NULL.
-
int bf_rule_marsh(const struct bf_rule *rule, struct bf_marsh **marsh)
Marsh a rule.
- Parameters:
rule – Rule to marsh. Can’t be NULL.
marsh – Output marshalled rule. Allocated by the function, owned by the caller once the function returns. Can’t be NULL.
- Returns:
0 on success, negative errno value on error.
-
int bf_rule_unmarsh(const struct bf_marsh *marsh, struct bf_rule **rule)
Unmarsh a rule.
- Parameters:
marsh – Marshalled rule. Must be non NULL.
rule – Unmarshalled rule. Allocated by the function, owned by the caller on success.
- Returns:
0 on success, negative errno value on error.
-
void bf_rule_dump(const struct bf_rule *rule, prefix_t *prefix)
Dump a rule.
- Parameters:
rule – Rule to dump. Must not be NULL.
prefix – Prefix for each printed line.
-
_cleanup_bf_rule_#
- file verdict.c
- #include “core/verdict.h”#include “bpfilter/shared/helper.h”
Functions
-
const char *bf_verdict_to_str(enum bf_verdict verdict)#
-
const char *bf_verdict_to_str(enum bf_verdict verdict)#
- file verdict.h
Enums
Functions
-
const char *bf_verdict_to_str(enum bf_verdict verdict)
-
const char *bf_verdict_to_str(enum bf_verdict verdict)
- file filter.h
- #include <linux/bpf.h>#include <linux/bpf_common.h>#include <stdbool.h>
Defines
-
BPF_REG_ARG1#
-
BPF_REG_ARG2#
-
BPF_REG_ARG3#
-
BPF_REG_ARG4#
-
BPF_REG_ARG5#
-
BPF_REG_CTX#
-
BPF_REG_FP#
-
BPF_REG_A#
-
BPF_REG_X#
-
BPF_REG_TMP#
-
BPF_REG_D#
-
BPF_REG_H#
-
BPF_REG_AX#
-
MAX_BPF_EXT_REG#
-
MAX_BPF_JIT_REG#
-
BPF_TAIL_CALL#
-
BPF_PROBE_MEM#
-
BPF_CALL_ARGS#
-
BPF_NOSPEC#
-
BPF_SYM_ELF_TYPE#
-
MAX_BPF_STACK#
-
BPF_ALU64_REG(OP, DST, SRC)#
-
BPF_ALU32_REG(OP, DST, SRC)#
-
BPF_ALU64_IMM(OP, DST, IMM)#
-
BPF_ALU32_IMM(OP, DST, IMM)#
-
BPF_ENDIAN(TYPE, DST, LEN)#
-
BPF_MOV64_REG(DST, SRC)#
-
BPF_MOV32_REG(DST, SRC)#
-
BPF_MOV64_IMM(DST, IMM)#
-
BPF_MOV32_IMM(DST, IMM)#
-
BPF_ZEXT_REG(DST)#
-
BPF_LD_IMM64(DST, IMM)#
-
BPF_LD_IMM64_RAW(DST, SRC, IMM)#
-
BPF_LD_MAP_FD(DST, MAP_FD)#
-
BPF_MOV64_RAW(TYPE, DST, SRC, IMM)#
-
BPF_MOV32_RAW(TYPE, DST, SRC, IMM)#
-
BPF_LD_ABS(SIZE, IMM)#
-
BPF_LD_IND(SIZE, SRC, IMM)#
-
BPF_LDX_MEM(SIZE, DST, SRC, OFF)#
-
BPF_STX_MEM(SIZE, DST, SRC, OFF)#
-
BPF_ATOMIC_OP(SIZE, OP, DST, SRC, OFF)#
-
BPF_STX_XADD(SIZE, DST, SRC, OFF)#
-
BPF_ST_MEM(SIZE, DST, OFF, IMM)#
-
BPF_JMP_REG(OP, DST, SRC, OFF)#
-
BPF_JMP_IMM(OP, DST, IMM, OFF)#
-
BPF_JMP32_REG(OP, DST, SRC, OFF)#
-
BPF_JMP32_IMM(OP, DST, IMM, OFF)#
-
BPF_JMP_A(OFF)#
-
BPF_CALL_REL(TGT)#
-
BPF_EMIT_CALL(FUNC)#
-
BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM)#
-
BPF_EXIT_INSN()#
-
BPF_ST_NOSPEC()#
-
__BPF_STMT(CODE, K)#
-
__BPF_JUMP(CODE, K, JT, JF)#
-
bytes_to_bpf_size(bytes)#
-
bpf_size_to_bytes(bpf_size)#
-
BPF_SIZEOF(type)#
-
BPF_FIELD_SIZEOF(type, field)#
-
BPF_LDST_BYTES(insn)#
-
__BPF_MAP_0(m, v, ...)#
-
__BPF_MAP_1(m, v, t, a, ...)#
-
__BPF_MAP_2(m, v, t, a, ...)#
-
__BPF_MAP_3(m, v, t, a, ...)#
-
__BPF_MAP_4(m, v, t, a, ...)#
-
__BPF_MAP_5(m, v, t, a, ...)#
-
__BPF_REG_0(...)#
-
__BPF_REG_1(...)#
-
__BPF_REG_2(...)#
-
__BPF_REG_3(...)#
-
__BPF_REG_4(...)#
-
__BPF_REG_5(...)#
-
__BPF_MAP(n, ...)#
-
__BPF_REG(n, ...)#
-
__BPF_CAST(t, a)#
-
__BPF_V#
-
__BPF_N#
-
__BPF_DECL_ARGS(t, a)#
-
__BPF_DECL_REGS(t, a)#
-
__BPF_PAD(n)#
-
BPF_CALL_x(x, name, ...)#
-
BPF_CALL_0(name, ...)#
-
BPF_CALL_1(name, ...)#
-
BPF_CALL_2(name, ...)#
-
BPF_CALL_3(name, ...)#
-
BPF_CALL_4(name, ...)#
-
BPF_CALL_5(name, ...)#
-
bpf_ctx_range(TYPE, MEMBER)#
-
bpf_ctx_range_till(TYPE, MEMBER1, MEMBER2)#
-
bpf_ctx_range_ptr(TYPE, MEMBER)#
-
bpf_target_off(TYPE, MEMBER, SIZE, PTR_SIZE)#
Functions
-
static inline bool insn_is_zext(const struct bpf_insn *insn)#
-
BPF_REG_ARG1#
- file codegen.c
- #include “codegen.h”#include <net/if.h>#include <errno.h>#include <stdbool.h>#include <stdlib.h>#include <string.h>#include “core/dump.h”#include “core/logger.h”#include “core/marsh.h”#include “core/rule.h”#include “generator/dump.h”#include “generator/program.h”#include “shared/front.h”#include “shared/helper.h”
Functions
-
int bf_codegen_new(struct bf_codegen **codegen)#
Allocate and initialise a new codegen.
- Parameters:
codegen – Codegen to initialise. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
void bf_codegen_free(struct bf_codegen **codegen)#
Free a codegen.
If one or more programs are loaded, they won’t be unloaded. Use bf_codegen_unload first to ensure programs are unloaded. This behaviour is expected so bf_codegen can be freed without unloading the BPF program, during a daemon restart for example.
- Parameters:
codegen – Codegen to free. Can’t be NULL.
-
int bf_codegen_generate(struct bf_codegen *codegen)#
Generate BPF programs for a codegen.
- Parameters:
codegen – Codegen to generate BPF programs for. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_codegen_load(struct bf_codegen *codegen, struct bf_codegen *prev_codegen)#
Load the BPF program stored in a codegen.
Each program within the codegen will be loaded and attached to its interface.
- Parameters:
codegen – Codegen containing the BPF program to load. Can’t be NULL.
prev_codegen – Codegen to replace. Can be NULL. bf_codegen_load is responsible for unloading the previous codegen. bf_codegen_load doesn’t own
prev_codegen
, and won’t free it.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_codegen_unload(struct bf_codegen *codegen)#
Unload a codegen’s BPF programs.
- Parameters:
codegen – Codegen containing the BPF program to unload. Can’t be NULL.
- Returns:
0 on success, negative error code on failure.
-
int bf_codegen_marsh(const struct bf_codegen *codegen, struct bf_marsh **marsh)#
-
int bf_codegen_unmarsh(const struct bf_marsh *marsh, struct bf_codegen **codegen)#
-
void bf_codegen_dump(const struct bf_codegen *codegen, prefix_t *prefix)#
-
struct bf_program *bf_codegen_get_program(const struct bf_codegen *codegen, uint32_t ifindex)#
Get a codegen’s BPF program for a given interface.
- Parameters:
codegen – Codegen containing the BPF program to get. Can’t be NULL.
ifindex – Interface to get the BPF program for.
- Returns:
BPF program for the given interface, or NULL if not found.
-
int bf_codegen_get_counter(const struct bf_codegen *codegen, uint32_t counter_idx, struct bf_counter *counter)#
Get packets and bytes counter at a specific index.
Counters are referenced by their index in the counters map. There are 1 more counter in the map than the number of rules. This last counter (the last in the map) is dedicated to the policy.
The counter from all the program generated from
codegen
are summarised together.- Parameters:
codegen – Codegen to get the counter for. Can’t be NULL.
counter_idx – Index of the counter to get. If
counter_idx
doesn’t correspond to a valid index, -E2BIG is returned.counter – Counter structure to fill with the counter values. Can’t be NULL.
- Returns:
0 on success, or a negative errno value on failure.
-
int bf_codegen_update(struct bf_codegen *codegen)#
Update the BPF programs for a codegen.
- Parameters:
codegen – Codegen to update. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_codegen_new(struct bf_codegen **codegen)#
- file codegen.h
- #include <stdint.h>#include “core/counter.h”#include “core/dump.h”#include “core/hook.h”#include “core/list.h”#include “core/verdict.h”#include “shared/front.h”
Defines
-
_cleanup_bf_codegen_#
Functions
-
int bf_codegen_new(struct bf_codegen **codegen)
Allocate and initialise a new codegen.
- Parameters:
codegen – Codegen to initialise. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
void bf_codegen_free(struct bf_codegen **codegen)
Free a codegen.
If one or more programs are loaded, they won’t be unloaded. Use bf_codegen_unload first to ensure programs are unloaded. This behaviour is expected so bf_codegen can be freed without unloading the BPF program, during a daemon restart for example.
- Parameters:
codegen – Codegen to free. Can’t be NULL.
-
int bf_codegen_generate(struct bf_codegen *codegen)
Generate BPF programs for a codegen.
- Parameters:
codegen – Codegen to generate BPF programs for. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_codegen_update(struct bf_codegen *codegen)
Update the BPF programs for a codegen.
- Parameters:
codegen – Codegen to update. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_codegen_load(struct bf_codegen *codegen, struct bf_codegen *prev_codegen)
Load the BPF program stored in a codegen.
Each program within the codegen will be loaded and attached to its interface.
- Parameters:
codegen – Codegen containing the BPF program to load. Can’t be NULL.
prev_codegen – Codegen to replace. Can be NULL. bf_codegen_load is responsible for unloading the previous codegen. bf_codegen_load doesn’t own
prev_codegen
, and won’t free it.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_codegen_unload(struct bf_codegen *codegen)
Unload a codegen’s BPF programs.
- Parameters:
codegen – Codegen containing the BPF program to unload. Can’t be NULL.
- Returns:
0 on success, negative error code on failure.
-
int bf_codegen_marsh(const struct bf_codegen *codegen, struct bf_marsh **marsh)
-
int bf_codegen_unmarsh(const struct bf_marsh *marsh, struct bf_codegen **codegen)
-
void bf_codegen_dump(const struct bf_codegen *codegen, prefix_t *prefix)
-
struct bf_program *bf_codegen_get_program(const struct bf_codegen *codegen, uint32_t ifindex)
Get a codegen’s BPF program for a given interface.
- Parameters:
codegen – Codegen containing the BPF program to get. Can’t be NULL.
ifindex – Interface to get the BPF program for.
- Returns:
BPF program for the given interface, or NULL if not found.
-
int bf_codegen_get_counter(const struct bf_codegen *codegen, uint32_t counter_idx, struct bf_counter *counter)
Get packets and bytes counter at a specific index.
Counters are referenced by their index in the counters map. There are 1 more counter in the map than the number of rules. This last counter (the last in the map) is dedicated to the policy.
The counter from all the program generated from
codegen
are summarised together.- Parameters:
codegen – Codegen to get the counter for. Can’t be NULL.
counter_idx – Index of the counter to get. If
counter_idx
doesn’t correspond to a valid index, -E2BIG is returned.counter – Counter structure to fill with the counter values. Can’t be NULL.
- Returns:
0 on success, or a negative errno value on failure.
-
_cleanup_bf_codegen_#
- file dump.c
- #include “dump.h”#include <stddef.h>#include <string.h>#include “opts.h”
Defines
-
_DUMP_HEXDUMP_LEN#
Functions
-
void bf_dump_prefix_push(prefix_t *prefix)#
Add a symbol to the prefix string.
- Parameters:
prefix – Prefix string.
-
prefix_t *bf_dump_prefix_last(prefix_t *prefix)#
Convert previous node to make is the last of the branch.
- Parameters:
prefix – Prefix string.
- Returns:
prefix
-
void bf_dump_prefix_pop(prefix_t *prefix)#
Remove rightmost branch from the prefix string.
When a subtree is completed and we backout to a different branch, we need to remove the rightmost branch from the prefix to continue.
- Parameters:
prefix – Prefix string.
-
void bf_dump_hex(prefix_t *prefix, const void *data, size_t len)#
Dump the data buffer in hexedecimal format.
Each byte in
data
will be printed as 0x%02x, with 8 bytes on each row.- Parameters:
prefix – Prefix string.
data – Data buffer to print.
len – Size of the data buffer.
-
_DUMP_HEXDUMP_LEN#
- file dump.c
- #include “generator/dump.h”#include <linux/bpf.h>#include <linux/bpf_common.h>#include <stdio.h>#include “core/dump.h”#include “core/logger.h”#include “generator/program.h”#include “shared/helper.h”
Defines
-
BF_INSN_CLS(insn)#
-
BF_INSN_CODE(insn)#
-
BF_INSN_SRC(insn)#
-
BF_INSN_MODE(insn)#
-
BF_INSN_SIZE(insn)#
-
BF_IMM_BUF_LEN#
Functions
-
static const char *_bpf_reg(unsigned char reg)#
-
static const char *_bf_op(const struct bpf_insn *insn)#
-
static const char *_bf_src(const struct bpf_insn *insn, char (*imm_buf)[BF_IMM_BUF_LEN])#
-
static void _bf_program_dump_alu_insn(const struct bf_program *program, const size_t *insn_idx, prefix_t *prefix)#
-
static const char *_bf_jmp_op(const struct bpf_insn *insn)#
-
static const char *_bpf_helper(const struct bpf_insn *insn)#
-
static void _bf_program_dump_jmp_insn(const struct bf_program *program, const size_t *insn_idx, prefix_t *prefix)#
-
static const char *_bpf_ldst_size(const struct bpf_insn *insn)#
-
static void _bf_program_dump_imm64_insn(const struct bf_program *program, size_t *insn_idx, prefix_t *prefix)#
-
static void _bf_program_dump_ldst_insn(const struct bf_program *program, size_t *insn_idx, prefix_t *prefix)#
-
static void _bf_program_dump_insn(const struct bf_program *program, size_t *insn_idx, prefix_t *prefix)#
-
static void _bf_program_dump_raw(const struct bf_program *program, const size_t *insn_idx, prefix_t *prefix)#
-
void bf_program_dump_bytecode(const struct bf_program *program, bool with_raw)#
-
BF_INSN_CLS(insn)#
- file dump.c
- #include “dump.h”#include <linux/netfilter.h>#include <linux/netfilter/x_tables.h>#include <linux/netfilter_ipv4/ip_tables.h>#include <stdbool.h>#include <stdint.h>#include <stdio.h>#include “core/dump.h”#include “helpers.h”#include “shared/helper.h”
Functions
-
static inline void ipt_dump_counters(const struct ipt_counters *counters, prefix_t *prefix)#
Dump content of
ipt_counters
structure.- Parameters:
counters –
ipt_counters
structure. Must be non-NULL.p –
log_prefix
structure.
-
static void ipt_dump_ip(const struct ipt_ip *ip, prefix_t *prefix)#
Dump content of
ipt_ip
structure.- Parameters:
ip –
ipt_ip
structure. Must be non-NULL.p –
log_prefix
structure.
-
static void ipt_dump_match(const struct ipt_entry_match *match, prefix_t *prefix)#
Dump content of
ipt_entry_match
structure.- Parameters:
match –
ipt_entry_match
structure. Must be non-NULL.p –
log_prefix
structure.
-
static inline int _bf_ipt_convert_verdict(int verdict)#
-
static void ipt_dump_target(const struct ipt_entry_target *target, prefix_t *prefix)#
Dump content of
ipt_entry_target
structure.- Parameters:
target –
ipt_entry_target
structure. Must be non-NULL.p –
log_prefix
structure.
-
void bf_ipt_dump_replace(struct ipt_replace *ipt, prefix_t *prefix)#
Dump content of bpfilter_ipt_replace structure.
- Parameters:
ipt – iptable’s ipt_replace structure. Must be non-NULL.
prefix – Prefix to print on each line.
Variables
- static const char * hook_name [] = {[NF_INET_PRE_ROUTING] = "PRE_ROUTING", [NF_INET_LOCAL_IN] = "LOCAL_IN",[NF_INET_FORWARD] = "FORWARD", [NF_INET_LOCAL_OUT] = "LOCAL_OUT",[NF_INET_POST_ROUTING] = "POST_ROUTING",}
Map each hook to its name as a string.
- static const char * target_name [] = {[NF_DROP] = "DROP", [NF_ACCEPT] = "ACCEPT", [NF_STOLEN] = "STOLEN",[NF_QUEUE] = "QUEUE", [NF_REPEAT] = "REPEAT", [NF_STOP] = "STOP",}
Map each target to its name as a string.
-
static inline void ipt_dump_counters(const struct ipt_counters *counters, prefix_t *prefix)#
- file dump.h
- #include “core/logger.h”
Defines
-
DUMP(p, fmt, ...)#
Dump prefixed-formatted string.
- Parameters:
p – Prefix string.
fmt – Log format string.
... – Variadic argument list for
fmt
.
-
IP4_SPLIT(addr)#
Split 32 bits IPv4 representation into four 8 bits components.
- Parameters:
addr – 32 bits IPv4 address to split.
-
BIN_SPLIT(byte)#
Split a byte into 8 characters representing each bit.
- Parameters:
byte – Byte to split.
-
BIN_FMT#
Format to use with BIN_SPLIT() to print a byte as 8 bits.
-
DUMP_PREFIX_LEN#
Maximum length of the prefix buffer.
Functions
- typedef char (prefix_t)[DUMP_PREFIX_LEN]
-
void bf_dump_prefix_push(prefix_t *prefix)
Add a symbol to the prefix string.
- Parameters:
prefix – Prefix string.
-
prefix_t *bf_dump_prefix_last(prefix_t *prefix)
Convert previous node to make is the last of the branch.
- Parameters:
prefix – Prefix string.
- Returns:
prefix
-
void bf_dump_prefix_pop(prefix_t *prefix)
Remove rightmost branch from the prefix string.
When a subtree is completed and we backout to a different branch, we need to remove the rightmost branch from the prefix to continue.
- Parameters:
prefix – Prefix string.
-
void bf_dump_hex(prefix_t *prefix, const void *data, size_t len)
Dump the data buffer in hexedecimal format.
Each byte in
data
will be printed as 0x%02x, with 8 bytes on each row.- Parameters:
prefix – Prefix string.
data – Data buffer to print.
len – Size of the data buffer.
-
DUMP(p, fmt, ...)#
- file dump.h
- #include <stdbool.h>
Functions
-
void bf_program_dump_bytecode(const struct bf_program *program, bool with_raw)
-
void bf_program_dump_bytecode(const struct bf_program *program, bool with_raw)
- file dump.h
- #include “core/dump.h”
Functions
-
void bf_ipt_dump_replace(struct ipt_replace *ipt, prefix_t *prefix)
Dump content of bpfilter_ipt_replace structure.
- Parameters:
ipt – iptable’s ipt_replace structure. Must be non-NULL.
prefix – Prefix to print on each line.
-
void bf_ipt_dump_replace(struct ipt_replace *ipt, prefix_t *prefix)
- file fixup.c
- #include “fixup.h”#include <errno.h>#include <stdlib.h>#include “core/dump.h”#include “shared/helper.h”
Functions
-
const char *bf_fixup_type_to_str(enum bf_fixup_type type)#
-
const char *bf_fixup_function_to_str(enum bf_fixup_function function)#
-
void bf_fixup_dump(const struct bf_fixup *fixup, char (*prefix)[DUMP_PREFIX_LEN])#
-
const char *bf_fixup_type_to_str(enum bf_fixup_type type)#
- file fixup.h
- #include <stddef.h>#include “core/dump.h”
Defines
-
_cleanup_bf_fixup_#
Enums
-
enum bf_fixup_insn_type#
Values:
-
enumerator BF_CODEGEN_FIXUP_INSN_OFF#
-
enumerator BF_CODEGEN_FIXUP_INSN_IMM#
-
enumerator _BF_CODEGEN_FIXUP_INSN_MAX_MAX#
-
enumerator BF_CODEGEN_FIXUP_INSN_OFF#
Functions
-
const char *bf_fixup_type_to_str(enum bf_fixup_type type)
-
const char *bf_fixup_function_to_str(enum bf_fixup_function function)
-
int bf_fixup_new(struct bf_fixup **fixup)
-
void bf_fixup_free(struct bf_fixup **fixup)
-
void bf_fixup_dump(const struct bf_fixup *fixup, char (*prefix)[DUMP_PREFIX_LEN])
-
_cleanup_bf_fixup_#
- file jmp.c
- #include “generator/jmp.h”#include “generator/program.h”
- file jmp.h
- #include <linux/bpf.h>#include <stddef.h>
bf_jmpctx is a helper structure to manage jump instructions in the program. It is used to emit a jump instruction and automatically clean it up when the scope is exited, thanks to GCC’s
cleanup
attribute.Example:
// Within a function body { _cleanup_bf_jmpctx_ struct bf_jmpctx ctx = bf_jmpctx_get(program, BPF_JMP_IMM(BPF_JEQ, BF_REG_2, 0, 0)); EMIT(program, BPF_MOV64_IMM(BF_REG_RET, program->runtime.ops->get_verdict( BF_VERDICT_ACCEPT))); EMIT(program, BPF_EXIT_INSN()); }
ctx
is a variable local to the scope, marked with_cleanup_bf_jmpctx_
. The second argument tobf_jmpctx_get
is the jump instruction to emit, with the correct condition. When the scope is exited, the jump instruction is automatically updated to point to the current instruction, which is after the scope.Hence, all the instructions emitted within the scope will be executed if the condition is not met. If the condition is met, then the program execution will continue with the first instruction after the scope.
Defines
-
_cleanup_bf_jmpctx_
Cleanup attribute for a bf_jmpctx variable.
-
_cleanup_bf_jmpctx_
- file nf.c
- #include “generator/nf.h”#include <linux/bpf.h>#include <linux/bpf_common.h>#include <linux/if_ether.h>#include <errno.h>#include <stddef.h>#include “core/bpf.h”#include “core/btf.h”#include “core/logger.h”#include “core/verdict.h”#include “generator/jmp.h”#include “generator/program.h”#include “generator/reg.h”#include “generator/stub.h”#include “shared/helper.h”#include “external/filter.h”
Functions
-
static int _nf_gen_inline_prologue(struct bf_program *program)#
-
static int _nf_gen_inline_epilogue(struct bf_program *program)#
-
static int _nf_get_verdict(enum bf_verdict verdict)#
Convert a standard verdict into a return value.
- Parameters:
verdict – Verdict to convert. Must be valid.
- Returns:
TC return code corresponding to the verdict, as an integer.
-
static int _nf_attach_prog_pre_unload(struct bf_program *program, int *prog_fd, union bf_flavor_attach_attr *attr)#
-
static int _nf_attach_prog_post_unload(struct bf_program *program, int *prog_fd, union bf_flavor_attach_attr *attr)#
-
static int _nf_detach_prog(struct bf_program *program)#
Unload the Netfilter BPF bytecode image.
- Parameters:
codegen – Codegen containing the image to unload. Can’t be NULL.
- Returns:
0 on success, negative error code on failure.
Variables
-
const struct bf_flavor_ops bf_flavor_ops_nf = {.gen_inline_prologue = _nf_gen_inline_prologue, .gen_inline_epilogue = _nf_gen_inline_epilogue, .get_verdict = _nf_get_verdict, .attach_prog_pre_unload = _nf_attach_prog_pre_unload, .attach_prog_post_unload = _nf_attach_prog_post_unload, .detach_prog = _nf_detach_prog,}#
-
static int _nf_gen_inline_prologue(struct bf_program *program)#
- file nf.h
- #include <net/if.h>#include <linux/netfilter.h>#include “core/flavor.h”#include “core/hook.h”
Functions
-
enum nf_inet_hooks bf_hook_to_nf_hook(enum bf_hook hook)
Variables
-
const struct bf_flavor_ops bf_flavor_ops_nf
-
enum nf_inet_hooks bf_hook_to_nf_hook(enum bf_hook hook)
- file print.c
- #include “generator/print.h”#include <linux/bpf.h>#include <stddef.h>#include <stdint.h>#include “core/bpf.h”#include “core/logger.h”#include “opts.h”#include “shared/helper.h”
Defines
-
make_print_str(id, str)#
Functions
-
size_t _bf_compute_offsets(void)#
-
int bf_print_setup(void)
Setup context to allow generated BPF programs to print messages.
The various printable messages are stored in an array of strings, this function will concatenate them into a unique nul-separated buffer of string and store it in a BPF map.
- Returns:
0 on success, or negative errno value on error.
-
void bf_print_teardown(void)
Teardown the printing context.
The file descriptor of the BPF map containing the printable messages will be closed. The map will remain on the system until the last BPF program using it is unloaded.
-
int bf_print_fd(void)
Get the file descriptor of the BPF map containing the printable messages.
- Returns:
File descriptor of the BPF map containing the printable messages.
-
size_t bf_print_msg_size(enum bf_print_msg msg_id)
Get the size of a printable message.
- Parameters:
msg_id – ID of the message to get the size of.
- Returns:
Size of the message.
-
size_t bf_print_msg_offset(enum bf_print_msg msg_id)
Get the offset of a printable message in the BPF map.
- Parameters:
msg_id – ID of the message to get the offset of.
- Returns:
Offset of the message in the BPF map.
Variables
-
size_t offset#
-
size_t len#
-
const char *str#
- static struct _bf_print_strings [] = { make_print_str(BF_PRINT_NO_DYNPTR, "failed to create a dynamic pointer"), make_print_str(BF_PRINT_NO_SLICE,"failed to create a dynamic pointer slice"),make_print_str(BF_PRINT_NO_L2, "no L2 header available in packet data"), make_print_str(BF_PRINT_NO_L3, "no L3 header available in packet data"), make_print_str(BF_PRINT_NO_IPV4, "L3 header is not IPv4"),}
-
static int _bf_fd#
-
static const char *_bf_print_strs_path = "/sys/fs/bpf/bf_print_strs"#
-
make_print_str(id, str)#
- file print.h
- #include <stddef.h>
The
bf_print_*
functions relates to the message printing facilities provided to the generated BPF programs.bpfilter
provides a set of predefined messages that can be printed from the BPF programs.During
bpfilter
initialization, the predefined messages are concatenated into a unique buffer or nul-separated strings. The offset of each message is saved inbpfilter
runtime context for later use. The resulting strings buffer is then stored in a BPF map.All the log messages defined in
bpfilter
prefixed with"$IFINDEX:$HOOK:$FRONT: "
, so log messages can be mapped back to a specific BPF program.The file descriptor to the loaded BPF map is stored within
bpfilter
runtime context. It is not pinned and will be closed whenbpfilter
is stopped. If any BPF program refers to the map, the kernel will keep it until the last BPF program using it is unloaded. This behaviour is compatible withbpfilter
transient mode:If
--transient
is used,bpfilter
will create the map at startup, create zero or more BPF programs using it. Whenbpfilter
is stopped, the map’s file descriptor will be closed and all the BPF programs created bybpfilter
will be unloaded. The map will be removed from the system.If
--transient
is not used,bpfilter
will create the map at startup, create zero or more BPF programs using it. Whenbpfilter
is stopped, the map’s file descriptor will be closed. The map will remain on the system if any BPF program refers to it. On the next start,bpfilter
will create a new map and use it for new BPF programs, while existing BPF program still refer to the old map. This mechanism prevents conflict ifbpfilter
is updated and restarted: existing programs use the old map, new programs use the new map.
Note
All the message strings are stored in a single BPF map entry in order to benefit from
BPF_PSEUDO_MAP_VALUE
which allows lookup free direct value access for maps. Hence, using a unique instruction,bpfilter
can load the map’s file descriptor and get the address of a message in the buffer. See https://lore.kernel.org/bpf/20190409210910.32048-2-daniel@iogearbox.net.Defines
-
EMIT_PRINT(program, msg_id)
Emit BPF instructions to print a predefined message.
This function will insert mulitple instruction into the BPF program to: load the messages map’s file descriptor, copy into the argument registers: the message’s length, the program’s ifindex, hook and front. Then it will call
bpf_trace_printk()
to print the message.Warning
As every
EMIT_*
macro,EMIT_PRINT()
will callreturn
if an error occurs. Hence, it must be used within a function that returns an integer.- Parameters:
program – Program to emit the instructions to. Must not be NULL.
msg_id – Identifier of the message to print. See bf_print_msg for the list of predefined messages.
Enums
-
enum bf_print_msg
Identifiers of the predefined printable messages.
Values:
-
enumerator BF_PRINT_NO_DYNPTR
-
enumerator BF_PRINT_NO_SLICE
-
enumerator BF_PRINT_NO_L2
-
enumerator BF_PRINT_NO_L3
-
enumerator BF_PRINT_NO_IPV4
-
enumerator _BF_PRINT_MAX
-
enumerator BF_PRINT_NO_DYNPTR
Functions
-
int bf_print_setup(void)
Setup context to allow generated BPF programs to print messages.
The various printable messages are stored in an array of strings, this function will concatenate them into a unique nul-separated buffer of string and store it in a BPF map.
- Returns:
0 on success, or negative errno value on error.
-
void bf_print_teardown(void)
Teardown the printing context.
The file descriptor of the BPF map containing the printable messages will be closed. The map will remain on the system until the last BPF program using it is unloaded.
-
int bf_print_fd(void)
Get the file descriptor of the BPF map containing the printable messages.
- Returns:
File descriptor of the BPF map containing the printable messages.
-
size_t bf_print_msg_size(enum bf_print_msg msg_id)
Get the size of a printable message.
- Parameters:
msg_id – ID of the message to get the size of.
- Returns:
Size of the message.
-
size_t bf_print_msg_offset(enum bf_print_msg msg_id)
Get the offset of a printable message in the BPF map.
- Parameters:
msg_id – ID of the message to get the offset of.
- Returns:
Offset of the message in the BPF map.
- file program.c
- #include “generator/program.h”#include <net/if.h>#include <linux/bpf.h>#include <linux/bpf_common.h>#include <linux/if_ether.h>#include <linux/netfilter_ipv4/ip_tables.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include “core/bpf.h”#include “core/btf.h”#include “core/counter.h”#include “core/flavor.h”#include “core/logger.h”#include “core/marsh.h”#include “core/rule.h”#include “core/verdict.h”#include “generator/stub.h”#include “shared/helper.h”#include “external/filter.h”
Defines
-
_BF_PROGRAM_DEFAULT_IMG_SIZE#
Functions
-
int bf_program_new(struct bf_program **program, int ifindex, enum bf_hook hook, enum bf_front front)#
-
void bf_program_free(struct bf_program **program)#
-
int bf_program_marsh(const struct bf_program *program, struct bf_marsh **marsh)#
-
int bf_program_unmarsh(const struct bf_marsh *marsh, struct bf_program **program)#
-
void bf_program_dump(const struct bf_program *program, prefix_t *prefix)#
-
static inline size_t _round_next_power_of_2(size_t x)#
-
int bf_program_grow_img(struct bf_program *program)#
-
static void _bf_program_fixup_insn(struct bpf_insn *insn, enum bf_fixup_insn_type type, int32_t v)#
-
static int _bf_program_fixup(struct bf_program *program, enum bf_fixup_type type, const union bf_fixup_attr *attr)#
-
static int _bf_program_generate_rule(struct bf_program *program, struct bf_rule *rule)#
-
static int _bf_program_generate_add_counter(struct bf_program *program)#
Generate a function to update the packets counter.
Assuming:
BF_ARG_1: file descriptor of the counters map.
BF_ARG_2: index of the rule in the counters map.
BF_ARG_3: packet size
- Todo:
Random jump into the bytecode should be calculated by the daemon, not the developer.
Create a fixup to jump to the end of a function.
Set BF_REG_0 to !0 on failure, so we don’t drop the packet.
- Parameters:
program – Program to emit the function into. Can not be NULL.
- Returns:
0 on success, or negative errno value on error.
-
static int _bf_program_generate_functions(struct bf_program *program)#
-
static int _bf_program_load_counters_map(struct bf_program *program, int *fd)#
-
int bf_program_emit(struct bf_program *program, struct bpf_insn insn)#
-
int bf_program_emit_kfunc_call(struct bf_program *program, const char *name)#
-
int bf_program_emit_fixup(struct bf_program *program, enum bf_fixup_type type, struct bpf_insn insn)#
-
int bf_program_emit_fixup_call(struct bf_program *program, enum bf_fixup_function function)#
-
static int _bf_program_generate_runtime_init(struct bf_program *program)#
-
int bf_program_generate(struct bf_program *program, bf_list *rules, enum bf_verdict policy)#
-
int bf_program_update(struct bf_program *program, bf_list *rules, enum bf_verdict policy)#
Update the program’s bytecode.
This function will regenerate the BPF bytecode for
program
based on the given rules. The new bytecode will be loaded into the kernel to replace the current program. The program’s metadata (ifindex, hook, front) will not be modified.Note
This function purposefully update the bytecode and the program in one step. This is to ensure that the program is always in a consistent state.
- Parameters:
program – Program to regenerate. Can not be NULL.
rules – List of rules to use to regenerate the program. Can not be NULL.
policy – Verdict to use when no rule matches. Must be one of bf_verdict.
- Returns:
0 on success, negative errno code on failure.
-
int bf_program_load(struct bf_program *program, struct bf_program *prev_program)#
Load the program into the kernel.
- Parameters:
program – Program to load. Can not be NULL.
prev_program – Previous program to unload. Can be NULL. If not NULL, bf_program_load will unload
prev_program
between attach_prog_pre_unload and attach_prog_post_unload calls.
- Returns:
0 on success, negative errno code on failure.
-
int bf_program_unload(struct bf_program *program)#
-
int bf_program_get_counter(const struct bf_program *program, uint32_t counter_idx, struct bf_counter *counter)#
-
int bf_codegen_set_counters(struct bf_program *program, const struct bf_counter *counters)#
-
_BF_PROGRAM_DEFAULT_IMG_SIZE#
- file program.h
- #include <net/if.h>#include <linux/bpf.h>#include <linux/icmp.h>#include <linux/if_ether.h>#include <linux/ip.h>#include <linux/tcp.h>#include <linux/udp.h>#include <stddef.h>#include <stdint.h>#include “core/dump.h”#include “core/hook.h”#include “core/list.h”#include “core/verdict.h”#include “generator/fixup.h”#include “generator/print.h”#include “generator/reg.h”#include “shared/front.h”#include “external/filter.h”
Defines
-
PIN_PATH_LEN#
-
BF_PROG_CTX_OFF(field)#
Convenience macro to get the offset of a field in bf_program_context.
-
EMIT(program, x)#
-
EMIT_KFUNC_CALL(program, function)#
-
EMIT_FIXUP(program, type, insn)#
-
EMIT_FIXUP_CALL(program, function)#
-
EMIT_LOAD_FD_FIXUP(program, reg)#
-
_cleanup_bf_program_#
Functions
- struct bf_program_context bf_aligned (8)
-
int bf_program_new(struct bf_program **program, int ifindex, enum bf_hook hook, enum bf_front front)
-
void bf_program_free(struct bf_program **program)
-
int bf_program_marsh(const struct bf_program *program, struct bf_marsh **marsh)
-
int bf_program_unmarsh(const struct bf_marsh *marsh, struct bf_program **program)
-
void bf_program_dump(const struct bf_program *program, prefix_t *prefix)
-
int bf_program_grow_img(struct bf_program *program)
-
int bf_program_emit(struct bf_program *program, struct bpf_insn insn)
-
int bf_program_emit_kfunc_call(struct bf_program *program, const char *name)
-
int bf_program_emit_fixup(struct bf_program *program, enum bf_fixup_type type, struct bpf_insn insn)
-
int bf_program_emit_fixup_call(struct bf_program *program, enum bf_fixup_function function)
-
int bf_program_generate(struct bf_program *program, bf_list *rules, enum bf_verdict policy)
-
int bf_program_update(struct bf_program *program, bf_list *rules, enum bf_verdict policy)
Update the program’s bytecode.
This function will regenerate the BPF bytecode for
program
based on the given rules. The new bytecode will be loaded into the kernel to replace the current program. The program’s metadata (ifindex, hook, front) will not be modified.Note
This function purposefully update the bytecode and the program in one step. This is to ensure that the program is always in a consistent state.
- Parameters:
program – Program to regenerate. Can not be NULL.
rules – List of rules to use to regenerate the program. Can not be NULL.
policy – Verdict to use when no rule matches. Must be one of bf_verdict.
- Returns:
0 on success, negative errno code on failure.
-
int bf_program_load(struct bf_program *program, struct bf_program *prev_program)
Load the program into the kernel.
- Parameters:
program – Program to load. Can not be NULL.
prev_program – Previous program to unload. Can be NULL. If not NULL, bf_program_load will unload
prev_program
between attach_prog_pre_unload and attach_prog_post_unload calls.
- Returns:
0 on success, negative errno code on failure.
-
int bf_program_unload(struct bf_program *program)
-
int bf_program_get_counter(const struct bf_program *program, uint32_t counter_idx, struct bf_counter *counter)
-
int bf_program_set_counters(struct bf_program *program, const struct bf_counter *counters)#
Variables
-
void *arg#
Argument passed to the BPF program, it content depends on the BPF program type.
-
struct bpf_dynptr dynptr#
BPF dynamic pointer representing the packet data. Dynamic pointers are used with every program type.
-
uint64_t pkt_size#
Total size of the packet.
-
uint32_t l3_offset#
Offset of the layer 3 header in the packet.
-
uint32_t l4_offset#
Offset of the layer 4 header in the packet.
-
uint8_t l4_proto#
Layer 4 protocol. Set when the L3 header is processed. Used to define how many bytes to read when processing the packet.
-
struct ethhdr _ethhdr#
-
char l2raw#
- union
Layer 2 header.
-
struct iphdr _iphdr#
-
char l3raw#
- union
Layer 3 header.
-
struct icmphdr _icmphdr#
-
struct udphdr _udphdr#
-
struct tcphdr _tcphdr#
-
char l4raw#
- union
Layer 4 header.
-
struct bf_program bf_aligned#
-
PIN_PATH_LEN#
- file reg.h
- #include <linux/bpf.h>#include “external/filter.h”
Enums
-
enum bf_reg#
BPF registers aliases adapted to bpfilter usage.
Values:
-
enumerator BF_REG_0 = BPF_REG_0#
-
enumerator BF_REG_1 = BPF_REG_1#
-
enumerator BF_REG_2 = BPF_REG_2#
-
enumerator BF_REG_3 = BPF_REG_3#
-
enumerator BF_REG_4 = BPF_REG_4#
-
enumerator BF_REG_5 = BPF_REG_5#
-
enumerator BF_REG_6 = BPF_REG_6#
-
enumerator BF_REG_7 = BPF_REG_7#
-
enumerator BF_REG_8 = BPF_REG_8#
-
enumerator BF_REG_9 = BPF_REG_9#
-
enumerator BF_REG_10 = BPF_REG_10#
-
enumerator BF_ARG_1 = BPF_REG_1#
-
enumerator BF_ARG_2 = BPF_REG_2#
-
enumerator BF_ARG_3 = BPF_REG_3#
-
enumerator BF_ARG_4 = BPF_REG_4#
-
enumerator BF_ARG_5 = BPF_REG_5#
-
enumerator BF_REG_L2 = BPF_REG_6#
-
enumerator BF_REG_L3 = BPF_REG_7#
-
enumerator BF_REG_L4 = BPF_REG_8#
-
enumerator BF_REG_CTX = BPF_REG_9#
-
enumerator BF_REG_RET = BPF_REG_0#
-
enumerator BF_REG_FP = BPF_REG_FP#
-
enumerator BF_REG_0 = BPF_REG_0#
-
enum bf_reg#
- file stub.c
- #include “generator/stub.h”#include <arpa/inet.h>#include <linux/bpf.h>#include “core/flavor.h”#include “generator/jmp.h”#include “generator/program.h”#include “generator/reg.h”#include “shared/helper.h”#include “external/filter.h”
Functions
-
int bf_stub_memclear(struct bf_program *program, enum bf_reg addr_reg, size_t size)#
Emit instructions to clear a memory region.
Generate BPF instructions to clear (set to 0) a memory region, from a register containing the address of the memory region to clear, and the size.
Warning
The memory area must be aligned on 8 bytes (address and size), as the region is cleared 8 bytes at a time.
- Parameters:
program – Program to emit instructions into.
addr_reg – Register containing the address to clear.
size – Size of the memory region to clear.
- Returns:
0 on success, or negative errno value on error.
-
static int _stub_make_ctx_dynptr(struct bf_program *program, enum bf_reg arg_reg, const char *kfunc)#
Generate stub to create a dynptr.
- Parameters:
program – Program to generate the stub for. Must not be NULL.
arg_reg – Register where the first argument to the dynptr creation function is located (SKB or xdp_md structure).
kfunc – Name of the kfunc to use to create the dynamic pointer.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_make_ctx_xdp_dynptr(struct bf_program *program, enum bf_reg md_reg)#
Emit instructions to get a dynptr for an XDP program.
Prepare arguments and call bpf_dynptr_from_xdp(). If the return value is different from 0, jump to the end of the program and accept the packet.
The initialised dynptr is stored in the program’s runtime context.
- Parameters:
program – Program to emit instructions into.
md_reg – Scratch register containing the pointer to the xdp_md.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_make_ctx_skb_dynptr(struct bf_program *program, enum bf_reg skb_reg)#
Emit instructions to get a dynptr for an XDP program.
Prepare arguments and call bpf_dynptr_from_skb(). If the return value is different from 0, jump to the end of the program and accept the packet.
The initialised dynptr is stored in the program’s runtime context.
- Parameters:
program – Program to emit instructions into.
skb_reg – Scratch register containing the pointer to the skb.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_get_l2_eth_hdr(struct bf_program *program)#
Emit instructions to get a dynptr slice for the packet’s L2 Ethernet header.
Store bpf_dynptr_slice arguments into:
BF_ARG_1: pointer to the dynptr located in the context.
BF_ARG_2: offset of the slice, in the dynptr. Always 0, as L2 Ethernet is the first header.
BF_ARG_3: pointer to the buffer to store the slice into. Each header buffer is located in the context.
BF_ARG_4: size of the buffer. Always ETH_HLEN, as L2 Ethernet is the first header. Then, call bpf_dynptr_slice(). If the return value is different from 0, jump to the end of the program. Finally:
Copy the address of the header into BF_REG_L2.
Load the header’s h_proto field to determine the L3 protocol. If L3 protocol is not IPv4 (the only supported protocol for now), jump to the end of the program.
Store the offset of the L3 header in the context.
- Parameters:
program – Program to emit instructions into.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_get_l3_ipv4_hdr(struct bf_program *program)#
Emit instructions to get a dynptr slice for the packet’s L3 IPv4 header.
Store bpf_dynptr_slice arguments into:
BF_ARG_1: pointer to the dynptr located in the context.
BF_ARG_2: offset of the slice, in the dynptr. Get it from l3_offset field in the context. This field is either 0, or set when processing layer 2 header.
BF_ARG_3: pointer to the buffer to store the slice into.
BF_ARG_4: size of the buffer, expected to be an IPv4 header. Then, call bpf_dynptr_slice(). If the return value is different from 0, jump to the end of the program. Finally:
Store the address of the header into BF_REG_L3.
Compute the offset of the L4 header:
Load ip.ihl into BF_REG_1
Add ctx.l3_offset to it.
Copy it back to the context.
Store L4 protocol into the context.
- Parameters:
program – Program to emit instructions into.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_get_l4_hdr(struct bf_program *program)#
Emit instructions to get a dynptr slice for the packet’s L4 header.
Store bpf_dynptr_slice arguments into:
BF_ARG_1: pointer to the dynptr located in the context.
BF_ARG_2: offset of the slice, in the dynptr. Get it from l4_offset field in the context. This field is set when processing layer 2 header.
BF_ARG_3: pointer to the buffer to store the slice into.
BF_ARG_4: size of the buffer, need to be computed depending ctx.l4_proto. If ctx.l4_proto is not supported, jump to the end of the program. Then, call bpf_dynptr_slice(). If the return value is different from 0, jump to the end of the program. Finally, copy the address of the header into BF_REG_L4.
- Parameters:
program – Program to emit instructions into.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_memclear(struct bf_program *program, enum bf_reg addr_reg, size_t size)#
- file stub.h
- #include <stddef.h>#include “generator/reg.h”
Functions
-
int bf_stub_memclear(struct bf_program *program, enum bf_reg addr_reg, size_t size)
Emit instructions to clear a memory region.
Generate BPF instructions to clear (set to 0) a memory region, from a register containing the address of the memory region to clear, and the size.
Warning
The memory area must be aligned on 8 bytes (address and size), as the region is cleared 8 bytes at a time.
- Parameters:
program – Program to emit instructions into.
addr_reg – Register containing the address to clear.
size – Size of the memory region to clear.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_make_ctx_xdp_dynptr(struct bf_program *program, enum bf_reg md_reg)
Emit instructions to get a dynptr for an XDP program.
Prepare arguments and call bpf_dynptr_from_xdp(). If the return value is different from 0, jump to the end of the program and accept the packet.
The initialised dynptr is stored in the program’s runtime context.
- Parameters:
program – Program to emit instructions into.
md_reg – Scratch register containing the pointer to the xdp_md.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_make_ctx_skb_dynptr(struct bf_program *program, enum bf_reg skb_reg)
Emit instructions to get a dynptr for an XDP program.
Prepare arguments and call bpf_dynptr_from_skb(). If the return value is different from 0, jump to the end of the program and accept the packet.
The initialised dynptr is stored in the program’s runtime context.
- Parameters:
program – Program to emit instructions into.
skb_reg – Scratch register containing the pointer to the skb.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_get_l2_eth_hdr(struct bf_program *program)
Emit instructions to get a dynptr slice for the packet’s L2 Ethernet header.
Store bpf_dynptr_slice arguments into:
BF_ARG_1: pointer to the dynptr located in the context.
BF_ARG_2: offset of the slice, in the dynptr. Always 0, as L2 Ethernet is the first header.
BF_ARG_3: pointer to the buffer to store the slice into. Each header buffer is located in the context.
BF_ARG_4: size of the buffer. Always ETH_HLEN, as L2 Ethernet is the first header. Then, call bpf_dynptr_slice(). If the return value is different from 0, jump to the end of the program. Finally:
Copy the address of the header into BF_REG_L2.
Load the header’s h_proto field to determine the L3 protocol. If L3 protocol is not IPv4 (the only supported protocol for now), jump to the end of the program.
Store the offset of the L3 header in the context.
- Parameters:
program – Program to emit instructions into.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_get_l3_ipv4_hdr(struct bf_program *program)
Emit instructions to get a dynptr slice for the packet’s L3 IPv4 header.
Store bpf_dynptr_slice arguments into:
BF_ARG_1: pointer to the dynptr located in the context.
BF_ARG_2: offset of the slice, in the dynptr. Get it from l3_offset field in the context. This field is either 0, or set when processing layer 2 header.
BF_ARG_3: pointer to the buffer to store the slice into.
BF_ARG_4: size of the buffer, expected to be an IPv4 header. Then, call bpf_dynptr_slice(). If the return value is different from 0, jump to the end of the program. Finally:
Store the address of the header into BF_REG_L3.
Compute the offset of the L4 header:
Load ip.ihl into BF_REG_1
Add ctx.l3_offset to it.
Copy it back to the context.
Store L4 protocol into the context.
- Parameters:
program – Program to emit instructions into.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_get_l4_hdr(struct bf_program *program)
Emit instructions to get a dynptr slice for the packet’s L4 header.
Store bpf_dynptr_slice arguments into:
BF_ARG_1: pointer to the dynptr located in the context.
BF_ARG_2: offset of the slice, in the dynptr. Get it from l4_offset field in the context. This field is set when processing layer 2 header.
BF_ARG_3: pointer to the buffer to store the slice into.
BF_ARG_4: size of the buffer, need to be computed depending ctx.l4_proto. If ctx.l4_proto is not supported, jump to the end of the program. Then, call bpf_dynptr_slice(). If the return value is different from 0, jump to the end of the program. Finally, copy the address of the header into BF_REG_L4.
- Parameters:
program – Program to emit instructions into.
- Returns:
0 on success, or negative errno value on error.
-
int bf_stub_memclear(struct bf_program *program, enum bf_reg addr_reg, size_t size)
- file tc.c
- #include “generator/tc.h”#include <arpa/inet.h>#include <linux/pkt_cls.h>#include <bpf/libbpf.h>#include <errno.h>#include “core/context.h”#include “core/logger.h”#include “generator/codegen.h”#include “generator/program.h”#include “generator/reg.h”#include “generator/stub.h”#include “shared/front.h”#include “shared/helper.h”#include “external/filter.h”
Functions
-
static int _tc_gen_inline_prologue(struct bf_program *program)#
-
static int _tc_gen_inline_epilogue(struct bf_program *program)#
-
static int _tc_get_verdict(enum bf_verdict verdict)#
Convert a standard verdict into a return value.
- Parameters:
verdict – Verdict to convert. Must be valid.
- Returns:
TC return code corresponding to the verdict, as an integer.
-
static int _tc_attach_prog_pre_unload(struct bf_program *program, int *prog_fd, union bf_flavor_attach_attr *attr)#
Attach the loaded TC program to the proper hook.
- Todo:
How should priority be handled?
This function, as well as many others, is using libbpf. Not all functions uses libbpf to communicate with the kernel. This should be unified.
- Parameters:
program – Program to attach to the TC hook. Can’t be NULL, image must have been previously generated.
fd – File descriptor of the loaded BPF program. Can’t be negative.
attr – Attribute used for 2-step attach workflow.
- Returns:
0 on success, negative error code on failure.
-
static int _tc_attach_prog_post_unload(struct bf_program *program, int *prog_fd, union bf_flavor_attach_attr *attr)#
-
static int _tc_detach_prog(struct bf_program *program)#
Detach the TC BPF program.
- Parameters:
program – Attached TC BPF program. Can’t be NULL.
- Returns:
0 on success, negative errno value on failure.
Variables
-
const struct bf_flavor_ops bf_flavor_ops_tc = {.gen_inline_prologue = _tc_gen_inline_prologue, .gen_inline_epilogue = _tc_gen_inline_epilogue, .get_verdict = _tc_get_verdict, .attach_prog_pre_unload = _tc_attach_prog_pre_unload, .attach_prog_post_unload = _tc_attach_prog_post_unload, .detach_prog = _tc_detach_prog,}#
-
static int _tc_gen_inline_prologue(struct bf_program *program)#
- file tc.h
- #include “core/flavor.h”#include “core/hook.h”
Defines
-
bf_tc_program_handle(program)#
Generate a handle for a TC codegen.
Handles are a way to identify a BPF program within the TC namespace.
- Parameters:
codegen – Codegen to generate a handle for.
- Returns:
32 bits handle for the codegen.
Functions
Variables
-
const struct bf_flavor_ops bf_flavor_ops_tc
-
bf_tc_program_handle(program)#
- file xdp.c
- #include <linux/bpf.h>#include <linux/bpf_common.h>#include <stddef.h>#include <unistd.h>#include “core/bpf.h”#include “core/flavor.h”#include “core/logger.h”#include “core/verdict.h”#include “generator/program.h”#include “generator/reg.h”#include “generator/stub.h”#include “shared/helper.h”#include “external/filter.h”
Functions
-
static int _xdp_gen_inline_prologue(struct bf_program *program)#
Generate XDP program prologue.
Warning
bf_stub_get_l2_eth_hdr will check for L3 protocol. If L3 is not IPv4, the program will be terminated.
- Parameters:
program – Program to generate the prologue for. Must not be NULL.
- Returns:
0 on success, or negative errno value on error.
-
static int _xdp_gen_inline_epilogue(struct bf_program *program)#
-
static int _xdp_get_verdict(enum bf_verdict verdict)#
-
static int _xdp_attach_prog_pre_unload(struct bf_program *program, int *prog_fd, union bf_flavor_attach_attr *attr)#
-
static int _xdp_attach_prog_post_unload(struct bf_program *program, int *prog_fd, union bf_flavor_attach_attr *attr)#
Post unload attach callback.
See bf_flavor_ops::attach_prog_post_unload for more details.
Warning
At this point, the previous XDP program has been detached already. Meaning that no packet will be filtering until the function completes.
- Parameters:
program – Program to unload. Must not be NULL.
prog_fd – File descriptor of the program to unload.
attr – Flavor-specific attributes. Unused for XDP.
- Returns:
0 on success, or negative errno value on failure.
-
static int _xdp_detach_prog(struct bf_program *program)#
Variables
-
const struct bf_flavor_ops bf_flavor_ops_xdp = {.gen_inline_prologue = _xdp_gen_inline_prologue, .gen_inline_epilogue = _xdp_gen_inline_epilogue, .get_verdict = _xdp_get_verdict, .attach_prog_pre_unload = _xdp_attach_prog_pre_unload, .attach_prog_post_unload = _xdp_attach_prog_post_unload, .detach_prog = _xdp_detach_prog,}#
-
static int _xdp_gen_inline_prologue(struct bf_program *program)#
- file xdp.h
- #include “core/flavor.h”
Variables
-
const struct bf_flavor_ops bf_flavor_ops_xdp
-
const struct bf_flavor_ops bf_flavor_ops_xdp
- file main.c
- #include <bits/types/sig_atomic_t.h>#include <errno.h>#include <signal.h>#include <stdbool.h>#include <string.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/un.h>#include <unistd.h>#include “core/btf.h”#include “core/context.h”#include “core/helper.h”#include “core/logger.h”#include “core/marsh.h”#include “generator/print.h”#include “opts.h”#include “shared/front.h”#include “shared/generic.h”#include “shared/helper.h”#include “shared/request.h”#include “shared/response.h”#include “xlate/front.h”
Functions
-
void _sig_handler(int sig)#
Set atomic flag to stop the daemon if specific signals are received.
- Parameters:
sig – Signal number.
-
static int _bf_ensure_runtime_dir(void)#
Ensure the daemon can use the runtime directory.
Check if the current process can access BF_RUNTIME_DIR. If it doesn’t exists, create it with the appropriate permissions. If it exists, check that it is a directory.
- Returns:
0 on success, negative errno value on failure.
-
static int _bf_load(const char *path)#
Load bpfilter’s runtime context from disk.
Read the daemon’s runtime context from
path
and initialize the internal context with it.- Parameters:
path – Path to the context file.
- Returns:
0 on success, negative error code on failure.
-
static int _bf_save(const char *path)#
Save bpfilter’s runtime context to disk.
Marshel the daemon’s runtime context and save it to
path
.- Parameters:
path – Path to the context file.
- Returns:
0 on success, negative error code on failure.
-
static int _bf_init(int argc, char *argv[])#
Initialize bpfilter’s daemon runtime.
Setup signal handler (for graceful shutdown), load context from disk, and initialise various front-ends.
If no context can be loaded, a new one is initialized from scratch.
Front-ends’
init
function is called every time. They are responsible for checking whether they need to perform any initialization or not, depending on the loaded runtime context.Updated context is saved back to disk.
- Todo:
Should the runtime context be saved unconditionally?
- Returns:
0 on success, negative error code on failure.
-
static int _bf_clean(void)#
Clean up bpfilter’s daemon runtime.
- Returns:
0 on success, negative error code on failure.
-
static int _process_request(struct bf_request *request, struct bf_response **response)#
Process a request.
The handler corresponding to
request->front
will be called (if any). If the handler returns 0,response
is expected to be filled, and ready to be returned to the client. If the handler returns a negative error code,response
is filled by process_request with a generated error response and 0 is returned. If generating the error response fails, then 0 is returned.In other words, if 0 is returned,
response
is ready to be sent back, if a negative error code is returned, an error occured duringrequest
processing, and no response is available.- Parameters:
request – Request to process.
response – Response to fill.
- Returns:
0 on success, negative error code on failure.
-
static int _run(void)#
Loop and process requests.
Create a socket and perform blocking accept() calls. For each connection, receive a request, process it, and send the response back.
If a signal is received, _stop_received will be set to 1 by _sig_handler and blocking call to
accept()
will be interrupted.- Returns:
0 on success, negative error code on failure.
-
int main(int argc, char *argv[])#
Variables
-
static volatile sig_atomic_t _stop_received = 0#
Global flag to indicate whether the daemon should stop.
- static const char * context_path = BF_RUNTIME_DIR "/data.bin"
Path to bpfilter’s runtime context file.
bpfilter will periodically save its internal context back to disk, to prevent spurious service interruption to lose information about the current state of the daemon.
This runtime context is read back when the daemon is restarted, so bpfilter can manage the BPF programs that survived the daemon reboot.
-
void _sig_handler(int sig)#
- file opts.c
- #include “opts.h”#include <argp.h>#include <stdint.h>#include “core/logger.h”#include “shared/helper.h”
Functions
-
static error_t _bf_opts_parser(int key, char *arg, struct argp_state *state)#
argp callback to process command line arguments.
- Returns:
0 on succcess, non-zero on failure.
-
int bf_opts_init(int argc, char *argv[])#
-
bool bf_opts_transient(void)#
-
unsigned int bf_opts_bpf_log_buf_len_pow(void)#
-
bool bf_opts_is_front_enabled(enum bf_front front)#
-
bool bf_opts_verbose(void)#
Variables
-
static struct bf_options _opts = {.transient = false, .bpf_log_buf_len_pow = 16, .fronts = 0xffff, .verbose = false,}#
- static struct argp_option options [] = {{"transient", 't', 0, 0,"Do not load or save runtime context and remove all BPF programs on shutdown",0},{"buffer-len", 'b', "BUF_LEN_POW", 0,"Size of the BPF log buffer as a power of 2 (only used when --verbose is used). Default: 16.",0},{"no-iptables", 0x01, 0, 0, "Disable iptables support", 0},{"no-nftables", 0x02, 0, 0, "Disable nftables support", 0},{"verbose", 'v', 0, 0, "Print debug logs", 0},{0},}
-
static error_t _bf_opts_parser(int key, char *arg, struct argp_state *state)#
- file opts.h
- #include <stdbool.h>#include “shared/front.h”
Functions
-
int bf_opts_init(int argc, char *argv[])
-
bool bf_opts_transient(void)
-
unsigned int bf_opts_bpf_log_buf_len_pow(void)
-
bool bf_opts_is_front_enabled(enum bf_front front)
-
bool bf_opts_verbose(void)
-
int bf_opts_init(int argc, char *argv[])
- file front.c
- #include “front.h”#include “shared/helper.h”
Functions
-
const struct bf_front_ops *bf_front_ops_get(enum bf_front front)#
Retrieve the bf_front_ops structure for a specific front.
- Parameters:
front – Front to get the bf_front_ops for.
- Returns:
-
const struct bf_front_ops *bf_front_ops_get(enum bf_front front)#
- file front.h
- #include “shared/front.h”
Functions
-
const struct bf_front_ops *bf_front_ops_get(enum bf_front front)
Retrieve the bf_front_ops structure for a specific front.
- Parameters:
front – Front to get the bf_front_ops for.
- Returns:
-
const struct bf_front_ops *bf_front_ops_get(enum bf_front front)
- file helpers.h
- #include <linux/netfilter_ipv4/ip_tables.h>
Defines
-
ipt_is_hook_enabled(replace, hook)#
Check whether
hook
is enabled inipt_replace
structure.- Parameters:
replace –
ipt_replace
structure.hook – Hook to test.
- Returns:
0 if
hook
is not enabled, any value otherwise.
-
ipt_get_match(entry, offset)#
Get
ipt_entry's
match atoffset
.- Parameters:
entry –
ipt_entry
structure the get the match from. Must be non-NULL.offset – Offset of the match to get.
- Returns:
Pointer to the match at
offset
inipt_entry
.
-
ipt_get_target(entry)#
Get
ipt_entry's
target.- Parameters:
entry –
ipt_entry
structure to get the target from.
- Returns:
Pointer to the target assigned to
ipt_entry
.
-
ipt_get_first_rule(replace, hook)#
Get first rule for
hook
inipt_replace
.- Parameters:
replace –
ipt_replace
structure.hook – Hook to get the first rule for.
- Returns:
Pointer to the first rule for
hook
.
-
ipt_get_next_rule(entry)#
Get rule following
ipt_entry
.- Parameters:
entry –
ipt_entry
structure.
- Returns:
Pointer to the next rule.
-
ipt_get_last_rule(replace, hook)#
Get last rule for
hook
inipt_replace
.- Parameters:
replace –
ipt_replace
structure.hook – Hook to get the last rule for.
- Returns:
Pointer to the last rule for
hook
.
-
ipt_is_hook_enabled(replace, hook)#
- file ipt.c
- #include “shared/ipt.h”#include <net/if.h>#include <linux/in.h>#include <linux/netfilter.h>#include <linux/netfilter_ipv4/ip_tables.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include “core/context.h”#include “core/counter.h”#include “core/flavor.h”#include “core/hook.h”#include “core/list.h”#include “core/logger.h”#include “core/marsh.h”#include “core/match.h”#include “core/rule.h”#include “core/verdict.h”#include “generator/codegen.h”#include “generator/program.h”#include “shared/front.h”#include “shared/helper.h”#include “shared/request.h”#include “shared/response.h”#include “xlate/front.h”#include “xlate/ipt/dump.h”#include “xlate/ipt/helpers.h”
Warning
Only LOCAL_IN and LOCAL_OUT chains are currently supported, until BPF_NETFILTER programs can be generated. To ensure only those rules are processed, we store the index and length of the chains statically.
Defines
-
_cleanup_bf_ipt_cache_#
Functions
-
static void _bf_ipt_cache_free(struct bf_ipt_cache **cache)#
-
static int _bf_ipt_setup(void)#
-
static int _bf_ipt_teardown(void)#
-
static int _bf_ipt_request_handler(struct bf_request *request, struct bf_response **response)#
- Todo:
Wouldn’t it be better to have a separate handler for each request type? In which case struct bf_front_ops would contain a handler for each request type, and the front would handle custom (BF_REQ_CUSTOM) requests itself.
Document that request and responses are not const: they will be free by the daemon once the front is done with them. Hence, the front is free to modify the requests content.
Check bf_assertions: a malformed request could cause the daemon to crash.
- Parameters:
request –
response –
- Returns:
-
static enum bf_hook _bf_ipt_hook_to_bf_hook(enum nf_inet_hooks ipt_hook)#
Convert an iptables hook to a bpfilter hook.
- Parameters:
ipt_hook – iptables hook. Must be valid.
- Returns:
bpfilter hook.
-
static int _bf_ipt_cache_new(struct bf_ipt_cache **cache)#
-
static int _bf_ipt_target_to_verdict(struct ipt_entry_target *ipt_target, enum bf_verdict *verdict)#
Convert an iptables target to a bpfilter verdict.
- Parameters:
ipt_target – iptables target to convert.
verdict – Verdict to store the conversion in.
- Returns:
0 on success, negative error code on failure.
-
static int _bf_ipt_to_match(const struct ipt_entry_match *ipt_match, struct bf_match **match)#
Translate an iptables match into a bpfilter match.
- Todo:
Convert actual match content.
- Parameters:
ipt_match – iptables match to translate.
match – Match to store the translation in.
- Returns:
0 on success, negative error code on failure.
-
static int _bf_ipt_to_rule(const struct ipt_entry *ipt_rule, struct bf_rule **rule)#
Translate an iptables rule into a bpfilter rule.
- Todo:
Bound check the target.
- Parameters:
ipt_rule – iptables rule to translate.
rule – Rule to store the translation in.
- Returns:
0 on success, negative error code on failure.
-
static bool _ipt_entry_is_empty(const struct ipt_entry *entry)#
-
static int _ipt_xlate_set_rules(struct ipt_replace *ipt, struct bf_codegen *(*codegens)[_BF_HOOK_MAX])#
Translate iptables rules into bpfilter format.
- Parameters:
ipt – iptables rules.
codegens – Array of codegens, indexed by hook. At most one codegen per hook will be generated.
- Returns:
0 on success, negative error code on failure.
-
static int _bf_ipt_set_rules_handler(struct ipt_replace *replace, size_t len)#
Modify existing iptables rules.
- Todo:
If processing for any codegen fails, all codegens should be unloaded and/or discarded.
- Parameters:
replace – New rules, in iptables format.
len – Length of the new rules.
- Returns:
0 on success, negative error code on failure.
-
static int _bf_ipt_set_counters_handler(struct xt_counters_info *counters, size_t len)#
Set counters for a rule.
- Todo:
Actually update the counters.
- Parameters:
counters – iptables structure containing the counters and their value.
len – Length of the counters structure.
- Returns:
0 on success, negative error code on failure.
-
int _bf_ipt_get_info_handler(struct bf_request *request, struct bf_response **response)#
-
int _bf_ipt_get_entries_handler(struct bf_request *request, struct bf_response **response)#
Get the entries of a table, including counters.
- Parameters:
request –
response –
- Returns:
0 on success, negative errno value on failure.
Variables
-
static struct bf_ipt_cache *_cache = NULL#
-
static unsigned char _default_ipt_filter[]#
Default iptables filter table. Required to initialize iptables.
-
const struct bf_front_ops ipt_front = {.setup = _bf_ipt_setup, .teardown = _bf_ipt_teardown, .request_handler = _bf_ipt_request_handler, .marsh = _bf_ipt_marsh, .unmarsh = _bf_ipt_unmarsh,}
-
_cleanup_bf_ipt_cache_#
- file nfgroup.c
- #include “xlate/nft/nfgroup.h”#include <linux/netfilter/nfnetlink.h>#include <linux/netlink.h>#include <errno.h>#include <limits.h>#include <netlink/msg.h>#include “core/list.h”#include “shared/response.h”#include “xlate/nft/nfmsg.h”
Functions
-
int bf_nfgroup_new(struct bf_nfgroup **group)
Create a new Netlink messages group.
- Parameters:
group – Pointer to the new messages group. Must not be NULL. Will be allocated and initialised by this function. Can’t be NULL.
- Returns:
0 on success, or negative errno value on error.
-
int bf_nfgroup_new_from_stream(struct bf_nfgroup **group, struct nlmsghdr *nlh, size_t length)
Create a new Netlink messages group from a stream of nlmsghdr.
- Parameters:
msg – Pointer to the new message. Must not be NULL. Will be allocated and initialised by this function.
nlh – Pointer to the first nlmsghdr in the stream. Must not be NULL.
length – Total length of the stream.
- Returns:
0 on success, or negative errno value on error.
-
void bf_nfgroup_free(struct bf_nfgroup **group)
Free a Netlink messages group.
- Parameters:
msg – Pointer to the messages group to free. If
msg
is NULL, nothing is done.
-
const bf_list *bf_nfgroup_messages(const struct bf_nfgroup *group)
Get the list of messages in the Netlink messages group.
-
size_t bf_nfgroup_size(const struct bf_nfgroup *group)
Get the total Netlink message size.
The total size of the Netlink message is the sum of the size of all the messages, including padding.
- Parameters:
group – Netlink messages group to get the size of. Can’t be NULL.
- Returns:
Total size of the Netlink messages group.
-
bool bf_nfgroup_is_empty(const struct bf_nfgroup *group)
Test if a Netlink message group is empty.
- Parameters:
group – Netlink message to check. Can’t be NULL.
- Returns:
True if the Netlink message is empty (no messages), false otherwise.
-
int bf_nfgroup_add_message(struct bf_nfgroup *group, struct bf_nfmsg *msg)
Add a Netlink message to the Netlink messages group.
- Parameters:
group – Netlink messages group to add the message to. Can’t be NULL.
group – Message to add to the messages group. Can’t be NULL. The Netlink messages group takes onwership of the message.
- Returns:
0 on success, or negative errno value on error.
-
int bf_nfgroup_add_new_message(struct bf_nfgroup *group, struct bf_nfmsg **msg, uint16_t command, uint16_t seqnr)
Create a new Netfilter Netlink message and add it to a Netlink messages group.
The new Netfilter Netlink message is owned by the messages group and should not be freed by the caller.
- Parameters:
group – Netlink messages group to add the message to. Can’t be NULL.
msg – Pointer to the new message. Once the function succeeds, this pointer will be set to the new message. Can be NULL, in which case the caller won’t have access to the new message.
command – Netlink message command.
seqnr – Netlink message sequence number.
- Returns:
0 on success, or negative errno value on error.
-
int bf_nfgroup_to_response(const struct bf_nfgroup *group, struct bf_response **resp)
Convert a Netlink messages group into a bf_response.
All the Netfilter Netlink messages contained in the group will written contiguously in the payload of a single
bf_response
.If only one message is present in the group, the response will contain only the message payload. If more than one message is present, the response will contain a multipart message, with the
NLM_F_MULTI
flag set on all the messages and a finalNLMSG_DONE
message.If the group is empty, the reponse will contain a single
NLMSG_DONE
message.- Parameters:
group – Netlink messages group to convert. Can’t be NULL.
resp – Pointer to the new response. Can’t be NULL. A new response will be allocated by this function and the caller will be responsible for freeing it.
- Returns:
0 on success, or negative errno value on error.
-
int bf_nfgroup_new(struct bf_nfgroup **group)
- file nfgroup.h
- #include <stdbool.h>#include <stddef.h>#include <stdint.h>#include “core/list.h”
Netlink allows data to be sent in multipart messages, which is a stream of multiple Netlink messages (each with its own header), flagged with
NLM_F_MULTI
and ending with a final message of typeNLMSG_DONE
bf_nfgroup is an abstraction to represent multipart messages. It contains a list of bf_nfmsg, each of which is a Netlink message.
The messages group can be converted into a single bf_response, which is a contiguous buffer containing all the messages in the group.
Defines
-
_cleanup_bf_nfgroup_
Cleanup function for bf_nfgroup.
Functions
-
int bf_nfgroup_new(struct bf_nfgroup **group)
Create a new Netlink messages group.
- Parameters:
group – Pointer to the new messages group. Must not be NULL. Will be allocated and initialised by this function. Can’t be NULL.
- Returns:
0 on success, or negative errno value on error.
-
int bf_nfgroup_new_from_stream(struct bf_nfgroup **group, struct nlmsghdr *nlh, size_t length)
Create a new Netlink messages group from a stream of nlmsghdr.
- Parameters:
msg – Pointer to the new message. Must not be NULL. Will be allocated and initialised by this function.
nlh – Pointer to the first nlmsghdr in the stream. Must not be NULL.
length – Total length of the stream.
- Returns:
0 on success, or negative errno value on error.
-
void bf_nfgroup_free(struct bf_nfgroup **group)
Free a Netlink messages group.
- Parameters:
msg – Pointer to the messages group to free. If
msg
is NULL, nothing is done.
-
const bf_list *bf_nfgroup_messages(const struct bf_nfgroup *group)
Get the list of messages in the Netlink messages group.
-
size_t bf_nfgroup_size(const struct bf_nfgroup *group)
Get the total Netlink message size.
The total size of the Netlink message is the sum of the size of all the messages, including padding.
- Parameters:
group – Netlink messages group to get the size of. Can’t be NULL.
- Returns:
Total size of the Netlink messages group.
-
bool bf_nfgroup_is_empty(const struct bf_nfgroup *group)
Test if a Netlink message group is empty.
- Parameters:
group – Netlink message to check. Can’t be NULL.
- Returns:
True if the Netlink message is empty (no messages), false otherwise.
-
int bf_nfgroup_add_message(struct bf_nfgroup *group, struct bf_nfmsg *msg)
Add a Netlink message to the Netlink messages group.
- Parameters:
group – Netlink messages group to add the message to. Can’t be NULL.
group – Message to add to the messages group. Can’t be NULL. The Netlink messages group takes onwership of the message.
- Returns:
0 on success, or negative errno value on error.
-
int bf_nfgroup_add_new_message(struct bf_nfgroup *group, struct bf_nfmsg **msg, uint16_t command, uint16_t seqnr)
Create a new Netfilter Netlink message and add it to a Netlink messages group.
The new Netfilter Netlink message is owned by the messages group and should not be freed by the caller.
- Parameters:
group – Netlink messages group to add the message to. Can’t be NULL.
msg – Pointer to the new message. Once the function succeeds, this pointer will be set to the new message. Can be NULL, in which case the caller won’t have access to the new message.
command – Netlink message command.
seqnr – Netlink message sequence number.
- Returns:
0 on success, or negative errno value on error.
-
int bf_nfgroup_to_response(const struct bf_nfgroup *group, struct bf_response **resp)
Convert a Netlink messages group into a bf_response.
All the Netfilter Netlink messages contained in the group will written contiguously in the payload of a single
bf_response
.If only one message is present in the group, the response will contain only the message payload. If more than one message is present, the response will contain a multipart message, with the
NLM_F_MULTI
flag set on all the messages and a finalNLMSG_DONE
message.If the group is empty, the reponse will contain a single
NLMSG_DONE
message.- Parameters:
group – Netlink messages group to convert. Can’t be NULL.
resp – Pointer to the new response. Can’t be NULL. A new response will be allocated by this function and the caller will be responsible for freeing it.
- Returns:
0 on success, or negative errno value on error.
-
_cleanup_bf_nfgroup_
- file nfmsg.c
- #include “xlate/nft/nfmsg.h”#include <linux/netfilter/nf_tables.h>#include <linux/netfilter/nfnetlink.h>#include <linux/netlink.h>#include <errno.h>#include <limits.h>#include <netlink/msg.h>#include “core/logger.h”#include “shared/helper.h”
Functions
-
int bf_nfmsg_new(struct bf_nfmsg **msg, uint8_t command, uint32_t seqnr)
Create a new Netfilter Netlink message.
- Parameters:
msg – The new message to allocate and initialise. Can’t be NULL.
command – Command to send, can be any of
nf_tables_msg_types
.seqnr – Sequence number for the message.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_nfmsg_new_done(struct bf_nfmsg **msg)
Create a new Netfilter Netlink
NLMSG_DONE
message.- Parameters:
msg – The new message to allocate and initialise. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_nfmsg_new_from_nlmsghdr(struct bf_nfmsg **msg, struct nlmsghdr *nlh)
Create a new Netfilter Netlink message from an existing Netlink message.
The provided
nlmsghdr
must be a valid Netlink message targeted to theNFNL_SUBSYS_NFTABLES
subsystem, and containing anfgenmsg
header.- Parameters:
msg – The new message to allocate and initialise. Can’t be NULL.
nlh – Netlink message to create the Netfilter Netlink message from. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
void bf_nfmsg_free(struct bf_nfmsg **msg)
Free a Netfilter Netlink message.
If
msg
is NULL, this function has no effect. Before returning,msg
is set to NULL.- Parameters:
msg – Message to free. Must be non-NULL.
-
struct nlmsghdr *bf_nfmsg_hdr(const struct bf_nfmsg *msg)
Get the Netlink message header for a Netfilter Netlink message.
- Parameters:
msg – Message to get the header from. Must be non-NULL.
- Returns:
The Netlink message header.
-
size_t bf_nfmsg_data_len(const struct bf_nfmsg *msg)
Get a Netfilter Netlink message’s payload size, including padding.
- Parameters:
msg – Message to get the payload size of. Can’t be NULL.
- Returns:
Message’s payload size, including padding.
-
size_t bf_nfmsg_len(const struct bf_nfmsg *msg)
Get a Netfilter Netlink message’s size, including header and padding.
- Parameters:
msg – Message to get the size of. Can’t be NULL.
- Returns:
Message’s size, including header and padding.
-
uint8_t bf_nfmsg_command(const struct bf_nfmsg *msg)
Get a Netfilter Netlink message’s command.
- Parameters:
msg – Message to get the command from. Can’t be NULL.
- Returns:
The message’s command.
-
uint32_t bf_nfmsg_seqnr(const struct bf_nfmsg *msg)
Get a Netfilter Netlink message’s sequence number.
- Parameters:
msg – Message to get the sequence number from. Can’t be NULL.
- Returns:
The message’s sequence number.
-
int bf_nfmsg_attr_push(struct bf_nfmsg *msg, uint16_t type, const void *data, size_t len)
Push a new attribute into a Netfilter Netlink message.
- Parameters:
msg – Message to push the attribute to. Can’t be NULL.
type – Attribute type.
data – Attribute data. Can’t be NULL.
len – Attribute data length.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_nfmsg_parse(const struct bf_nfmsg *msg, bf_nfattr **attrs, int maxtype, const bf_nfpolicy *policy)
Parse attributes from a Netfilter Netlink message.
All the attributes contained in the message are parsed and stored in the
attrs
array. Nested attributes (attributes contained within other) are not parsed, see bf_nfattr_parse instead.- Parameters:
msg – Message to parse the attributes from. Can’t be NULL.
attrs – Array of attributes to parse. Can’t be NULL.
maxtype – Maximum attribute type to parse.
policy – Netlink validation policy to use. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_nfattr_parse(bf_nfattr *attr, bf_nfattr **attrs, int maxtype, const bf_nfpolicy *policy)
Parse attributes nested within a Netlink attribute.
All the attributes contained in the
attr
are parsed and stored in theattrs
array.- Parameters:
attr – Attribute to parse the nested attributes from. Can’t be NULL.
attrs – Array of attributes to parse. Can’t be NULL.
maxtype – Maximum attribute type to parse.
policy – Netlink validation policy to use. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
void *bf_nfattr_data(bf_nfattr *attr)
Get the data of a Netlink attribute.
- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
size_t bf_nfattr_data_len(bf_nfattr *attr)
Get a Netlink attribute’s payload size, including padding.
- Parameters:
attr – Attribute the get the payload size of. Can’t be NULL.
- Returns:
Attribute’s payload size, including padding.
-
bool bf_nfattr_is_ok(bf_nfattr *attr, size_t remaining)
Check if a Netlink attribute (and its payload) is valid.
If the function returns false, the attribute and its content can’t be accessed safely.
- Parameters:
attr – Attribute to validate. Can’t be NULL.
remaining – Remaining bytes in the parent message or attribute. Can’t be negative.
- Returns:
true if the attribute is valid, false otherwise.
-
bf_nfattr *bf_nfattr_next(bf_nfattr *attr, size_t *remaining)
Get the next Netlink attribute in a message or in a nested attribute.
- Parameters:
attr – Attribute to get the next attribute from. Can’t be NULL.
remaining – Remaining bytes in the parent message or attribute. Can’t be NULL. When the function succeeds, it is updated with the remaining bytes in the parent message or attribute.
- Returns:
Pointer to the next attribute, or NULL if there are no more
-
int bf_nfmsg_nest_init(struct bf_nfnest *nest, struct bf_nfmsg *parent, uint16_t type)
Declares a new nested attribute within
parent
.Once a nested attribute has been defined, all the attributes added to the part (
parent
here) will be added within the nested attribute, until it is closed (bf_nfnest_cleanup).- Parameters:
nest – Pointer to the nested attribute. Must be an allocated bf_nfmsg_next structure. Can’t be NULL.
parent – bf_nfmsg containing the nested attribute.
type – Type of the nested attribute.
- Returns:
0 on success, negative errno value on error.
-
void bf_nfnest_cleanup(struct bf_nfnest *nest)
Close a nested attribute.
- Parameters:
nest – Nested attribute to close. Can’t be NULL.
Variables
- static const struct nla_policy _bf_nf_table_policy [__NFTA_TABLE_MAX] = {[NFTA_TABLE_NAME] = {.type = NLA_STRING},[NFTA_TABLE_FLAGS] = {.type = NLA_U32},[NFTA_TABLE_HANDLE] = {.type = NLA_U64},[NFTA_TABLE_USERDATA] = {.type = NLA_BINARY},}
-
const bf_nfpolicy *bf_nf_table_policy = _bf_nf_table_policy
Netlink validation policy for
nft_table_attributes
.
- static const struct nla_policy _bf_nf_chain_policy [__NFTA_CHAIN_MAX] = {[NFTA_CHAIN_TABLE] = {.type = NLA_STRING},[NFTA_CHAIN_HANDLE] = {.type = NLA_U64},[NFTA_CHAIN_NAME] = {.type = NLA_STRING},[NFTA_CHAIN_HOOK] = {.type = NLA_NESTED},[NFTA_CHAIN_POLICY] = {.type = NLA_U32},[NFTA_CHAIN_TYPE] = {.type = NLA_STRING},[NFTA_CHAIN_COUNTERS] = {.type = NLA_NESTED},[NFTA_CHAIN_FLAGS] = {.type = NLA_U32},[NFTA_CHAIN_ID] = {.type = NLA_U32},[NFTA_CHAIN_USERDATA] = {.type = NLA_BINARY},}
-
const bf_nfpolicy *bf_nf_chain_policy = _bf_nf_chain_policy
Netlink validation policy for
nft_chain_attributes
.
- static const struct nla_policy _bf_nf_hook_policy [__NFTA_HOOK_MAX] = {[NFTA_HOOK_HOOKNUM] = {.type = NLA_U32},[NFTA_HOOK_PRIORITY] = {.type = NLA_U32},[NFTA_HOOK_DEV] = {.type = NLA_STRING},}
-
const bf_nfpolicy *bf_nf_hook_policy = _bf_nf_hook_policy
Netlink validation policy for
nft_hook_attributes
.
- static const struct nla_policy _bf_nf_rule_policy [__NFTA_RULE_MAX] = {[NFTA_RULE_TABLE] = {.type = NLA_STRING},[NFTA_RULE_CHAIN] = {.type = NLA_STRING},[NFTA_RULE_HANDLE] = {.type = NLA_U64},[NFTA_RULE_EXPRESSIONS] = {.type = NLA_NESTED},[NFTA_RULE_COMPAT] = {.type = NLA_NESTED},[NFTA_RULE_POSITION] = {.type = NLA_U64},[NFTA_RULE_USERDATA] = {.type = NLA_BINARY},[NFTA_RULE_ID] = {.type = NLA_U32},[NFTA_RULE_POSITION_ID] = {.type = NLA_U32},[NFTA_RULE_CHAIN_ID] = {.type = NLA_U32},}
-
const bf_nfpolicy *bf_nf_rule_policy = _bf_nf_rule_policy
Netlink validation policy for
nft_rule_attributes
.
- static const struct nla_policy _bf_nf_expr_policy [__NFTA_EXPR_MAX] = {[NFTA_EXPR_NAME] = {.type = NLA_STRING},[NFTA_EXPR_DATA] = {.type = NLA_NESTED},}
-
const bf_nfpolicy *bf_nf_expr_policy = _bf_nf_expr_policy
Netlink validation policy for
nft_expr_attributes
.
- static const struct nla_policy _bf_nf_counter_policy [NFTA_COUNTER_MAX+1] = {[NFTA_COUNTER_PACKETS] = {.type = NLA_U64},[NFTA_COUNTER_BYTES] = {.type = NLA_U64},}
-
const bf_nfpolicy *bf_nf_counter_policy = _bf_nf_counter_policy
Netlink validation policy for
nft_counter_attributes
.
- static const struct nla_policy _bf_nf_payload_policy [__NFTA_PAYLOAD_MAX] = {[NFTA_PAYLOAD_SREG] = {.type = NLA_U32},[NFTA_PAYLOAD_DREG] = {.type = NLA_U32},[NFTA_PAYLOAD_BASE] = {.type = NLA_U32},[NFTA_PAYLOAD_OFFSET] = {.type = NLA_U32},[NFTA_PAYLOAD_LEN] = {.type = NLA_U32},[NFTA_PAYLOAD_CSUM_TYPE] = {.type = NLA_U32},[NFTA_PAYLOAD_CSUM_OFFSET] = {.type = NLA_U32},[NFTA_PAYLOAD_CSUM_FLAGS] = {.type = NLA_U32},}
-
const bf_nfpolicy *bf_nf_payload_policy = _bf_nf_payload_policy
Netlink validation policy for
nft_payload_attributes
.
- static const struct nla_policy _bf_nf_cmp_policy [__NFTA_CMP_MAX] = {[NFTA_CMP_SREG] = {.type = NLA_U32},[NFTA_CMP_OP] = {.type = NLA_U32},[NFTA_CMP_DATA] = {.type = NLA_NESTED},}
-
const bf_nfpolicy *bf_nf_cmp_policy = _bf_nf_cmp_policy
Netlink validation policy for
nft_cmp_attributes
.
- static const struct nla_policy _bf_nf_immediate_policy [__NFTA_IMMEDIATE_MAX] = {[NFTA_IMMEDIATE_DREG] = {.type = NLA_U32},[NFTA_IMMEDIATE_DATA] = {.type = NLA_NESTED},}
-
const bf_nfpolicy *bf_nf_immediate_policy = _bf_nf_immediate_policy
Netlink validation policy for
nft_immediate_attributes
.
- static const struct nla_policy _bf_nf_data_policy [__NFTA_DATA_MAX] = {[NFTA_DATA_VALUE] = {.type = NLA_BINARY},[NFTA_DATA_VERDICT] = {.type = NLA_NESTED},}
-
const bf_nfpolicy *bf_nf_data_policy = _bf_nf_data_policy
Netlink validation policy for
nft_data_attributes
.
- static const struct nla_policy _bf_nf_verdict_policy [__NFTA_VERDICT_MAX] = {[NFTA_VERDICT_CODE] = {.type = NLA_U32},[NFTA_VERDICT_CHAIN] = {.type = NLA_STRING},[NFTA_VERDICT_CHAIN_ID] = {.type = NLA_U32},}
-
const bf_nfpolicy *bf_nf_verdict_policy = _bf_nf_verdict_policy
Netlink validation policy for
nft_verdict_attributes
.
-
int bf_nfmsg_new(struct bf_nfmsg **msg, uint8_t command, uint32_t seqnr)
- file nfmsg.h
- #include <stdbool.h>#include <stddef.h>#include <stdint.h>
nftables
communicates with the kernel using Netlink messages. To reduce the work needed bynftables
to supportbpfilter
the same communication mechanism is used. Hence,bpfilter
will receive Netlink messages fromnftables
and will send Netlink messages tonftables
.This file provides a set of functions to create, parse, and manipulate Netlink messages. It also provides a set of Netlink validation policies for the different Netlink attributes used by
nftables
.All the functions defined in this file are dedicated to Netfilter Netlink messages and are not suitable for generic Netlink communication.
Messages#
bf_nfmsg is a structure used to represent Netlink messages. It is an opaque structure, so the user must go through the dedicated API to create, parse, and manipulate Netlink messages.
Netlink attributes can be pushed into the message using the generic function bf_nfmsg_attr_push. However, for common types, convenience macros are provided to push a string, a
uint8_t
, auint16_t
, auint32_t
, or auint64_t
attribute.Attributes#
bf_nfattr is a structure used to represent Netlink attributes. It is an opaque structure, so the user must go through the dedicated API to create, parse, and manipulate Netlink attributes.
Nested attributes#
bf_nfnest represent a virtual stack of nested attributes. It is used to create and close nested attributes within a Netlink message.
bf_nfmsg_nest_init declares a new nested attribute within a bf_nfmsg. Every attribute added to the message after calling this function will be pushed within the nested attribute. When complete, bf_nfnest_cleanup must be called to close the nested attribute.
The nested attribute is a stack, so it is possible to have nested attributes within nested attributes.
Defines
-
_cleanup_bf_nfmsg_
Cleanup attribute for a bf_nfmsg variable.
-
bf_nfmsg_attr_push_or_jmp(msg, type, data, size)
Convenience macro to push a new attribute into a Netfilter Netlink message, but jump to a label on failure.
If the attribute push fails, this macro jumps to the label
bf_nfmsg_push_failure
.- Parameters:
msg – Message to push the attribute to. Can’t be NULL.
type – Attribute type.
data – Attribute data. Can’t be NULL.
size – Attribute data length.
-
bf_nfmsg_push_str(msg, attr, data)
Convenience macro to push a new string attribute into a Netfilter Netlink message. See bf_nfmsg_attr_push for more details.
-
bf_nfmsg_push_str_or_jmp(part, attr, value)
Convenience macro to push a new string attribute into a Netfilter Netlink message, and jump to a label on failure. See bf_nfmsg_attr_push_or_jmp for more details.
-
bf_nfmsg_push_u8(msg, attr, data)
Convenience macro to push a new uint8_t attribute into a Netfilter Netlink message. See bf_nfmsg_attr_push for more details.
-
bf_nfmsg_push_u8_or_jmp(msg, attr, data)
Convenience macro to push a new uint8_t attribute into a Netfilter Netlink message, and jump to a label on failure. See bf_nfmsg_attr_push_or_jmp for more details.
-
bf_nfmsg_push_u16(msg, attr, data)
Convenience macro to push a new uint16_t attribute into a Netfilter Netlink message. See bf_nfmsg_attr_push for more details.
-
bf_nfmsg_push_u16_or_jmp(msg, attr, data)
Convenience macro to push a new uint16_t attribute into a Netfilter Netlink message, and jump to a label on failure. See bf_nfmsg_attr_push_or_jmp for more details.
-
bf_nfmsg_push_u32(msg, attr, data)
Convenience macro to push a new uint32_t attribute into a Netfilter Netlink message. See bf_nfmsg_attr_push for more details.
-
bf_nfmsg_push_u32_or_jmp(msg, attr, data)
Convenience macro to push a new uint32_t attribute into a Netfilter Netlink message, and jump to a label on failure. See bf_nfmsg_attr_push_or_jmp for more details.
-
bf_nfmsg_push_u64(msg, attr, data)
Convenience macro to push a new uint64_t attribute into a Netfilter Netlink message. See bf_nfmsg_attr_push for more details.
-
bf_nfmsg_push_u64_or_jmp(msg, attr, data)
Convenience macro to push a new uint64_t attribute into a Netfilter Netlink message, and jump to a label on failure. See bf_nfmsg_attr_push_or_jmp for more details.
-
bf_nfattr_get_str(attr)
Get a Netlink attribute’s data as a string.
- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
bf_nfattr_get_u8(attr)
Get a Netlink attribute’s data as a
uint8_t
.- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
bf_nfattr_get_s8(attr)
Get a Netlink attribute’s data as a
int8_t
.- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
bf_nfattr_get_u16(attr)
Get a Netlink attribute’s data as a
uint16_t
.- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
bf_nfattr_get_s16(attr)
Get a Netlink attribute’s data as a
int16_t
.- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
bf_nfattr_get_u32(attr)
Get a Netlink attribute’s data as a
uint32_t
.- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
bf_nfattr_get_s32(attr)
Get a Netlink attribute’s data as a
int32_t
.- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
bf_nfattr_get_u64(attr)
Get a Netlink attribute’s data as a
uint64_t
.- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
bf_nfattr_get_s64(attr)
Get a Netlink attribute’s data as a
int64_t
.- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
_cleanup_bf_nfnest_
Cleanup attribute for a bf_nfnest variable.
-
bf_nfnest_or_jmp(parent, type)
Convenience macro to create a new nested attribute context or jump to
bf_nfmsg_push_failure
on failure.- Parameters:
parent – bf_nfmsg to create the nested attribute into. Can’t be NULL.
type – Type of the nested attribute.
- Returns:
0 on success, or negative errno value on error.
Typedefs
-
typedef struct nlattr bf_nfattr
-
typedef struct nla_policy bf_nfpolicy
Functions
-
int bf_nfmsg_new(struct bf_nfmsg **msg, uint8_t command, uint32_t seqnr)
Create a new Netfilter Netlink message.
- Parameters:
msg – The new message to allocate and initialise. Can’t be NULL.
command – Command to send, can be any of
nf_tables_msg_types
.seqnr – Sequence number for the message.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_nfmsg_new_done(struct bf_nfmsg **msg)
Create a new Netfilter Netlink
NLMSG_DONE
message.- Parameters:
msg – The new message to allocate and initialise. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_nfmsg_new_from_nlmsghdr(struct bf_nfmsg **msg, struct nlmsghdr *nlh)
Create a new Netfilter Netlink message from an existing Netlink message.
The provided
nlmsghdr
must be a valid Netlink message targeted to theNFNL_SUBSYS_NFTABLES
subsystem, and containing anfgenmsg
header.- Parameters:
msg – The new message to allocate and initialise. Can’t be NULL.
nlh – Netlink message to create the Netfilter Netlink message from. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
void bf_nfmsg_free(struct bf_nfmsg **msg)
Free a Netfilter Netlink message.
If
msg
is NULL, this function has no effect. Before returning,msg
is set to NULL.- Parameters:
msg – Message to free. Must be non-NULL.
-
struct nlmsghdr *bf_nfmsg_hdr(const struct bf_nfmsg *msg)
Get the Netlink message header for a Netfilter Netlink message.
- Parameters:
msg – Message to get the header from. Must be non-NULL.
- Returns:
The Netlink message header.
-
size_t bf_nfmsg_len(const struct bf_nfmsg *msg)
Get a Netfilter Netlink message’s size, including header and padding.
- Parameters:
msg – Message to get the size of. Can’t be NULL.
- Returns:
Message’s size, including header and padding.
-
size_t bf_nfmsg_data_len(const struct bf_nfmsg *msg)
Get a Netfilter Netlink message’s payload size, including padding.
- Parameters:
msg – Message to get the payload size of. Can’t be NULL.
- Returns:
Message’s payload size, including padding.
-
uint8_t bf_nfmsg_command(const struct bf_nfmsg *msg)
Get a Netfilter Netlink message’s command.
- Parameters:
msg – Message to get the command from. Can’t be NULL.
- Returns:
The message’s command.
-
uint32_t bf_nfmsg_seqnr(const struct bf_nfmsg *msg)
Get a Netfilter Netlink message’s sequence number.
- Parameters:
msg – Message to get the sequence number from. Can’t be NULL.
- Returns:
The message’s sequence number.
-
int bf_nfmsg_attr_push(struct bf_nfmsg *msg, uint16_t type, const void *data, size_t len)
Push a new attribute into a Netfilter Netlink message.
- Parameters:
msg – Message to push the attribute to. Can’t be NULL.
type – Attribute type.
data – Attribute data. Can’t be NULL.
len – Attribute data length.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_nfmsg_parse(const struct bf_nfmsg *msg, bf_nfattr **attrs, int maxtype, const bf_nfpolicy *policy)
Parse attributes from a Netfilter Netlink message.
All the attributes contained in the message are parsed and stored in the
attrs
array. Nested attributes (attributes contained within other) are not parsed, see bf_nfattr_parse instead.- Parameters:
msg – Message to parse the attributes from. Can’t be NULL.
attrs – Array of attributes to parse. Can’t be NULL.
maxtype – Maximum attribute type to parse.
policy – Netlink validation policy to use. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
int bf_nfattr_parse(bf_nfattr *attr, bf_nfattr **attrs, int maxtype, const bf_nfpolicy *policy)
Parse attributes nested within a Netlink attribute.
All the attributes contained in the
attr
are parsed and stored in theattrs
array.- Parameters:
attr – Attribute to parse the nested attributes from. Can’t be NULL.
attrs – Array of attributes to parse. Can’t be NULL.
maxtype – Maximum attribute type to parse.
policy – Netlink validation policy to use. Can’t be NULL.
- Returns:
0 on success, or negative errno value on failure.
-
void *bf_nfattr_data(bf_nfattr *attr)
Get the data of a Netlink attribute.
- Parameters:
attr – Attribute to get the data from. Can’t be NULL.
- Returns:
Pointer to the attribute’s data.
-
size_t bf_nfattr_data_len(bf_nfattr *attr)
Get a Netlink attribute’s payload size, including padding.
- Parameters:
attr – Attribute the get the payload size of. Can’t be NULL.
- Returns:
Attribute’s payload size, including padding.
-
bool bf_nfattr_is_ok(bf_nfattr *attr, size_t remaining)
Check if a Netlink attribute (and its payload) is valid.
If the function returns false, the attribute and its content can’t be accessed safely.
- Parameters:
attr – Attribute to validate. Can’t be NULL.
remaining – Remaining bytes in the parent message or attribute. Can’t be negative.
- Returns:
true if the attribute is valid, false otherwise.
-
bf_nfattr *bf_nfattr_next(bf_nfattr *attr, size_t *remaining)
Get the next Netlink attribute in a message or in a nested attribute.
- Parameters:
attr – Attribute to get the next attribute from. Can’t be NULL.
remaining – Remaining bytes in the parent message or attribute. Can’t be NULL. When the function succeeds, it is updated with the remaining bytes in the parent message or attribute.
- Returns:
Pointer to the next attribute, or NULL if there are no more
-
int bf_nfmsg_nest_init(struct bf_nfnest *nest, struct bf_nfmsg *parent, uint16_t type)
Declares a new nested attribute within
parent
.Once a nested attribute has been defined, all the attributes added to the part (
parent
here) will be added within the nested attribute, until it is closed (bf_nfnest_cleanup).- Parameters:
nest – Pointer to the nested attribute. Must be an allocated bf_nfmsg_next structure. Can’t be NULL.
parent – bf_nfmsg containing the nested attribute.
type – Type of the nested attribute.
- Returns:
0 on success, negative errno value on error.
-
void bf_nfnest_cleanup(struct bf_nfnest *nest)
Close a nested attribute.
- Parameters:
nest – Nested attribute to close. Can’t be NULL.
Variables
-
const bf_nfpolicy *bf_nf_table_policy
Netlink validation policy for
nft_table_attributes
.
-
const bf_nfpolicy *bf_nf_chain_policy
Netlink validation policy for
nft_chain_attributes
.
-
const bf_nfpolicy *bf_nf_hook_policy
Netlink validation policy for
nft_hook_attributes
.
-
const bf_nfpolicy *bf_nf_rule_policy
Netlink validation policy for
nft_rule_attributes
.
-
const bf_nfpolicy *bf_nf_expr_policy
Netlink validation policy for
nft_expr_attributes
.
-
const bf_nfpolicy *bf_nf_counter_policy
Netlink validation policy for
nft_counter_attributes
.
-
const bf_nfpolicy *bf_nf_payload_policy
Netlink validation policy for
nft_payload_attributes
.
-
const bf_nfpolicy *bf_nf_cmp_policy
Netlink validation policy for
nft_cmp_attributes
.
-
const bf_nfpolicy *bf_nf_immediate_policy
Netlink validation policy for
nft_immediate_attributes
.
-
const bf_nfpolicy *bf_nf_data_policy
Netlink validation policy for
nft_data_attributes
.
-
const bf_nfpolicy *bf_nf_verdict_policy
Netlink validation policy for
nft_verdict_attributes
.
-
_cleanup_bf_nfmsg_
- file nft.c
- #include <arpa/inet.h>#include <linux/netfilter.h>#include <linux/netfilter/nf_tables.h>#include “core/context.h”#include “core/hook.h”#include “core/logger.h”#include “core/marsh.h”#include “core/rule.h”#include “core/verdict.h”#include “generator/codegen.h”#include “shared/request.h”#include “shared/response.h”#include “xlate/front.h”#include “xlate/nft/nfgroup.h”#include “xlate/nft/nfmsg.h”
Functions
-
static int _bf_nft_setup(void)#
-
static int _bf_nft_teardown(void)#
-
static int _bf_nft_request_handler(struct bf_request *request, struct bf_response **response)#
-
static int _bf_nft_getgen_cb(const struct bf_nfmsg *req, struct bf_nfgroup *res)#
-
static int _bf_nft_gettable_cb(const struct bf_nfmsg *req, struct bf_nfgroup *res)#
-
static int _bf_nft_getchain_cb(const struct bf_nfmsg *req, struct bf_nfgroup *res)#
-
static int _bf_nft_getrule_cb(const struct bf_nfmsg *req, struct bf_nfgroup *res)#
-
static int _bf_nft_request_handle(const struct bf_nfmsg *req, struct bf_nfgroup *res)#
Variables
-
static const char *_bf_table_name = "bpfilter"#
-
static const char *_bf_chain_name = "prerouting"#
-
const struct bf_front_ops nft_front = {.setup = _bf_nft_setup, .teardown = _bf_nft_teardown, .request_handler = _bf_nft_request_handler, .marsh = _bf_nft_marsh, .unmarsh = _bf_nft_unmarsh,}
-
static int _bf_nft_setup(void)#
- page todo
- Global _bf_init (int argc, char *argv[])
Should the runtime context be saved unconditionally?
- Global _bf_ipt_request_handler (struct bf_request *request, struct bf_response **response)
Wouldn’t it be better to have a separate handler for each request type? In which case struct bf_front_ops would contain a handler for each request type, and the front would handle custom (BF_REQ_CUSTOM) requests itself.
Document that request and responses are not const: they will be free by the daemon once the front is done with them. Hence, the front is free to modify the requests content.
Check bf_assertions: a malformed request could cause the daemon to crash.
- Global _bf_ipt_set_counters_handler (struct xt_counters_info *counters, size_t len)
Actually update the counters.
- Global _bf_ipt_set_rules_handler (struct ipt_replace *replace, size_t len)
If processing for any codegen fails, all codegens should be unloaded and/or discarded.
- Global _bf_ipt_to_match (const struct ipt_entry_match *ipt_match, struct bf_match **match)
Convert actual match content.
- Global _bf_ipt_to_rule (const struct ipt_entry *ipt_rule, struct bf_rule **rule)
Bound check the target.
- Global _bf_program_generate_add_counter (struct bf_program *program)
Random jump into the bytecode should be calculated by the daemon, not the developer.
Create a fixup to jump to the end of a function.
Set BF_REG_0 to !0 on failure, so we don’t drop the packet.
- Global _bf_program_generate_rule (struct bf_program *program, struct bf_rule *rule)
do matches too!
- Global _tc_attach_prog_pre_unload (struct bf_program *program, int *prog_fd, union bf_flavor_attach_attr *attr)
How should priority be handled?
This function, as well as many others, is using libbpf. Not all functions uses libbpf to communicate with the kernel. This should be unified.
- Global bf_front_ops::setup )(void)
Make bf_front_ops.request_handler take a const struct bf_request.
- dir core
- dir external
- dir generator
- dir xlate/ipt
- dir xlate/nft
- dir xlate