-
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.
ebpf-library: Add pages CO-RE macros
This commit adds pages the CO-RE macros defined in libbpf's `bpf_core_read.h` file. Signed-off-by: Dylan Reimerink <[email protected]>
- Loading branch information
1 parent
0d21c24
commit d34bec5
Showing
34 changed files
with
1,439 additions
and
33 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,93 @@ | ||
--- | ||
title: "Libbpf eBPF macro 'BPF_CORE_READ'" | ||
description: "This page documents the 'BPF_CORE_READ' libbpf eBPF macro, including its definition, usage, and examples." | ||
--- | ||
# Libbpf eBPF macro `BPF_CORE_READ` | ||
|
||
[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) | ||
|
||
The `BPF_CORE_READ` macro is used to simplify BPF CO-RE relocatable read, especially when there are few pointer chasing steps. | ||
|
||
## Definition | ||
|
||
```c | ||
#define BPF_CORE_READ(src, a, ...) ({ \ | ||
___type((src), a, ##__VA_ARGS__) __r; \ | ||
BPF_CORE_READ_INTO(&__r, (src), a, ##__VA_ARGS__); \ | ||
__r; \ | ||
}) | ||
``` | ||
## Usage | ||
`BPF_CORE_READ` is used to simplify BPF CO-RE relocatable read, especially when there are few pointer chasing steps. E.g., what in non-BPF world (or in BPF w/ BCC) would be something like: | ||
`#!c int x = s->a.b.c->d.e->f->g;` | ||
can be succinctly achieved using `BPF_CORE_READ` as: | ||
`#!c int x = BPF_CORE_READ(s, a.b.c, d.e, f, g);` | ||
`BPF_CORE_READ` will decompose above statement into 4 [`bpf_core_read`](bpf_core_read.md) (BPF CO-RE relocatable [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) wrapper) calls, logically equivalent to: | ||
1. `const void *__t = s->a.b.c;` | ||
2. `__t = __t->d.e;` | ||
3. `__t = __t->f;` | ||
4. `return __t->g;` | ||
Equivalence is logical, because there is a heavy type casting/preservation involved, as well as all the reads are happening through [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) calls using `__builtin_preserve_access_index`() to emit CO-RE relocations. | ||
!!! note | ||
Only up to 9 "field accessors" are supported, which should be more than enough for any practical purpose. | ||
### Example | ||
```c hl_lines="32 33" | ||
/* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of version 2 of the GNU General Public | ||
* License as published by the Free Software Foundation. | ||
*/ | ||
#include "vmlinux.h" | ||
#include "net_shared.h" | ||
#include <linux/version.h> | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include <bpf/bpf_tracing.h> | ||
/* kprobe is NOT a stable ABI | ||
* kernel functions can be removed, renamed or completely change semantics. | ||
* Number of arguments and their positions can change, etc. | ||
* In such case this bpf+kprobe example will no longer be meaningful | ||
*/ | ||
SEC("kprobe.multi/__netif_receive_skb_core*") | ||
int bpf_prog1(struct pt_regs *ctx) | ||
{ | ||
/* attaches to kprobe __netif_receive_skb_core, | ||
* looks for packets on loobpack device and prints them | ||
* (wildcard is used for avoiding symbol mismatch due to optimization) | ||
*/ | ||
char devname[IFNAMSIZ]; | ||
struct net_device *dev; | ||
struct sk_buff *skb; | ||
int len; | ||
bpf_core_read(&skb, sizeof(skb), (void *)PT_REGS_PARM1(ctx)); | ||
dev = BPF_CORE_READ(skb, dev); | ||
len = BPF_CORE_READ(skb, len); | ||
BPF_CORE_READ_STR_INTO(&devname, dev, name); | ||
if (devname[0] == 'l' && devname[1] == 'o') { | ||
char fmt[] = "skb %p len %d\n"; | ||
/* using bpf_trace_printk() for DEBUG ONLY */ | ||
bpf_trace_printk(fmt, sizeof(fmt), skb, len); | ||
} | ||
return 0; | ||
} | ||
char _license[] SEC("license") = "GPL"; | ||
u32 _version SEC("version") = LINUX_VERSION_CODE; | ||
``` |
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,74 @@ | ||
--- | ||
title: "Libbpf eBPF macro 'BPF_CORE_READ_BITFIELD'" | ||
description: "This page documents the 'BPF_CORE_READ_BITFIELD' libbpf eBPF macro, including its definition, usage, and examples." | ||
--- | ||
# Libbpf eBPF macro `BPF_CORE_READ_BITFIELD` | ||
|
||
[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) | ||
|
||
The `BPF_CORE_READ_BITFIELD` macro extracts a bitfield from a given structure in a CO-RE relocatable way. | ||
|
||
## Definition | ||
|
||
```c | ||
#define BPF_CORE_READ_BITFIELD(s, field) ({ \ | ||
const void *p = (const void *)s + __CORE_RELO(s, field, BYTE_OFFSET); \ | ||
unsigned long long val; \ | ||
\ | ||
/* This is a so-called barrier_var() operation that makes specified \ | ||
* variable "a black box" for optimizing compiler. \ | ||
* It forces compiler to perform BYTE_OFFSET relocation on p and use \ | ||
* its calculated value in the switch below, instead of applying \ | ||
* the same relocation 4 times for each individual memory load. \ | ||
*/ \ | ||
asm volatile("" : "=r"(p) : "0"(p)); \ | ||
\ | ||
switch (__CORE_RELO(s, field, BYTE_SIZE)) { \ | ||
case 1: val = *(const unsigned char *)p; break; \ | ||
case 2: val = *(const unsigned short *)p; break; \ | ||
case 4: val = *(const unsigned int *)p; break; \ | ||
case 8: val = *(const unsigned long long *)p; break; \ | ||
default: val = 0; break; \ | ||
} \ | ||
val <<= __CORE_RELO(s, field, LSHIFT_U64); \ | ||
if (__CORE_RELO(s, field, SIGNED)) \ | ||
val = ((long long)val) >> __CORE_RELO(s, field, RSHIFT_U64); \ | ||
else \ | ||
val = val >> __CORE_RELO(s, field, RSHIFT_U64); \ | ||
val; \ | ||
}) | ||
``` | ||
## Usage | ||
`BPF_CORE_READ_BITFIELD` extract bitfield, identified by `s->field`, and return its value as u64. This is a variant of the [`BPF_CORE_READ_BITFIELD_PROBED`](BPF_CORE_READ_BITFIELD_PROBED.md) macro. This macro is using direct memory reads and should be used from BPF program types that support such functionality (e.g., typed [raw tracepoints](../../../linux/program-type/BPF_PROG_TYPE_TRACING.md#raw-tracepoint)). | ||
### Example | ||
```c | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2019 Facebook */ | ||
struct tcp_sock { | ||
u32 snd_cwnd; /* Sending congestion window */ | ||
/* [...] */ | ||
u8 chrono_type : 2, /* current chronograph type */ | ||
repair : 1, | ||
tcp_usec_ts : 1, /* TSval values in usec */ | ||
is_sack_reneg:1, /* in recovery from loss with SACK reneg? */ | ||
is_cwnd_limited:1;/* forward progress limited by snd_cwnd? */ | ||
/* [...] */ | ||
u32 max_packets_out; /* max packets_out in last window */ | ||
} | ||
static inline bool tcp_is_cwnd_limited(const struct sock *sk) | ||
{ | ||
const struct tcp_sock *tp = tcp_sk(sk); | ||
/* If in slow start, ensure cwnd grows to twice what was ACKed. */ | ||
if (tcp_in_slow_start(tp)) | ||
return tp->snd_cwnd < 2 * tp->max_packets_out; | ||
return !!BPF_CORE_READ_BITFIELD(tp, is_cwnd_limited); | ||
} | ||
``` |
34 changes: 34 additions & 0 deletions
34
docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_BITFIELD_PROBED.md
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,34 @@ | ||
--- | ||
title: "Libbpf eBPF macro 'BPF_CORE_READ_BITFIELD_PROBED'" | ||
description: "This page documents the 'BPF_CORE_READ_BITFIELD_PROBED' libbpf eBPF macro, including its definition, usage, and examples." | ||
--- | ||
# Libbpf eBPF macro `BPF_CORE_READ_BITFIELD_PROBED` | ||
|
||
[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) | ||
|
||
The `BPF_CORE_READ_BITFIELD_PROBED` macro extracts a bitfield from a given structure in a CO-RE relocatable way. | ||
|
||
## Definition | ||
|
||
```c | ||
#define BPF_CORE_READ_BITFIELD_PROBED(s, field) ({ \ | ||
unsigned long long val = 0; \ | ||
\ | ||
__CORE_BITFIELD_PROBE_READ(&val, s, field); \ | ||
val <<= __CORE_RELO(s, field, LSHIFT_U64); \ | ||
if (__CORE_RELO(s, field, SIGNED)) \ | ||
val = ((long long)val) >> __CORE_RELO(s, field, RSHIFT_U64); \ | ||
else \ | ||
val = val >> __CORE_RELO(s, field, RSHIFT_U64); \ | ||
val; \ | ||
}) | ||
``` | ||
## Usage | ||
`BPF_CORE_READ_BITFIELD` extract bitfield, identified by `s->field`, and return its value as u64. All this is done in relocatable manner, so bitfield changes such as signedness, bit size, offset changes, this will be handled automatically. This version of macro is using [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) to read underlying integer storage. Macro functions as an expression and its return type is [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) return value: 0, on success, <0 on error. | ||
### Example | ||
!!! example "Docs could be improved" | ||
This part of the docs is incomplete, contributions are very welcome |
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,40 @@ | ||
--- | ||
title: "Libbpf eBPF macro 'BPF_CORE_READ_INTO'" | ||
description: "This page documents the 'BPF_CORE_READ_INTO' libbpf eBPF macro, including its definition, usage, and examples." | ||
--- | ||
# Libbpf eBPF macro `BPF_CORE_READ_INTO` | ||
|
||
[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) | ||
|
||
The `BPF_CORE_READ_INTO` macro is a more performance-conscious variant of [`BPF_CORE_READ`](BPF_CORE_READ.md), in which final field is read into user-provided storage. | ||
|
||
## Definition | ||
|
||
```c | ||
#define BPF_CORE_READ_INTO(dst, src, a, ...) ({ \ | ||
___core_read(bpf_core_read, bpf_core_read, \ | ||
dst, (src), a, ##__VA_ARGS__) \ | ||
}) | ||
``` | ||
## Usage | ||
`BPF_CORE_READ_INTO` is very similar to [`BPF_CORE_READ`](BPF_CORE_READ.md), but instead of returning the value, it writes the value into the provided destination. | ||
The following two code snippets are equivalent: | ||
```c | ||
int x = BPF_CORE_READ(s, a.b.c, d.e, f, g); | ||
``` | ||
|
||
```c | ||
int x; | ||
BPF_CORE_READ_INTO(&x, s, a.b.c, d.e, f, g); | ||
``` | ||
Please refer to the [`BPF_CORE_READ`](BPF_CORE_READ.md) documentation for more details on usage of it and its variants like this macros. | ||
### Example | ||
!!! example "Docs could be improved" | ||
This part of the docs is incomplete, contributions are very welcome |
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,29 @@ | ||
--- | ||
title: "Libbpf eBPF macro 'BPF_CORE_READ_STR_INTO'" | ||
description: "This page documents the 'BPF_CORE_READ_STR_INTO' libbpf eBPF macro, including its definition, usage, and examples." | ||
--- | ||
# Libbpf eBPF macro `BPF_CORE_READ_STR_INTO` | ||
|
||
[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) | ||
|
||
The `BPF_CORE_READ_STR_INTO` macro is a variant of the [`BPF_CORE_READ_INTO`](BPF_CORE_READ_INTO.md) macro, which is used to do a BPF CO-RE relocatable string read into user-provided storage. | ||
|
||
## Definition | ||
|
||
```c | ||
#define BPF_CORE_READ_STR_INTO(dst, src, a, ...) ({ \ | ||
___core_read(bpf_core_read_str, bpf_core_read, \ | ||
dst, (src), a, ##__VA_ARGS__) \ | ||
}) | ||
``` | ||
## Usage | ||
`BPF_CORE_READ_STR_INTO` is very similar to [`BPF_CORE_READ_INTO`](BPF_CORE_READ_INTO.md), but it uses the [`bpf_probe_read_kernel_str`](../../../linux/helper-function/bpf_probe_read_kernel_str.md) helper function instead of the [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) helper function. This makes it better suites for reading NUL-terminated strings from kernel memory. | ||
Please refer to the [`BPF_CORE_READ`](BPF_CORE_READ.md) documentation for more details on usage of it and its variants like this macros. | ||
### Example | ||
!!! example "Docs could be improved" | ||
This part of the docs is incomplete, contributions are very welcome |
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,32 @@ | ||
--- | ||
title: "Libbpf eBPF macro 'BPF_CORE_READ_USER'" | ||
description: "This page documents the 'BPF_CORE_READ_USER' libbpf eBPF macro, including its definition, usage, and examples." | ||
--- | ||
# Libbpf eBPF macro `BPF_CORE_READ_USER` | ||
|
||
[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) | ||
|
||
The `BPF_CORE_READ_USER` macro is the userspace variant of the [`BPF_CORE_READ`](BPF_CORE_READ.md) macro. | ||
|
||
## Definition | ||
|
||
```c | ||
#define BPF_CORE_READ_USER(src, a, ...) ({ \ | ||
___type((src), a, ##__VA_ARGS__) __r; \ | ||
BPF_CORE_READ_USER_INTO(&__r, (src), a, ##__VA_ARGS__); \ | ||
__r; \ | ||
}) | ||
``` | ||
## Usage | ||
The `BPF_CORE_READ_USER` macro is the userspace variant of the [`BPF_CORE_READ`](BPF_CORE_READ.md) macro. The difference being that the [`bpf_probe_read_user`](../../../linux/helper-function/bpf_probe_read_user.md) helper function is used instead of the [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) helper function. This makes it able to read from userspace memory. | ||
All the source types involved are still *kernel types* and need to exist in kernel (or kernel module) BTF, otherwise CO-RE relocation will fail. Custom user types are not relocatable with CO-RE. The typical situation in which `BPF_CORE_READ_USER` might be used is to read kernel UAPI types from the user-space memory passed in as a syscall input argument. | ||
Please refer to the [`BPF_CORE_READ`](BPF_CORE_READ.md) documentation for more details on usage of it and its variants like this macros. | ||
### Example | ||
!!! example "Docs could be improved" | ||
This part of the docs is incomplete, contributions are very welcome |
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,40 @@ | ||
--- | ||
title: "Libbpf eBPF macro 'BPF_CORE_READ_USER_INTO'" | ||
description: "This page documents the 'BPF_CORE_READ_USER_INTO' libbpf eBPF macro, including its definition, usage, and examples." | ||
--- | ||
# Libbpf eBPF macro `BPF_CORE_READ_USER_INTO` | ||
|
||
[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) | ||
|
||
The `BPF_CORE_READ_USER_INTO` macro is a more performance-conscious variant of [`BPF_CORE_READ_USER`](BPF_CORE_READ.md), in which final field is read into user-provided storage. | ||
|
||
## Definition | ||
|
||
```c | ||
#define BPF_CORE_READ_USER_INTO(dst, src, a, ...) ({ \ | ||
___core_read(bpf_core_read_user, bpf_core_read_user, \ | ||
dst, (src), a, ##__VA_ARGS__) \ | ||
}) | ||
``` | ||
## Usage | ||
`BPF_CORE_READ_USER_INTO` is very similar to [`BPF_CORE_READ_USER`](BPF_CORE_READ_USER.md), but instead of returning the value, it writes the value into the provided destination. | ||
The following two code snippets are equivalent: | ||
```c | ||
int x = BPF_CORE_READ_USER(s, a.b.c, d.e, f, g); | ||
``` | ||
|
||
```c | ||
int x; | ||
BPF_CORE_READ_USER_INTO(&x, s, a.b.c, d.e, f, g); | ||
``` | ||
Please refer to the [`BPF_CORE_READ_USER`](BPF_CORE_READ_USER.md) documentation for more details on usage of it and its variants like this macros. | ||
### Example | ||
!!! example "Docs could be improved" | ||
This part of the docs is incomplete, contributions are very welcome |
Oops, something went wrong.