-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
libbpf/ebpf: Add pages for print helpers
This commit adds pages for the print helpers currntly available in the libbpf ebpf side library. Signed-off-by: Dylan Reimerink <[email protected]>
- Loading branch information
1 parent
f738cba
commit 985a8c5
Showing
5 changed files
with
249 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
--- | ||
title: "Libbpf eBPF macro 'bpf_printk'" | ||
description: "This page documents the 'bpf_printk' libbpf eBPF macro, including its definition, usage, and examples." | ||
--- | ||
# Libbpf eBPF macro `bpf_printk` | ||
|
||
[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) | ||
|
||
The `bpf_printk` macro is used to make printing to the kernel trace log easier. | ||
|
||
## Definition | ||
|
||
The short version (left out the implementation) | ||
```c | ||
/* Helper macro to print out debug messages */ | ||
#define bpf_printk(fmt, args...) ___bpf_pick_printk(args)(fmt, ##args) | ||
``` | ||
??? example "The full version" | ||
```c | ||
#ifdef BPF_NO_GLOBAL_DATA | ||
#define BPF_PRINTK_FMT_MOD | ||
#else | ||
#define BPF_PRINTK_FMT_MOD static const | ||
#endif | ||
#define __bpf_printk(fmt, ...) \ | ||
({ \ | ||
BPF_PRINTK_FMT_MOD char ____fmt[] = fmt; \ | ||
bpf_trace_printk(____fmt, sizeof(____fmt), \ | ||
##__VA_ARGS__); \ | ||
}) | ||
/* | ||
* __bpf_vprintk wraps the bpf_trace_vprintk helper with variadic arguments | ||
* instead of an array of u64. | ||
*/ | ||
#define __bpf_vprintk(fmt, args...) \ | ||
({ \ | ||
static const char ___fmt[] = fmt; \ | ||
unsigned long long ___param[___bpf_narg(args)]; \ | ||
\ | ||
_Pragma("GCC diagnostic push") \ | ||
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ | ||
___bpf_fill(___param, args); \ | ||
_Pragma("GCC diagnostic pop") \ | ||
\ | ||
bpf_trace_vprintk(___fmt, sizeof(___fmt), \ | ||
___param, sizeof(___param)); \ | ||
}) | ||
/* Use __bpf_printk when bpf_printk call has 3 or fewer fmt args | ||
* Otherwise use __bpf_vprintk | ||
*/ | ||
#define ___bpf_pick_printk(...) \ | ||
___bpf_nth(_, ##__VA_ARGS__, __bpf_vprintk, __bpf_vprintk, __bpf_vprintk, \ | ||
__bpf_vprintk, __bpf_vprintk, __bpf_vprintk, __bpf_vprintk, \ | ||
__bpf_vprintk, __bpf_vprintk, __bpf_printk /*3*/, __bpf_printk /*2*/,\ | ||
__bpf_printk /*1*/, __bpf_printk /*0*/) | ||
/* Helper macro to print out debug messages */ | ||
#define bpf_printk(fmt, args...) ___bpf_pick_printk(args)(fmt, ##args) | ||
``` | ||
## Usage | ||
This is a macro makes writing to the kernel trace log easier. It does two things, the first is it picks between the [`bpf_trace_printk`](../../../linux/helper-function/bpf_trace_printk.md) and [`bpf_trace_vprintk`](../../../linux/helper-function/bpf_trace_vprintk.md) helper functions. The [`bpf_trace_printk`](../../../linux/helper-function/bpf_trace_printk.md) helper only supports up to 3 arguments besides the format string, but [`bpf_trace_vprintk`](../../../linux/helper-function/bpf_trace_vprintk.md) supports any number of arguments (the macro supports up to 12 arguments). | ||
!!! note | ||
While the [`bpf_trace_printk`](../../../linux/helper-function/bpf_trace_printk.md) helper is supported on most kernels, the [`bpf_trace_vprintk`](../../../linux/helper-function/bpf_trace_vprintk.md) helper is only supported on kernel versions [:octicons-tag-24: v5.16](https://github.com/torvalds/linux/commit/10aceb629e198429c849d5e995c3bb1ba7a9aaa3) and later. | ||
So using this macro with more than 3 arguments on older kernels might cause the verifier to reject your program. | ||
The second thing it does is it turns the literal format string into a `char` array. If `BPF_NO_GLOBAL_DATA` is defined the char array will live on the stack, otherwise it will be turned into a global variable (this only works up to 4 arguments, the [`bpf_trace_vprintk`](../../../linux/helper-function/bpf_trace_vprintk.md) variant always make the format string into a global variable). Without this `char` array the compiler will place strings in a dedicated string ELF section unrecognized by loaders and not emit the proper global variable relocations. | ||
### Example | ||
```c | ||
SEC("tc") | ||
int example_prog(struct __sk_buff *ctx) | ||
{ | ||
// Will use bpf_trace_printk | ||
bpf_printk( | ||
"Got a packet from interface %d, src: %pi4, dst: %pi4\\n", | ||
ctx->ingress_ifindex, | ||
ctx->remote_ip4, | ||
ctx->local_ip4, | ||
); | ||
// Will use bpf_trace_vprintk | ||
bpf_printk( | ||
"Got a packet from interface %d, src: %pi4, dst: %pi4, src port: %d, dst port: %d\\n", | ||
ctx->ingress_ifindex, | ||
ctx->remote_ip4, | ||
ctx->local_ip4, | ||
ctx->remote_port, | ||
ctx->local_port, | ||
); | ||
return TC_ACT_OK; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
--- | ||
title: "Libbpf eBPF macro 'BPF_SEQ_PRINTF'" | ||
description: "This page documents the 'BPF_SEQ_PRINTF' libbpf eBPF macro, including its definition, usage, and examples." | ||
--- | ||
# Libbpf eBPF macro `BPF_SEQ_PRINTF` | ||
|
||
[:octicons-tag-24: v0.0.9](https://github.com/libbpf/libbpf/releases/tag/v0.0.9) | ||
|
||
!!! note | ||
This macro was moved from `bpf_tracing.h` to `bpf_helpers.h` in [:octicons-tag-24: v0.5.0](https://github.com/libbpf/libbpf/releases/tag/v0.5.0) | ||
|
||
The `BPF_SEQ_PRINTF` macro is used to make printing to bpf iterator sequence files easier. | ||
|
||
## Definition | ||
|
||
```c | ||
/* | ||
* BPF_SEQ_PRINTF to wrap bpf_seq_printf to-be-printed values | ||
* in a structure. | ||
*/ | ||
#define BPF_SEQ_PRINTF(seq, fmt, args...) \ | ||
({ \ | ||
static const char ___fmt[] = fmt; \ | ||
unsigned long long ___param[___bpf_narg(args)]; \ | ||
\ | ||
_Pragma("GCC diagnostic push") \ | ||
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ | ||
___bpf_fill(___param, args); \ | ||
_Pragma("GCC diagnostic pop") \ | ||
\ | ||
bpf_seq_printf(seq, ___fmt, sizeof(___fmt), \ | ||
___param, sizeof(___param)); \ | ||
}) | ||
``` | ||
|
||
## Usage | ||
|
||
This macro is a wrapper around the [`bpf_seq_printf`](../../../linux/helper-function/bpf_seq_printf.md) helper. It places the literal format string in a global variable, this is necessary to get the compiler to emit code that will be accepted by the verifier. | ||
|
||
### Example | ||
```c hl_lines="14 25 26" | ||
SEC("iter/task_file") | ||
int dump_task_file(struct bpf_iter__task_file *ctx) | ||
{ | ||
struct seq_file *seq = ctx->meta->seq; | ||
struct task_struct *task = ctx->task; | ||
struct file *file = ctx->file; | ||
__u32 fd = ctx->fd; | ||
|
||
if (task == NULL || file == NULL) | ||
return 0; | ||
|
||
if (ctx->meta->seq_num == 0) { | ||
count = 0; | ||
BPF_SEQ_PRINTF(seq, " tgid gid fd file\n"); | ||
} | ||
|
||
if (tgid == task->tgid && task->tgid != task->pid) | ||
count++; | ||
|
||
if (last_tgid != task->tgid) { | ||
last_tgid = task->tgid; | ||
unique_tgid_count++; | ||
} | ||
|
||
BPF_SEQ_PRINTF(seq, "%8d %8d %8d %lx\n", task->tgid, task->pid, fd, | ||
(long)file->f_op); | ||
return 0; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
--- | ||
title: "Libbpf eBPF macro 'BPF_SNPRINTF'" | ||
description: "This page documents the 'BPF_SNPRINTF' libbpf eBPF macro, including its definition, usage, and examples." | ||
--- | ||
# Libbpf eBPF macro `BPF_SNPRINTF` | ||
|
||
[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) | ||
|
||
!!! note | ||
This macro was moved from `bpf_tracing.h` to `bpf_helpers.h` in [:octicons-tag-24: v0.5.0](https://github.com/libbpf/libbpf/releases/tag/v0.5.0) | ||
|
||
The `BPF_SNPRINTF` macro is used to make in-BPF string formatting easier. | ||
|
||
## Definition | ||
|
||
```c | ||
/* | ||
* BPF_SNPRINTF wraps the bpf_snprintf helper with variadic arguments instead of | ||
* an array of u64. | ||
*/ | ||
#define BPF_SNPRINTF(out, out_size, fmt, args...) \ | ||
({ \ | ||
static const char ___fmt[] = fmt; \ | ||
unsigned long long ___param[___bpf_narg(args)]; \ | ||
\ | ||
_Pragma("GCC diagnostic push") \ | ||
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ | ||
___bpf_fill(___param, args); \ | ||
_Pragma("GCC diagnostic pop") \ | ||
\ | ||
bpf_snprintf(out, out_size, ___fmt, \ | ||
___param, sizeof(___param)); \ | ||
}) | ||
``` | ||
|
||
## Usage | ||
|
||
This macro is a wrapper around the [`bpf_snprintf`](../../../linux/helper-function/bpf_snprintf.md) helper. It places the literal format string in a global variable, this is necessary to get the compiler to emit code that will be accepted by the verifier. | ||
|
||
### Example | ||
```c hl_lines="17" | ||
struct { | ||
__uint(type, BPF_MAP_TYPE_RINGBUF); | ||
__uint(max_entries, 4096); | ||
} ringbuf SEC(".maps"); | ||
|
||
SEC("tc") | ||
int example_prog(struct __sk_buff *ctx) | ||
{ | ||
const int size = 100; | ||
char *str_out = bpf_ringbuf_reserve(&ringbuf, size, 0); | ||
if (!str_out) | ||
return TC_ACT_OK; | ||
|
||
// `len` is the length of the formatted string including NULL-termination char. | ||
// if `len` > `size` then the string was truncated. | ||
// `len` can also be -EBUSY if the per-CPU memory copy buffer is busy. | ||
long len = BPF_SNPRINTF(str_out, size, | ||
"Got a packet from interface %d, src: %pi4, dst: %pi4, src port: %d, dst port: %d\\n", | ||
ctx->ingress_ifindex, | ||
ctx->remote_ip4, | ||
ctx->local_ip4, | ||
ctx->remote_port, | ||
ctx->local_port | ||
); | ||
|
||
bpf_ringbuf_submit(str_out, 0); | ||
|
||
return TC_ACT_OK; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters