From d34bec595cdc1ea4f06008ef4d8f1c90acaf09e0 Mon Sep 17 00:00:00 2001 From: Dylan Reimerink Date: Mon, 16 Dec 2024 23:10:26 +0100 Subject: [PATCH] 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 --- .aspell.en.pws | 7 ++ .../ebpf-library/libbpf/ebpf/BPF_CORE_READ.md | 93 +++++++++++++++++++ .../libbpf/ebpf/BPF_CORE_READ_BITFIELD.md | 74 +++++++++++++++ .../ebpf/BPF_CORE_READ_BITFIELD_PROBED.md | 34 +++++++ .../libbpf/ebpf/BPF_CORE_READ_INTO.md | 40 ++++++++ .../libbpf/ebpf/BPF_CORE_READ_STR_INTO.md | 29 ++++++ .../libbpf/ebpf/BPF_CORE_READ_USER.md | 32 +++++++ .../libbpf/ebpf/BPF_CORE_READ_USER_INTO.md | 40 ++++++++ .../ebpf/BPF_CORE_READ_USER_STR_INTO.md | 29 ++++++ .../libbpf/ebpf/BPF_CORE_WRITE_BITFIELD.md | 50 ++++++++++ .../libbpf/ebpf/BPF_PROBE_READ.md | 31 +++++++ .../libbpf/ebpf/BPF_PROBE_READ_INTO.md | 42 +++++++++ .../libbpf/ebpf/BPF_PROBE_READ_STR_INTO.md | 31 +++++++ .../libbpf/ebpf/BPF_PROBE_READ_USER.md | 32 +++++++ .../libbpf/ebpf/BPF_PROBE_READ_USER_INTO.md | 42 +++++++++ .../ebpf/BPF_PROBE_READ_USER_STR_INTO.md | 31 +++++++ docs/ebpf-library/libbpf/ebpf/SUMMARY.md | 33 +++++++ .../ebpf-library/libbpf/ebpf/bpf_core_cast.md | 67 +++++++++++++ .../libbpf/ebpf/bpf_core_enum_value.md | 37 ++++++++ .../libbpf/ebpf/bpf_core_enum_value_exists.md | 37 ++++++++ .../libbpf/ebpf/bpf_core_field_exists.md | 62 +++++++++++++ .../libbpf/ebpf/bpf_core_field_offset.md | 48 ++++++++++ .../libbpf/ebpf/bpf_core_field_size.md | 50 ++++++++++ .../ebpf-library/libbpf/ebpf/bpf_core_read.md | 71 ++++++++++++++ .../libbpf/ebpf/bpf_core_read_str.md | 27 ++++++ .../libbpf/ebpf/bpf_core_read_user.md | 27 ++++++ .../libbpf/ebpf/bpf_core_read_user_str.md | 27 ++++++ .../libbpf/ebpf/bpf_core_type_exists.md | 57 ++++++++++++ .../libbpf/ebpf/bpf_core_type_id_kernel.md | 34 +++++++ .../libbpf/ebpf/bpf_core_type_id_local.md | 29 ++++++ .../libbpf/ebpf/bpf_core_type_matches.md | 87 +++++++++++++++++ .../libbpf/ebpf/bpf_core_type_size.md | 32 +++++++ docs/ebpf-library/libbpf/ebpf/index.md | 64 ++++++------- docs/linux/kfuncs/bpf_rdonly_cast.md | 46 ++++++++- 34 files changed, 1439 insertions(+), 33 deletions(-) create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_BITFIELD.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_BITFIELD_PROBED.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_INTO.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_STR_INTO.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER_INTO.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER_STR_INTO.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_CORE_WRITE_BITFIELD.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_INTO.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_STR_INTO.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER_INTO.md create mode 100644 docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER_STR_INTO.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_cast.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_enum_value.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_enum_value_exists.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_field_exists.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_field_offset.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_field_size.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_read.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_read_str.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_read_user.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_read_user_str.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_type_exists.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_type_id_kernel.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_type_id_local.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_type_matches.md create mode 100644 docs/ebpf-library/libbpf/ebpf/bpf_core_type_size.md diff --git a/.aspell.en.pws b/.aspell.en.pws index 67e9228a..29d11cb0 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -122,10 +122,16 @@ NUMA IMM GPL MPL +accessor +accessors centric +enum +enums relocation relocations signable +signedness +typedefs accumulatively untrusted inlined @@ -145,6 +151,7 @@ deduplication dereference dereferenced dereferencing +dereferences incrementing misprediction sleepable diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ.md b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ.md new file mode 100644 index 00000000..9578d3ca --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ.md @@ -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 +#include +#include +#include + +/* 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; +``` diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_BITFIELD.md b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_BITFIELD.md new file mode 100644 index 00000000..f2b99be8 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_BITFIELD.md @@ -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); +} +``` diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_BITFIELD_PROBED.md b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_BITFIELD_PROBED.md new file mode 100644 index 00000000..90d30b84 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_BITFIELD_PROBED.md @@ -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 diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_INTO.md b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_INTO.md new file mode 100644 index 00000000..1fd7a730 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_INTO.md @@ -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 diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_STR_INTO.md b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_STR_INTO.md new file mode 100644 index 00000000..c862ecbf --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_STR_INTO.md @@ -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 diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER.md b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER.md new file mode 100644 index 00000000..3d7ab8e4 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER.md @@ -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 diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER_INTO.md b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER_INTO.md new file mode 100644 index 00000000..c272a436 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER_INTO.md @@ -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 diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER_STR_INTO.md b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER_STR_INTO.md new file mode 100644 index 00000000..4ff0373c --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER_STR_INTO.md @@ -0,0 +1,29 @@ +--- +title: "Libbpf eBPF macro 'BPF_CORE_READ_USER_STR_INTO'" +description: "This page documents the 'BPF_CORE_READ_USER_STR_INTO' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `BPF_CORE_READ_USER_STR_INTO` + +[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) + +The `BPF_CORE_READ_USER_STR_INTO` macro is a variant of the [`BPF_CORE_READ_USER_INTO`](BPF_CORE_READ_USER_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_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_STR_INTO` is very similar to [`BPF_CORE_READ_USER_INTO`](BPF_CORE_READ_USER_INTO.md), but it uses the [`bpf_probe_read_user_str`](../../../linux/helper-function/bpf_probe_read_kernel_str.md) helper function instead of the [`bpf_probe_read_kernel_str`](../../../linux/helper-function/bpf_probe_read_kernel_str.md) helper function. This makes it better suites for reading NUL-terminated strings from userspace 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 diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_CORE_WRITE_BITFIELD.md b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_WRITE_BITFIELD.md new file mode 100644 index 00000000..2fcf1852 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_CORE_WRITE_BITFIELD.md @@ -0,0 +1,50 @@ +--- +title: "Libbpf eBPF macro 'BPF_CORE_WRITE_BITFIELD'" +description: "This page documents the 'BPF_CORE_WRITE_BITFIELD' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `BPF_CORE_WRITE_BITFIELD` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `BPF_CORE_WRITE_BITFIELD` macro writes a bitfield to a given structure in a CO-RE relocatable way. + +## Definition + +```c +#define BPF_CORE_WRITE_BITFIELD(s, field, new_val) ({ \ + void *p = (void *)s + __CORE_RELO(s, field, BYTE_OFFSET); \ + unsigned int byte_size = __CORE_RELO(s, field, BYTE_SIZE); \ + unsigned int lshift = __CORE_RELO(s, field, LSHIFT_U64); \ + unsigned int rshift = __CORE_RELO(s, field, RSHIFT_U64); \ + unsigned long long mask, val, nval = new_val; \ + unsigned int rpad = rshift - lshift; \ + \ + asm volatile("" : "+r"(p)); \ + \ + switch (byte_size) { \ + case 1: val = *(unsigned char *)p; break; \ + case 2: val = *(unsigned short *)p; break; \ + case 4: val = *(unsigned int *)p; break; \ + case 8: val = *(unsigned long long *)p; break; \ + } \ + \ + mask = (~0ULL << rshift) >> lshift; \ + val = (val & ~mask) | ((nval << rpad) & mask); \ + \ + switch (byte_size) { \ + case 1: *(unsigned char *)p = val; break; \ + case 2: *(unsigned short *)p = val; break; \ + case 4: *(unsigned int *)p = val; break; \ + case 8: *(unsigned long long *)p = val; break; \ + } \ +}) +``` + +## Usage + +`BPF_CORE_WRITE_BITFIELD` writes to a bitfield, identified by `s->field`, the inverse of [`BPF_CORE_READ_BITFIELD`](BPF_CORE_READ_BITFIELD.md) 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 + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ.md b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ.md new file mode 100644 index 00000000..819d3179 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ.md @@ -0,0 +1,31 @@ +--- +title: "Libbpf eBPF macro 'BPF_PROBE_READ'" +description: "This page documents the 'BPF_PROBE_READ' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `BPF_PROBE_READ` + +[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) + +The `BPF_PROBE_READ` macro is the non CO-RE variant of [`BPF_CORE_READ`](BPF_CORE_READ.md). + +## Definition + +```c +#define BPF_PROBE_READ(src, a, ...) ({ \ + ___type((src), a, ##__VA_ARGS__) __r; \ + BPF_PROBE_READ_INTO(&__r, (src), a, ##__VA_ARGS__); \ + __r; \ +}) +``` + +## Usage + +The `BPF_PROBE_READ` macro is the non CO-RE variant of [`BPF_CORE_READ`](BPF_CORE_READ.md). So it does not emit CO-RE relocations. Its value is mostly in the pointer chasing use cases where this macro can convert one accessor into multiple [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) calls. + +!!! note + Only up to 9 "field accessors" are supported, which should be more than enough for any practical purpose. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_INTO.md b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_INTO.md new file mode 100644 index 00000000..ccafae5c --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_INTO.md @@ -0,0 +1,42 @@ +--- +title: "Libbpf eBPF macro 'BPF_PROBE_READ_INTO'" +description: "This page documents the 'BPF_PROBE_READ_INTO' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `BPF_PROBE_READ_INTO` + +[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) + +The `BPF_PROBE_READ_INTO` macro is a more performance-conscious variant of [`BPF_PROBE_READ`](BPF_PROBE_READ.md), in which final field is read into user-provided storage. + +## Definition + +```c +#define BPF_PROBE_READ_INTO(dst, src, a, ...) ({ \ + ___core_read(bpf_probe_read_kernel, bpf_probe_read_kernel, \ + dst, (src), a, ##__VA_ARGS__) \ +}) +``` + +## Usage + +`BPF_PROBE_READ_INTO` is very similar to [`BPF_PROBE_READ`](BPF_PROBE_READ.md), but instead of returning the value, it writes the value into the provided destination. + +This macro does not emit CO-RE relocations. Its value is mostly in the pointer chasing use cases where this macro can convert one accessor into multiple [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) calls. + +The following two code snippets are equivalent: + +```c +int x = BPF_PROBE_READ_INTO(s, a.b.c, d.e, f, g); +``` + +```c +int x; +BPF_PROBE_READ(&x, s, a.b.c, d.e, f, g); +``` + +Please refer to the [`BPF_PROBE_READ`](BPF_PROBE_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 diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_STR_INTO.md b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_STR_INTO.md new file mode 100644 index 00000000..2556359a --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_STR_INTO.md @@ -0,0 +1,31 @@ +--- +title: "Libbpf eBPF macro 'BPF_PROBE_READ_STR_INTO'" +description: "This page documents the 'BPF_PROBE_READ_STR_INTO' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `BPF_PROBE_READ_STR_INTO` + +[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) + +The `BPF_PROBE_READ_STR_INTO` macro is a variant of the [`BPF_PROBE_READ_INTO`](BPF_PROBE_READ_INTO.md) macro, which is used to do a string read into user-provided storage. + +## Definition + +```c +#define BPF_PROBE_READ_STR_INTO(dst, src, a, ...) ({ \ + ___core_read(bpf_probe_read_kernel_str, bpf_probe_read_kernel, \ + dst, (src), a, ##__VA_ARGS__) \ +}) +``` + +## Usage + +`BPF_PROBE_READ_STR_INTO` is very similar to [`BPF_PROBE_READ_INTO`](BPF_PROBE_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. + +This macro does not emit CO-RE relocations. Its value is mostly in the pointer chasing use cases where this macro can convert one accessor into multiple [`bpf_probe_read_kernel_str`](../../../linux/helper-function/bpf_probe_read_kernel_str.md) calls. + +Please refer to the [`BPF_PROBE_READ`](BPF_PROBE_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 diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER.md b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER.md new file mode 100644 index 00000000..9b783480 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER.md @@ -0,0 +1,32 @@ +--- +title: "Libbpf eBPF macro 'BPF_PROBE_READ_USER'" +description: "This page documents the 'BPF_PROBE_READ_USER' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `BPF_PROBE_READ_USER` + +[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) + +The `BPF_PROBE_READ_USER` macro is the userspace variant of the [`BPF_PROBE_READ`](BPF_PROBE_READ.md) macro. + +## Definition + +```c +#define BPF_PROBE_READ_USER(src, a, ...) ({ \ + ___type((src), a, ##__VA_ARGS__) __r; \ + BPF_PROBE_READ_USER_INTO(&__r, (src), a, ##__VA_ARGS__); \ + __r; \ +}) +``` + +## Usage + +The `BPF_PROBE_READ_USER` macro is the userspace variant of the [`BPF_PROBE_READ`](BPF_PROBE_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. + +This macro does not emit CO-RE relocations. Its value is mostly in the pointer chasing use cases where this macro can convert one accessor into multiple [`bpf_probe_read_user`](../../../linux/helper-function/bpf_probe_read_kernel.md) calls. As no CO-RE relocations are emitted, source types can be arbitrary and are not restricted to kernel types only. + +Please refer to the [`BPF_PROBE_READ`](BPF_PROBE_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 diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER_INTO.md b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER_INTO.md new file mode 100644 index 00000000..4e18c08e --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER_INTO.md @@ -0,0 +1,42 @@ +--- +title: "Libbpf eBPF macro 'BPF_PROBE_READ_USER_INTO'" +description: "This page documents the 'BPF_PROBE_READ_USER_INTO' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `BPF_PROBE_READ_USER_INTO` + +[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) + +The `BPF_PROBE_READ_USER_INTO` macro is a more performance-conscious variant of [`BPF_PROBE_READ_USER`](BPF_PROBE_READ_USER.md), in which final field is read into user-provided storage. + +## Definition + +```c +#define BPF_PROBE_READ_USER_INTO(dst, src, a, ...) ({ \ + ___core_read(bpf_probe_read_user, bpf_probe_read_user, \ + dst, (src), a, ##__VA_ARGS__) \ +}) +``` + +## Usage + +`BPF_PROBE_READ_USER_INTO` is very similar to [`BPF_PROBE_READ_USER`](BPF_PROBE_READ_USER.md), but instead of returning the value, it writes the value into the provided destination. + +This macro does not emit CO-RE relocations. Its value is mostly in the pointer chasing use cases where this macro can convert one accessor into multiple [`bpf_probe_read_user`](../../../linux/helper-function/bpf_probe_read_user.md) calls. + +The following two code snippets are equivalent: + +```c +int x = BPF_PROBE_READ_USER(s, a.b.c, d.e, f, g); +``` + +```c +int x; +BPF_PROBE_READ_USER_INTO(&x, s, a.b.c, d.e, f, g); +``` + +Please refer to the [`BPF_PROBE_READ_USER`](BPF_PROBE_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 diff --git a/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER_STR_INTO.md b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER_STR_INTO.md new file mode 100644 index 00000000..f3a54f52 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/BPF_PROBE_READ_USER_STR_INTO.md @@ -0,0 +1,31 @@ +--- +title: "Libbpf eBPF macro 'BPF_PROBE_READ_USER_STR_INTO'" +description: "This page documents the 'BPF_PROBE_READ_USER_STR_INTO' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `BPF_PROBE_READ_USER_STR_INTO` + +[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) + +The `BPF_PROBE_READ_USER_STR_INTO` macro is a variant of the [`BPF_PROBE_READ_USER_INTO`](BPF_PROBE_READ_USER_INTO.md) macro, which is used to do a string read into user-provided storage. + +## Definition + +```c +#define BPF_PROBE_READ_USER_STR_INTO(dst, src, a, ...) ({ \ + ___core_read(bpf_probe_read_user_str, bpf_probe_read_user, \ + dst, (src), a, ##__VA_ARGS__) \ +}) +``` + +## Usage + +`BPF_PROBE_READ_USER_STR_INTO` is very similar to [`BPF_PROBE_READ_USER_INTO`](BPF_PROBE_READ_USER_INTO.md), but it uses the [`bpf_probe_read_user_str`](../../../linux/helper-function/bpf_probe_read_kernel_str.md) helper function instead of the [`bpf_probe_read_kernel_str`](../../../linux/helper-function/bpf_probe_read_kernel_str.md) helper function. This makes it better suites for reading NUL-terminated strings from userspace memory. + +This macro does not emit CO-RE relocations. Its value is mostly in the pointer chasing use cases where this macro can convert one accessor into multiple [`bpf_probe_read_user_str`](../../../linux/helper-function/bpf_probe_read_user_str.md) calls. As no CO-RE relocations are emitted, source types can be arbitrary and are not restricted to kernel types only. + +Please refer to the [`BPF_PROBE_READ`](BPF_PROBE_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 diff --git a/docs/ebpf-library/libbpf/ebpf/SUMMARY.md b/docs/ebpf-library/libbpf/ebpf/SUMMARY.md index 82a207ed..b3abb51d 100644 --- a/docs/ebpf-library/libbpf/ebpf/SUMMARY.md +++ b/docs/ebpf-library/libbpf/ebpf/SUMMARY.md @@ -59,3 +59,36 @@ - [`BPF_URETPROBE`](BPF_URETPROBE.md) - [`BPF_KSYSCALL`](BPF_KSYSCALL.md) - [`BPF_KPROBE_SYSCALL`](BPF_KPROBE_SYSCALL.md) +- CO-RE memory access + - [`BPF_CORE_READ`](BPF_CORE_READ.md) + - [`BPF_CORE_READ_INTO`](BPF_CORE_READ_INTO.md) + - [`bpf_core_read`](bpf_core_read.md) + - [`BPF_CORE_READ_STR_INTO`](BPF_CORE_READ_STR_INTO.md) + - [`bpf_core_read_str`](bpf_core_read_str.md) + - [`BPF_CORE_READ_USER`](BPF_CORE_READ_USER.md) + - [`BPF_CORE_READ_USER_INTO`](BPF_CORE_READ_USER_INTO.md) + - [`bpf_core_read_user`](bpf_core_read_user.md) + - [`BPF_CORE_READ_USER_STR_INTO`](BPF_CORE_READ_USER_STR_INTO.md) + - [`bpf_core_read_user_str`](bpf_core_read_user_str.md) + - [`BPF_CORE_READ_BITFIELD`](BPF_CORE_READ_BITFIELD.md) + - [`BPF_CORE_READ_BITFIELD_PROBED`](BPF_CORE_READ_BITFIELD_PROBED.md) + - [`BPF_CORE_WRITE_BITFIELD`](BPF_CORE_WRITE_BITFIELD.md) +- CO-RE queries + - [`bpf_core_field_exists`](bpf_core_field_exists.md) + - [`bpf_core_field_size`](bpf_core_field_size.md) + - [`bpf_core_field_offset`](bpf_core_field_offset.md) + - [`bpf_core_type_id_local`](bpf_core_type_id_local.md) + - [`bpf_core_type_id_kernel`](bpf_core_type_id_kernel.md) + - [`bpf_core_type_exists`](bpf_core_type_exists.md) + - [`bpf_core_type_matches`](bpf_core_type_matches.md) + - [`bpf_core_type_size`](bpf_core_type_size.md) + - [`bpf_core_enum_value_exists`](bpf_core_enum_value_exists.md) + - [`bpf_core_enum_value`](bpf_core_enum_value.md) +- [`bpf_core_cast`](bpf_core_cast.md) +- Non CO-RE macros + - [`BPF_PROBE_READ`](BPF_PROBE_READ.md) + - [`BPF_PROBE_READ_INTO`](BPF_PROBE_READ_INTO.md) + - [`BPF_PROBE_READ_USER_INTO`](BPF_PROBE_READ_USER_INTO.md) + - [`BPF_PROBE_READ_STR_INTO`](BPF_PROBE_READ_STR_INTO.md) + - [`BPF_PROBE_READ_USER_STR_INTO`](BPF_PROBE_READ_USER_STR_INTO.md) + - [`BPF_PROBE_READ_USER`](BPF_PROBE_READ_USER.md) diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_cast.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_cast.md new file mode 100644 index 00000000..c8241ef4 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_cast.md @@ -0,0 +1,67 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_cast'" +description: "This page documents the 'bpf_core_cast' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_cast` + +[:octicons-tag-24: v1.4.0](https://github.com/libbpf/libbpf/releases/tag/v1.4.0) + +The `bpf_core_cast` macro abstracts away [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) call and captures offset relocation. + +## Definition + +```c +#define bpf_core_cast(ptr, type) \ + ((typeof(type) *)bpf_rdonly_cast((ptr), bpf_core_type_id_kernel(type))) +``` + +## Usage + +The `bpf_core_cast` macro casts the provided pointer `ptr` into a pointer to a specified `type` in such a way that BPF verifier will become aware of associated kernel-side BTF type. This allows to access members of kernel types directly without the need to use [`BPF_CORE_READ`](BPF_CORE_READ.md) macros. + +This macro calls the [`bpf_rdonly_cast`](../../../linux/kfuncs/bpf_rdonly_cast.md) kfunc with the kernel-side BTF type ID of the provided `type`. + +### Example + +```c hl_lines="29" +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Facebook + +#include +#include +#include +#include "bpf_tracing_net.h" +#define NUM_CGROUP_LEVELS 4 + +__u64 cgroup_ids[NUM_CGROUP_LEVELS]; +__u16 dport; + +static __always_inline void log_nth_level(struct __sk_buff *skb, __u32 level) +{ + /* [1] &level passed to external function that may change it, it's + * incompatible with loop unroll. + */ + cgroup_ids[level] = bpf_skb_ancestor_cgroup_id(skb, level); +} + +SEC("tc") +int log_cgroup_id(struct __sk_buff *skb) +{ + struct sock *sk = (void *)skb->sk; + + if (!sk) + return TC_ACT_OK; + + sk = bpf_core_cast(sk, struct sock); + if (sk->sk_protocol == IPPROTO_UDP && sk->sk_dport == dport) { + log_nth_level(skb, 0); + log_nth_level(skb, 1); + log_nth_level(skb, 2); + log_nth_level(skb, 3); + } + + return TC_ACT_OK; +} + +char _license[] SEC("license") = "GPL"; +``` diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_enum_value.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_enum_value.md new file mode 100644 index 00000000..bc48a2b9 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_enum_value.md @@ -0,0 +1,37 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_enum_value'" +description: "This page documents the 'bpf_core_enum_value' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_enum_value` + +[:octicons-tag-24: v0.2](https://github.com/libbpf/libbpf/releases/tag/v0.2) + +The `bpf_core_enum_value` macro is used to get the integer value of an enumerator value in a target kernel. + +## Definition + +```c +#ifdef __clang__ +#define bpf_core_enum_value(enum_type, enum_value) \ + __builtin_preserve_enum_value(*(typeof(enum_type) *)enum_value, BPF_ENUMVAL_VALUE) +#else +#define bpf_core_enum_value(enum_type, enum_value) \ + __builtin_preserve_enum_value(___bpf_typeof(enum_type), enum_value, BPF_ENUMVAL_VALUE) +#endif +``` + +## Usage + +The `bpf_core_enum_value` macro is used to get the integer value of an enumerator value in a target kernel. + +Returns: + + * 64-bit value, if specified enum type and its enumerator value are present in target kernel's BTF + * 0, if no matching enum and/or enum value within that enum is found + +This result is determined by the loader library such as libbpf, and set at load time and is considered as a constant value by the verifier. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_enum_value_exists.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_enum_value_exists.md new file mode 100644 index 00000000..1016149f --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_enum_value_exists.md @@ -0,0 +1,37 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_enum_value_exists'" +description: "This page documents the 'bpf_core_enum_value_exists' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_enum_value_exists` + +[:octicons-tag-24: v0.2](https://github.com/libbpf/libbpf/releases/tag/v0.2) + +The `bpf_core_enum_value_exists` macro is used to check that provided enumerator value is defined in a target kernel. + +## Definition + +```c +#ifdef __clang__ +#define bpf_core_enum_value_exists(enum_type, enum_value) \ + __builtin_preserve_enum_value(*(typeof(enum_type) *)enum_value, BPF_ENUMVAL_EXISTS) +#else +#define bpf_core_enum_value_exists(enum_type, enum_value) \ + __builtin_preserve_enum_value(___bpf_typeof(enum_type), enum_value, BPF_ENUMVAL_EXISTS) +#endif +``` + +## Usage + +The `bpf_core_enum_value_exists` macro is used to check that provided enumerator value is defined in a target kernel. + +Returns: + + * 1, if specified enum type and its enumerator value are present in target kernel's BTF + * 0, if no matching enum and/or enum value within that enum is found + +This result is determined by the loader library such as libbpf, and set at load time. If a branch is never taken based on the result, it will not be evaluated by the verifier. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_field_exists.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_field_exists.md new file mode 100644 index 00000000..946a55fd --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_field_exists.md @@ -0,0 +1,62 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_field_exists'" +description: "This page documents the 'bpf_core_field_exists' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_field_exists` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `bpf_core_field_exists` macro is used to query if a struct field exists in the kernel the program is being loaded on. + +## Definition + +```c +#define bpf_core_field_exists(field...) \ + __builtin_preserve_field_info(___bpf_field_ref(field), BPF_FIELD_EXISTS) +``` + +## Usage + +The `bpf_core_field_exists` macro is used to essentially ask a given field exists in the kernel the program is being loaded on. One use case is to have fallback code in case a certain field is not present in the kernel. + +Returns: + +* 1, if matching field is present in target kernel +* 0, if no matching field found + +Supports two forms: + +* field reference through variable access: `#!c bpf_core_field_exists(p->my_field)` +* field reference through type and field names: `#!c bpf_core_field_exists(struct my_type, my_field)` + +This result is determined by the loader library such as libbpf, and set at load time. If a branch is never taken based on the result, it will not be evaluated by the verifier. + +### Example + +```c hl_lines="32 33" +struct some_kernel_struct { + int a; + int b; +}; + +SEC("kprobe") +int kprobe__example(struct pt_regs *ctx) +{ + struct some_kernel_struct *a = PT_REGS_PARM1(ctx); + int b; + + // Depending on if some_kernel_struct->b exists on the kernel we are running on + // one or the other branch is taken. The verifier will only evaluate the branch + // that is taken, and will optimize the if statement away, so this does not + // impact the program's performance. + if (bpf_core_field_exists(a->b)) { + b = BPF_CORE_READ(a, b); + } else { + b = more_complex_fallback_to_get_b(); + } + + bpf_printk("Value of field 'a' = %d", b); + + return 0; +} +``` diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_field_offset.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_field_offset.md new file mode 100644 index 00000000..514b490c --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_field_offset.md @@ -0,0 +1,48 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_field_offset'" +description: "This page documents the 'bpf_core_field_offset' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_field_offset` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `bpf_core_field_offset` macro is used to query the offset of a struct field on the kernel the program is being loaded on. The returned offset is in bytes. + +## Definition + +```c +#define bpf_core_field_offset(field...) \ + __builtin_preserve_field_info(___bpf_field_ref(field), BPF_FIELD_BYTE_OFFSET) +``` + +## Usage + +The `bpf_core_field_offset` macro is used to query the offset of a struct field on the kernel the program is being loaded on. The returned size is in bytes. + +Supports two forms: + +* field reference through variable access: `#!c bpf_core_field_offset(p->my_field)` +* field reference through type and field names: `#!c bpf_core_field_offset(struct my_type, my_field)` + +This result is determined by the loader library such as libbpf, and set at load time and is considered as a constant value by the verifier. + +### Example + +```c +struct some_kernel_struct { + __u16 field1; // This field might be smaller or larger on the target kernel + __u32 field2; +} + +SEC("kprobe") +int kprobe__example(struct pt_regs *ctx) +{ + struct some_kernel_struct *a = PT_REGS_PARM1(ctx); + int field_offset = bpf_core_field_offset(a->field2) + + // Do something with field_offset + // ... + + return 0; +} +``` diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_field_size.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_field_size.md new file mode 100644 index 00000000..80751c9d --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_field_size.md @@ -0,0 +1,50 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_field_size'" +description: "This page documents the 'bpf_core_field_size' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_field_size` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `bpf_core_field_size` macro is used to query the size of a struct field on the kernel the program is being loaded on. The returned size is in bytes. + +## Definition + +```c +#define bpf_core_field_size(field...) \ + __builtin_preserve_field_info(___bpf_field_ref(field), BPF_FIELD_BYTE_SIZE) +``` + +## Usage + +The `bpf_core_field_size` macro is used to query the size of a struct field on the kernel the program is being loaded on. The returned size is in bytes. The macro works for integers, struct/unions, pointers, arrays, and enums. + +Supports two forms: + +* field reference through variable access: `#!c bpf_core_field_size(p->my_field)` +* field reference through type and field names: `#!c bpf_core_field_size(struct my_type, my_field)` + +This result is determined by the loader library such as libbpf, and set at load time and is considered as a constant value by the verifier. + +### Example + +```c +struct some_kernel_struct { + __u16 field1; // This field might be smaller or larger on the target kernel +} + +SEC("kprobe") +int kprobe__example(struct pt_regs *ctx) +{ + struct some_kernel_struct *a = PT_REGS_PARM1(ctx); + __u64 tmp; + + tmp = 0; + bpf_core_read_int(&tmp, bpf_core_field_size(a->field1), &a->field1); + + // Do something with tmp + // ... + + return 0; +} +``` diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_read.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_read.md new file mode 100644 index 00000000..dcb5663e --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_read.md @@ -0,0 +1,71 @@ +--- +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 abstracts away [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) call and captures offset relocation. + +## Definition + +```c +#define bpf_core_read(dst, sz, src) \ + bpf_probe_read_kernel(dst, sz, (const void *)__builtin_preserve_access_index(src)) +``` + +## Usage + +The `bpf_core_read` abstracts away [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md) call and captures offset relocation. + +This relocation allows libbpf to adjust BPF instruction to use correct actual field offset, based on target kernel BTF type that matches original (local) BTF, used to record relocation. + +`dst` is a pointer to the destination buffer, `sz` is the size of the buffer, and `src` an expression that evaluates to the pointer to kernel memory. + +Given a structure like: + +```c +struct a { + int b; + struct { + struct some_value *d; + } c; +}; +``` + +Where you wish to get the value of `d`, you would call `bpf_core_read` as: + +```c +struct some_value dst; +bpf_core_read(&dst, sizeof(dst), a.c.d); +``` + +Since `src` contains the field accesses, these fill be stored in the relocation entry so the actual offset can be adjusted. It is therefor important to not do the field access outside of the `bpf_core_read`: + +```c +/* Incorrect */ +struct some_value dst; +struct some_value *ptr = a.c.d; +bpf_core_read(&dst, sizeof(dst), ptr); +``` + +It is also important to remember that you should avoid using expressions that implicitly dereference pointers. For example, an expression like `a->b.c` will dereference the pointer `a` without the use of [`bpf_probe_read_kernel`](../../../linux/helper-function/bpf_probe_read_kernel.md). Whereas `&a->b` will not dereference the pointer `a`. + +To do a CO-RE read with dereferences, use the [`BPF_CORE_READ`](BPF_CORE_READ.md) macro, which chains multiple `bpf_core_read` calls together for you like: `BPF_CORE_READ(a, b.c)`. + + +### Example + +```c hl_lines="5" +struct task_struct *task = (void *)bpf_get_current_task(); +struct task_struct *parent_task; +int err; + +err = bpf_core_read(&parent_task, sizeof(void *), &task->parent); +if (err) { + /* handle error */ +} + +/* parent_task contains the value of task->parent pointer */ +``` diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_read_str.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_read_str.md new file mode 100644 index 00000000..a844f102 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_read_str.md @@ -0,0 +1,27 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_read_str'" +description: "This page documents the 'bpf_core_read_str' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_read_str` + +[:octicons-tag-24: v0.0.6](https://github.com/libbpf/libbpf/releases/tag/v0.0.6) + +The `bpf_core_read_str` macro abstracts away [`bpf_probe_read_kernel_str`](../../../linux/helper-function/bpf_probe_read_kernel_str.md) call and captures offset relocation. + +## Definition + +```c +#define bpf_core_read_str(dst, sz, src) \ + bpf_probe_read_kernel_str(dst, sz, (const void *)__builtin_preserve_access_index(src)) +``` + +## Usage + +`bpf_core_read_str` is the string variant of the [`bpf_core_read`](bpf_core_read.md) macro. It is better suited for reading NUL-terminated strings from kernel memory. + +See 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 diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_read_user.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_read_user.md new file mode 100644 index 00000000..aa798cad --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_read_user.md @@ -0,0 +1,27 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_read_user'" +description: "This page documents the 'bpf_core_read' 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 abstracts away [`bpf_probe_read_user`](../../../linux/helper-function/bpf_probe_read_user.md) call and captures offset relocation. + +## Definition + +```c +#define bpf_core_read_user(dst, sz, src) \ + bpf_probe_read_user(dst, sz, (const void *)__builtin_preserve_access_index(src)) +``` + +## Usage + +The `bpf_core_read_user` is the userspace variant of [`bpf_core_read`](bpf_core_read.md). It wraps the [`bpf_probe_read_user`](../../../linux/helper-function/bpf_probe_read_user.md) helper function instead of [`bpf_probe_read`](../../../linux/helper-function/bpf_probe_read.md). + +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 diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_read_user_str.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_read_user_str.md new file mode 100644 index 00000000..a41a7b9d --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_read_user_str.md @@ -0,0 +1,27 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_read_user_str'" +description: "This page documents the 'bpf_core_read_user_str' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_read_user_str` + +[:octicons-tag-24: v0.4.0](https://github.com/libbpf/libbpf/releases/tag/v0.4.0) + +The `bpf_core_read_user_str` macro abstracts away [`bpf_probe_read_user_str`](../../../linux/helper-function/bpf_probe_read_user_str.md) call and captures offset relocation. + +## Definition + +```c +#define bpf_core_read_user_str(dst, sz, src) \ + bpf_probe_read_user_str(dst, sz, (const void *)__builtin_preserve_access_index(src)) +``` + +## Usage + +`bpf_core_read_user_str` is the string variant of the [`bpf_core_read_user`](bpf_core_read_user.md) macro. It is better suited for reading NUL-terminated strings from kernel memory. + +See 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 diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_type_exists.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_type_exists.md new file mode 100644 index 00000000..12975b54 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_type_exists.md @@ -0,0 +1,57 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_type_exists'" +description: "This page documents the 'bpf_core_type_exists' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_type_exists` + +[:octicons-tag-24: v0.2](https://github.com/libbpf/libbpf/releases/tag/v0.2) + +The `bpf_core_type_exists` macro is used to check that provided named type (struct/union/enum/typedef) exists in a target kernel. + +## Definition + +```c +#define bpf_core_type_exists(type) \ + __builtin_preserve_type_info(*___bpf_typeof(type), BPF_TYPE_EXISTS) +``` + +## Usage + +The `bpf_core_field_exists` macro is used to essentially ask a given type (struct/union/enum/typedef) exists in the kernel the program is being loaded on. One use case is to have fallback code in case a certain field is not present in the kernel. + +Returns: + + * 1, if such type is present in target kernel's BTF + * 0, if no matching type is found + +This result is determined by the loader library such as libbpf, and set at load time. If a branch is never taken based on the result, it will not be evaluated by the verifier. + +### Example + +```c hl_lines="32 33" +struct some_kernel_struct { + int a; + int b; +}; + +SEC("kprobe") +int kprobe__example(struct pt_regs *ctx) +{ + int b; + + // Depending on if some_kernel_struct exists on the kernel we are running on + // one or the other branch is taken. The verifier will only evaluate the branch + // that is taken, and will optimize the if statement away, so this does not + // impact the program's performance. + if (bpf_core_field_exists(struct some_kernel_struct)) { + struct some_kernel_struct *a = PT_REGS_PARM1(ctx); + int b = BPF_CORE_READ(a, b); + } else { + int b = more_complex_fallback_to_get_b(); + } + + bpf_printk("Value of field 'a' = %d", b); + + return 0; +} +``` diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_type_id_kernel.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_type_id_kernel.md new file mode 100644 index 00000000..27e33f49 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_type_id_kernel.md @@ -0,0 +1,34 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_type_id_kernel'" +description: "This page documents the 'bpf_core_type_id_kernel' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_type_id_kernel` + +[:octicons-tag-24: v0.2](https://github.com/libbpf/libbpf/releases/tag/v0.2) + +The `bpf_core_type_id_kernel` macro to get BTF type ID of a target kernel's type that matches specified local type. + +## Definition + +```c +#define bpf_core_type_id_kernel(type) \ + __builtin_btf_type_id(*___bpf_typeof(type), BPF_TYPE_ID_TARGET) +``` + +## Usage + +The `bpf_core_type_id_kernel` macro to get BTF type ID of a target kernel's type that matches specified local type. + +The target BTF type ID can be used to construct a `struct btf_ptr` to be used as parameter to [`bpf_snprintf_btf`](../../../linux/helper-function/bpf_snprintf_btf.md). + +Returns: + + * valid 32-bit unsigned type ID in kernel BTF + * 0, if no matching type was found in a target kernel BTF + +This result is determined by the loader library such as libbpf, and set at load time and is considered as a constant value by the verifier. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_type_id_local.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_type_id_local.md new file mode 100644 index 00000000..0869af4a --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_type_id_local.md @@ -0,0 +1,29 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_type_id_local'" +description: "This page documents the 'bpf_core_type_id_local' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_type_id_local` + +[:octicons-tag-24: v0.2](https://github.com/libbpf/libbpf/releases/tag/v0.2) + +The `bpf_core_type_id_local` macro to get BTF type ID of a specified type, using a local BTF information. + +## Definition + +```c +#define bpf_core_type_id_local(type) \ + __builtin_btf_type_id(*___bpf_typeof(type), BPF_TYPE_ID_LOCAL) +``` + +## Usage + +The `bpf_core_type_id_local` macro to get BTF type ID of a specified type, using a local BTF information. Return 32-bit unsigned integer with type ID from program's own BTF. Always succeeds. + +The local type ID can be useful to communicate type info from BPF to userspace or as parameter for kfuncs such as [`bpf_obj_new_impl`](../../../linux/kfuncs/bpf_obj_new_impl.md) or [`bpf_percpu_obj_new_impl`](../../../linux/kfuncs/bpf_percpu_obj_new_impl.md). + +This result is determined by the loader library such as libbpf, and set at load time and is considered as a constant value by the verifier. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_type_matches.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_type_matches.md new file mode 100644 index 00000000..313d74f2 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_type_matches.md @@ -0,0 +1,87 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_type_matches'" +description: "This page documents the 'bpf_core_type_matches' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_type_matches` + +[:octicons-tag-24: v1.0.0](https://github.com/libbpf/libbpf/releases/tag/v1.0.0) + +The `bpf_core_type_matches` macro is used to check that provided named type (struct/union/enum/typedef) "matches" that in a target kernel. + +## Definition + +```c +#define bpf_core_type_matches(type) \ + __builtin_preserve_type_info(*___bpf_typeof(type), BPF_TYPE_MATCHES) +``` + +## Usage + +The `bpf_core_type_matches` macro is used to check that provided named type (struct/union/enum/typedef) "matches" that in a target kernel. + +The matching relation is defined as follows: + +* modifiers and typedefs are stripped (and, hence, effectively ignored) +* generally speaking types need to be of same kind (struct vs. struct, union vs. union, etc.) + * exceptions are struct/union behind a pointer which could also match a forward declaration of a struct or union, respectively, and enum vs. enum64 (see below) + +Then, depending on type: + +* integers: + * match if size and signedness match +* arrays & pointers: + * target types are recursively matched +* structs & unions: + * local members need to exist in target with the same name + * for each member we recursively check match unless it is already behind a pointer, in which case we only check matching names and compatible kind +* enums: + * local variants have to have a match in target by symbolic name (but not numeric value) + * size has to match (but enum may match enum64 and vice versa) +* function pointers: + * number and position of arguments in local type has to match target + * for each argument and the return value we recursively check match + +Returns: + + * 1, if the type matches in the target kernel's BTF + * 0, if the type does not match any in the target kernel + +This result is determined by the loader library such as libbpf, and set at load time. If a branch is never taken based on the result, it will not be evaluated by the verifier. + +### Example + +```c hl_lines="18 21" +struct rw_semaphore___old { + struct task_struct *owner; +} __attribute__((preserve_access_index)); + +struct rw_semaphore___new { + atomic_long_t owner; +} __attribute__((preserve_access_index)); + +static inline struct task_struct *get_lock_owner(__u64 lock, __u32 flags) +{ + struct task_struct *task; + __u64 owner = 0; + + if (flags & LCB_F_MUTEX) { + struct mutex *mutex = (void *)lock; + owner = BPF_CORE_READ(mutex, owner.counter); + } else if (flags == LCB_F_READ || flags == LCB_F_WRITE) { + if (bpf_core_type_matches(struct rw_semaphore___old)) { + struct rw_semaphore___old *rwsem = (void *)lock; + owner = (unsigned long)BPF_CORE_READ(rwsem, owner); + } else if (bpf_core_type_matches(struct rw_semaphore___new)) { + struct rw_semaphore___new *rwsem = (void *)lock; + owner = BPF_CORE_READ(rwsem, owner.counter); + } + } + + if (!owner) + return NULL; + + task = (void *)(owner & ~7UL); + return task; +} + +``` diff --git a/docs/ebpf-library/libbpf/ebpf/bpf_core_type_size.md b/docs/ebpf-library/libbpf/ebpf/bpf_core_type_size.md new file mode 100644 index 00000000..8df18fd5 --- /dev/null +++ b/docs/ebpf-library/libbpf/ebpf/bpf_core_type_size.md @@ -0,0 +1,32 @@ +--- +title: "Libbpf eBPF macro 'bpf_core_type_size'" +description: "This page documents the 'bpf_core_type_size' libbpf eBPF macro, including its definition, usage, and examples." +--- +# Libbpf eBPF macro `bpf_core_type_size` + +[:octicons-tag-24: v0.2](https://github.com/libbpf/libbpf/releases/tag/v0.2) + +The `bpf_core_type_size` macro is used to get the byte size of a provided named type (struct/union/enum/typedef) in a target kernel. + +## Definition + +```c +#define bpf_core_type_size(type) \ + __builtin_preserve_type_info(*___bpf_typeof(type), BPF_TYPE_SIZE) +``` + +## Usage + +The `bpf_core_type_size` macro is used to get the byte size of a provided named type (struct/union/enum/typedef) in a target kernel. The returned size is in bytes. + +Returns: + + * \>= 0 size (in bytes), if type is present in target kernel's BTF + * 0, if no matching type is found + +This result is determined by the loader library such as libbpf, and set at load time and is considered as a constant value by the verifier. + +### Example + +!!! example "Docs could be improved" + This part of the docs is incomplete, contributions are very welcome diff --git a/docs/ebpf-library/libbpf/ebpf/index.md b/docs/ebpf-library/libbpf/ebpf/index.md index 6e8987e0..87cd2f1b 100644 --- a/docs/ebpf-library/libbpf/ebpf/index.md +++ b/docs/ebpf-library/libbpf/ebpf/index.md @@ -104,34 +104,36 @@ The `bpf_core_read.h` file contains macros for CO-RE(Compile Once Run Everywhere The file contains definitions for the following: -* `BPF_CORE_READ_BITFIELD_PROBED` -* `BPF_CORE_READ_BITFIELD` -* `BPF_CORE_WRITE_BITFIELD` -* `bpf_core_field_exists` -* `bpf_core_field_size` -* `bpf_core_field_offset` -* `bpf_core_type_id_local` -* `bpf_core_type_id_kernel` -* `bpf_core_type_exists` -* `bpf_core_type_matches` -* `bpf_core_type_size` -* `bpf_core_enum_value_exists` -* `bpf_core_enum_value` -* `bpf_core_read` -* `bpf_core_read_user` -* `bpf_core_read_str` -* `bpf_core_read_user_str` -* `bpf_core_cast` -* `BPF_CORE_READ_INTO` -* `BPF_CORE_READ_USER_INTO` -* `BPF_CORE_READ_STR_INTO` -* `BPF_CORE_READ_USER_STR_INTO` -* `BPF_CORE_READ_BITFIELD_INTO` -* `BPF_CORE_READ` -* `BPF_CORE_READ_USER` -* `BPF_PROBE_READ_INTO` -* `BPF_PROBE_READ_USER_INTO` -* `BPF_PROBE_READ_STR_INTO` -* `BPF_PROBE_READ_USER_STR_INTO` -* `BPF_PROBE_READ` -* `BPF_PROBE_READ_USER` +* CO-RE memory access + * [`BPF_CORE_READ`](BPF_CORE_READ.md) + * [`BPF_CORE_READ_INTO`](BPF_CORE_READ_INTO.md) + * [`bpf_core_read`](bpf_core_read.md) + * [`BPF_CORE_READ_STR_INTO`](BPF_CORE_READ_STR_INTO.md) + * [`bpf_core_read_str`](bpf_core_read_str.md) + * [`BPF_CORE_READ_USER`](BPF_CORE_READ_USER.md) + * [`BPF_CORE_READ_USER_INTO`](BPF_CORE_READ_USER_INTO.md) + * [`bpf_core_read_user`](bpf_core_read_user.md) + * [`BPF_CORE_READ_USER_STR_INTO`](BPF_CORE_READ_USER_STR_INTO.md) + * [`bpf_core_read_user_str`](bpf_core_read_user_str.md) + * [`BPF_CORE_READ_BITFIELD`](BPF_CORE_READ_BITFIELD.md) + * [`BPF_CORE_READ_BITFIELD_PROBED`](BPF_CORE_READ_BITFIELD_PROBED.md) + * [`BPF_CORE_WRITE_BITFIELD`](BPF_CORE_WRITE_BITFIELD.md) +* CO-RE queries + * [`bpf_core_field_exists`](bpf_core_field_exists.md) + * [`bpf_core_field_size`](bpf_core_field_size.md) + * [`bpf_core_field_offset`](bpf_core_field_offset.md) + * [`bpf_core_type_id_local`](bpf_core_type_id_local.md) + * [`bpf_core_type_id_kernel`](bpf_core_type_id_kernel.md) + * [`bpf_core_type_exists`](bpf_core_type_exists.md) + * [`bpf_core_type_matches`](bpf_core_type_matches.md) + * [`bpf_core_type_size`](bpf_core_type_size.md) + * [`bpf_core_enum_value_exists`](bpf_core_enum_value_exists.md) + * [`bpf_core_enum_value`](bpf_core_enum_value.md) +* [`bpf_core_cast`](bpf_core_cast.md) +* Non CO-RE macros + * [`BPF_PROBE_READ`](BPF_PROBE_READ.md) + * [`BPF_PROBE_READ_INTO`](BPF_PROBE_READ_INTO.md) + * [`BPF_PROBE_READ_USER_INTO`](BPF_PROBE_READ_USER_INTO.md) + * [`BPF_PROBE_READ_STR_INTO`](BPF_PROBE_READ_STR_INTO.md) + * [`BPF_PROBE_READ_USER_STR_INTO`](BPF_PROBE_READ_USER_STR_INTO.md) + * [`BPF_PROBE_READ_USER`](BPF_PROBE_READ_USER.md) diff --git a/docs/linux/kfuncs/bpf_rdonly_cast.md b/docs/linux/kfuncs/bpf_rdonly_cast.md index 9f29874c..e5c48e63 100644 --- a/docs/linux/kfuncs/bpf_rdonly_cast.md +++ b/docs/linux/kfuncs/bpf_rdonly_cast.md @@ -62,6 +62,48 @@ The following program types can make use of this kfunc: ### Example -!!! example "Docs could be improved" - This part of the docs is incomplete, contributions are very welcome +This example shows a use case of `bpf_rdonly_cast`, which in the example is called by the [`bpf_core_cast`](../../ebpf-library/libbpf/ebpf/bpf_core_cast.md) macro. + +```c hl_lines="29" +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Facebook + +#include +#include +#include +#include "bpf_tracing_net.h" +#define NUM_CGROUP_LEVELS 4 + +__u64 cgroup_ids[NUM_CGROUP_LEVELS]; +__u16 dport; + +static __always_inline void log_nth_level(struct __sk_buff *skb, __u32 level) +{ + /* [1] &level passed to external function that may change it, it's + * incompatible with loop unroll. + */ + cgroup_ids[level] = bpf_skb_ancestor_cgroup_id(skb, level); +} + +SEC("tc") +int log_cgroup_id(struct __sk_buff *skb) +{ + struct sock *sk = (void *)skb->sk; + + if (!sk) + return TC_ACT_OK; + + sk = bpf_core_cast(sk, struct sock); + if (sk->sk_protocol == IPPROTO_UDP && sk->sk_dport == dport) { + log_nth_level(skb, 0); + log_nth_level(skb, 1); + log_nth_level(skb, 2); + log_nth_level(skb, 3); + } + + return TC_ACT_OK; +} + +char _license[] SEC("license") = "GPL"; +```