Programs generation#
Error handling#
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 to bf_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
Functions
-
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#
Printing debug messages#
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 in bpfilter
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 when bpfilter
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 with bpfilter
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
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.