mirror of
https://github.com/netdata/libbpf.git
synced 2026-03-14 13:29:06 +08:00
Compare commits
37 Commits
netdata_pa
...
netdata_pa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11eaf2b0b7 | ||
|
|
b39b7f426f | ||
|
|
e055420033 | ||
|
|
255b705a16 | ||
|
|
6a41f02ad4 | ||
|
|
dd589c3b31 | ||
|
|
045a0372ef | ||
|
|
6c3cf5108e | ||
|
|
b63d2945ff | ||
|
|
d3e18fceec | ||
|
|
22bd976613 | ||
|
|
f9f3fbf72d | ||
|
|
37b8e0eb2d | ||
|
|
f28271ab72 | ||
|
|
b1051d9361 | ||
|
|
43df08cd17 | ||
|
|
4794f18bf4 | ||
|
|
2fdcc365a0 | ||
|
|
52c37177cc | ||
|
|
7cbfddfdf2 | ||
|
|
f2fe16ec95 | ||
|
|
a911ca1e3e | ||
|
|
24924003c6 | ||
|
|
2c6f445a8e | ||
|
|
09397e309a | ||
|
|
62217fb32a | ||
|
|
b521a722b9 | ||
|
|
98de9ace4d | ||
|
|
26d9ab5f78 | ||
|
|
c5219d1b3d | ||
|
|
8d3a3e138b | ||
|
|
9f2853a352 | ||
|
|
d2f83fb976 | ||
|
|
8b9cb7d479 | ||
|
|
b062410166 | ||
|
|
89d8cdf741 | ||
|
|
8a2054f417 |
155090
.github/actions/build-selftests/vmlinux.h
vendored
155090
.github/actions/build-selftests/vmlinux.h
vendored
File diff suppressed because it is too large
Load Diff
17
.mailmap
Normal file
17
.mailmap
Normal file
@@ -0,0 +1,17 @@
|
||||
Alexei Starovoitov <ast@kernel.org> <alexei.starovoitov@gmail.com>
|
||||
Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com>
|
||||
Benjamin Tissoires <bentiss@kernel.org> <benjamin.tissoires@redhat.com>
|
||||
Björn Töpel <bjorn@kernel.org> <bjorn.topel@intel.com>
|
||||
Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com>
|
||||
Colin Ian King <colin.i.king@gmail.com> <colin.king@canonical.com>
|
||||
Dan Carpenter <error27@gmail.com> <dan.carpenter@oracle.com>
|
||||
Geliang Tang <geliang@kernel.org> <geliang.tang@suse.com>
|
||||
Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Jakub Kicinski <kuba@kernel.org> <jakub.kicinski@netronome.com>
|
||||
Leo Yan <leo.yan@linux.dev> <leo.yan@linaro.org>
|
||||
Mark Starovoytov <mstarovo@pm.me> <mstarovoitov@marvell.com>
|
||||
Maxim Mikityanskiy <maxtram95@gmail.com> <maximmi@mellanox.com>
|
||||
Maxim Mikityanskiy <maxtram95@gmail.com> <maximmi@nvidia.com>
|
||||
Quentin Monnet <qmo@kernel.org> <quentin@isovalent.com>
|
||||
Quentin Monnet <qmo@kernel.org> <quentin.monnet@netronome.com>
|
||||
Vadim Fedorenko <vadim.fedorenko@linux.dev> <vfedorenko@novek.ru>
|
||||
@@ -1 +1 @@
|
||||
443574b033876c85a35de4c65c14f7fe092222b2
|
||||
3e9bc0472b910d4115e16e9c2d684c7757cb6c60
|
||||
|
||||
@@ -1 +1 @@
|
||||
14bb1e8c8d4ad5d9d2febb7d19c70a3cf536e1e5
|
||||
0737df6de94661ae55fd3343ce9abec32c687e62
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
From c71766e8ff7a7f950522d25896fba758585500df Mon Sep 17 00:00:00 2001
|
||||
From: Song Liu <song@kernel.org>
|
||||
Date: Mon, 22 Apr 2024 21:14:40 -0700
|
||||
Subject: [PATCH] arch/Kconfig: Move SPECULATION_MITIGATIONS to arch/Kconfig
|
||||
|
||||
SPECULATION_MITIGATIONS is currently defined only for x86. As a result,
|
||||
IS_ENABLED(CONFIG_SPECULATION_MITIGATIONS) is always false for other
|
||||
archs. f337a6a21e2f effectively set "mitigations=off" by default on
|
||||
non-x86 archs, which is not desired behavior. Jakub observed this
|
||||
change when running bpf selftests on s390 and arm64.
|
||||
|
||||
Fix this by moving SPECULATION_MITIGATIONS to arch/Kconfig so that it is
|
||||
available in all archs and thus can be used safely in kernel/cpu.c
|
||||
|
||||
Fixes: f337a6a21e2f ("x86/cpu: Actually turn off mitigations by default for SPECULATION_MITIGATIONS=n")
|
||||
Cc: stable@vger.kernel.org
|
||||
Cc: Sean Christopherson <seanjc@google.com>
|
||||
Cc: Ingo Molnar <mingo@kernel.org>
|
||||
Cc: Daniel Sneddon <daniel.sneddon@linux.intel.com>
|
||||
Cc: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Song Liu <song@kernel.org>
|
||||
---
|
||||
arch/Kconfig | 10 ++++++++++
|
||||
arch/x86/Kconfig | 10 ----------
|
||||
2 files changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/arch/Kconfig b/arch/Kconfig
|
||||
index 9f066785bb71..8f4af75005f8 100644
|
||||
--- a/arch/Kconfig
|
||||
+++ b/arch/Kconfig
|
||||
@@ -1609,4 +1609,14 @@ config CC_HAS_SANE_FUNCTION_ALIGNMENT
|
||||
# strict alignment always, even with -falign-functions.
|
||||
def_bool CC_HAS_MIN_FUNCTION_ALIGNMENT || CC_IS_CLANG
|
||||
|
||||
+menuconfig SPECULATION_MITIGATIONS
|
||||
+ bool "Mitigations for speculative execution vulnerabilities"
|
||||
+ default y
|
||||
+ help
|
||||
+ Say Y here to enable options which enable mitigations for
|
||||
+ speculative execution hardware vulnerabilities.
|
||||
+
|
||||
+ If you say N, all mitigations will be disabled. You really
|
||||
+ should know what you are doing to say so.
|
||||
+
|
||||
endmenu
|
||||
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
|
||||
index 39886bab943a..50c890fce5e0 100644
|
||||
--- a/arch/x86/Kconfig
|
||||
+++ b/arch/x86/Kconfig
|
||||
@@ -2486,16 +2486,6 @@ config PREFIX_SYMBOLS
|
||||
def_bool y
|
||||
depends on CALL_PADDING && !CFI_CLANG
|
||||
|
||||
-menuconfig SPECULATION_MITIGATIONS
|
||||
- bool "Mitigations for speculative execution vulnerabilities"
|
||||
- default y
|
||||
- help
|
||||
- Say Y here to enable options which enable mitigations for
|
||||
- speculative execution hardware vulnerabilities.
|
||||
-
|
||||
- If you say N, all mitigations will be disabled. You really
|
||||
- should know what you are doing to say so.
|
||||
-
|
||||
if SPECULATION_MITIGATIONS
|
||||
|
||||
config MITIGATION_PAGE_TABLE_ISOLATION
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -41,7 +41,6 @@ task_fd_query_rawtp
|
||||
task_fd_query_tp
|
||||
tc_bpf
|
||||
tcp_estats
|
||||
tcp_rtt
|
||||
test_global_funcs/arg_tag_ctx*
|
||||
tp_attach_query
|
||||
usdt/urand_pid_attach
|
||||
|
||||
@@ -1115,6 +1115,7 @@ enum bpf_attach_type {
|
||||
BPF_CGROUP_UNIX_GETSOCKNAME,
|
||||
BPF_NETKIT_PRIMARY,
|
||||
BPF_NETKIT_PEER,
|
||||
BPF_TRACE_KPROBE_SESSION,
|
||||
__MAX_BPF_ATTACH_TYPE
|
||||
};
|
||||
|
||||
@@ -1135,6 +1136,7 @@ enum bpf_link_type {
|
||||
BPF_LINK_TYPE_TCX = 11,
|
||||
BPF_LINK_TYPE_UPROBE_MULTI = 12,
|
||||
BPF_LINK_TYPE_NETKIT = 13,
|
||||
BPF_LINK_TYPE_SOCKMAP = 14,
|
||||
__MAX_BPF_LINK_TYPE,
|
||||
};
|
||||
|
||||
@@ -3394,6 +3396,10 @@ union bpf_attr {
|
||||
* for the nexthop. If the src addr cannot be derived,
|
||||
* **BPF_FIB_LKUP_RET_NO_SRC_ADDR** is returned. In this
|
||||
* case, *params*->dmac and *params*->smac are not set either.
|
||||
* **BPF_FIB_LOOKUP_MARK**
|
||||
* Use the mark present in *params*->mark for the fib lookup.
|
||||
* This option should not be used with BPF_FIB_LOOKUP_DIRECT,
|
||||
* as it only has meaning for full lookups.
|
||||
*
|
||||
* *ctx* is either **struct xdp_md** for XDP programs or
|
||||
* **struct sk_buff** tc cls_act programs.
|
||||
@@ -5022,7 +5028,7 @@ union bpf_attr {
|
||||
* bytes will be copied to *dst*
|
||||
* Return
|
||||
* The **hash_algo** is returned on success,
|
||||
* **-EOPNOTSUP** if IMA is disabled or **-EINVAL** if
|
||||
* **-EOPNOTSUPP** if IMA is disabled or **-EINVAL** if
|
||||
* invalid arguments are passed.
|
||||
*
|
||||
* struct socket *bpf_sock_from_file(struct file *file)
|
||||
@@ -5508,7 +5514,7 @@ union bpf_attr {
|
||||
* bytes will be copied to *dst*
|
||||
* Return
|
||||
* The **hash_algo** is returned on success,
|
||||
* **-EOPNOTSUP** if the hash calculation failed or **-EINVAL** if
|
||||
* **-EOPNOTSUPP** if the hash calculation failed or **-EINVAL** if
|
||||
* invalid arguments are passed.
|
||||
*
|
||||
* void *bpf_kptr_xchg(void *map_value, void *ptr)
|
||||
@@ -6720,6 +6726,10 @@ struct bpf_link_info {
|
||||
__u32 ifindex;
|
||||
__u32 attach_type;
|
||||
} netkit;
|
||||
struct {
|
||||
__u32 map_id;
|
||||
__u32 attach_type;
|
||||
} sockmap;
|
||||
};
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
@@ -6938,6 +6948,8 @@ enum {
|
||||
* socket transition to LISTEN state.
|
||||
*/
|
||||
BPF_SOCK_OPS_RTT_CB, /* Called on every RTT.
|
||||
* Arg1: measured RTT input (mrtt)
|
||||
* Arg2: updated srtt
|
||||
*/
|
||||
BPF_SOCK_OPS_PARSE_HDR_OPT_CB, /* Parse the header option.
|
||||
* It will be called to handle
|
||||
@@ -7120,6 +7132,7 @@ enum {
|
||||
BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
|
||||
BPF_FIB_LOOKUP_TBID = (1U << 3),
|
||||
BPF_FIB_LOOKUP_SRC = (1U << 4),
|
||||
BPF_FIB_LOOKUP_MARK = (1U << 5),
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -7152,7 +7165,7 @@ struct bpf_fib_lookup {
|
||||
|
||||
/* output: MTU value */
|
||||
__u16 mtu_result;
|
||||
};
|
||||
} __attribute__((packed, aligned(2)));
|
||||
/* input: L3 device index for lookup
|
||||
* output: device index from FIB lookup
|
||||
*/
|
||||
@@ -7197,8 +7210,19 @@ struct bpf_fib_lookup {
|
||||
__u32 tbid;
|
||||
};
|
||||
|
||||
__u8 smac[6]; /* ETH_ALEN */
|
||||
__u8 dmac[6]; /* ETH_ALEN */
|
||||
union {
|
||||
/* input */
|
||||
struct {
|
||||
__u32 mark; /* policy routing */
|
||||
/* 2 4-byte holes for input */
|
||||
};
|
||||
|
||||
/* output: source and dest mac */
|
||||
struct {
|
||||
__u8 smac[6]; /* ETH_ALEN */
|
||||
__u8 dmac[6]; /* ETH_ALEN */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct bpf_redir_neigh {
|
||||
@@ -7285,6 +7309,10 @@ struct bpf_timer {
|
||||
__u64 __opaque[2];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct bpf_wq {
|
||||
__u64 __opaque[2];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct bpf_dynptr {
|
||||
__u64 __opaque[2];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
37
scripts/mailmap-update.sh
Executable file
37
scripts/mailmap-update.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
|
||||
usage () {
|
||||
echo "USAGE: ./mailmap-update.sh <libbpf-repo> <linux-repo>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
LIBBPF_REPO="${1-""}"
|
||||
LINUX_REPO="${2-""}"
|
||||
|
||||
if [ -z "${LIBBPF_REPO}" ] || [ -z "${LINUX_REPO}" ]; then
|
||||
echo "Error: libbpf or linux repos are not specified"
|
||||
usage
|
||||
fi
|
||||
|
||||
LIBBPF_MAILMAP="${LIBBPF_REPO}/.mailmap"
|
||||
LINUX_MAILMAP="${LINUX_REPO}/.mailmap"
|
||||
|
||||
tmpfile="$(mktemp)"
|
||||
cleanup() {
|
||||
rm -f "${tmpfile}"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
grep_lines() {
|
||||
local pattern="$1"
|
||||
local file="$2"
|
||||
grep "${pattern}" "${file}" || true
|
||||
}
|
||||
|
||||
while read -r email; do
|
||||
grep_lines "${email}$" "${LINUX_MAILMAP}" >> "${tmpfile}"
|
||||
done < <(git log --format='<%ae>' | sort -u)
|
||||
|
||||
sort -u "${tmpfile}" > "${LIBBPF_MAILMAP}"
|
||||
@@ -295,6 +295,22 @@ Latest changes to BPF helper definitions.
|
||||
" -- src/bpf_helper_defs.h
|
||||
fi
|
||||
|
||||
echo "Regenerating .mailmap..."
|
||||
cd_to "${LINUX_REPO}"
|
||||
git checkout "${TIP_SYM_REF}"
|
||||
cd_to "${LIBBPF_REPO}"
|
||||
"${LIBBPF_REPO}"/scripts/mailmap-update.sh "${LIBBPF_REPO}" "${LINUX_REPO}"
|
||||
# if anything changed, commit it
|
||||
mailmap_changes=$(git status --porcelain .mailmap | wc -l)
|
||||
if ((${mailmap_changes} == 1)); then
|
||||
git add .mailmap
|
||||
git commit -s -m "sync: update .mailmap
|
||||
|
||||
Update .mailmap based on libbpf's list of contributors and on the latest
|
||||
.mailmap version in the upstream repository.
|
||||
" -- .mailmap
|
||||
fi
|
||||
|
||||
# Use generated cover-letter as a template for "sync commit" with
|
||||
# baseline and checkpoint commits from kernel repo (and leave summary
|
||||
# from cover letter intact, of course)
|
||||
|
||||
@@ -9,7 +9,7 @@ else
|
||||
endif
|
||||
|
||||
LIBBPF_MAJOR_VERSION := 1
|
||||
LIBBPF_MINOR_VERSION := 4
|
||||
LIBBPF_MINOR_VERSION := 5
|
||||
LIBBPF_PATCH_VERSION := 0
|
||||
LIBBPF_VERSION := $(LIBBPF_MAJOR_VERSION).$(LIBBPF_MINOR_VERSION).$(LIBBPF_PATCH_VERSION)
|
||||
LIBBPF_MAJMIN_VERSION := $(LIBBPF_MAJOR_VERSION).$(LIBBPF_MINOR_VERSION).0
|
||||
|
||||
@@ -766,6 +766,7 @@ int bpf_link_create(int prog_fd, int target_fd,
|
||||
return libbpf_err(-EINVAL);
|
||||
break;
|
||||
case BPF_TRACE_KPROBE_MULTI:
|
||||
case BPF_TRACE_KPROBE_SESSION:
|
||||
attr.link_create.kprobe_multi.flags = OPTS_GET(opts, kprobe_multi.flags, 0);
|
||||
attr.link_create.kprobe_multi.cnt = OPTS_GET(opts, kprobe_multi.cnt, 0);
|
||||
attr.link_create.kprobe_multi.syms = ptr_to_u64(OPTS_GET(opts, kprobe_multi.syms, 0));
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#ifndef __BPF_CORE_READ_H__
|
||||
#define __BPF_CORE_READ_H__
|
||||
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include "bpf_helpers.h"
|
||||
|
||||
/*
|
||||
* enum bpf_field_info_kind is passed as a second argument into
|
||||
|
||||
@@ -1851,6 +1851,10 @@ static long (* const bpf_skb_load_bytes_relative)(const void *skb, __u32 offset,
|
||||
* for the nexthop. If the src addr cannot be derived,
|
||||
* **BPF_FIB_LKUP_RET_NO_SRC_ADDR** is returned. In this
|
||||
* case, *params*->dmac and *params*->smac are not set either.
|
||||
* **BPF_FIB_LOOKUP_MARK**
|
||||
* Use the mark present in *params*->mark for the fib lookup.
|
||||
* This option should not be used with BPF_FIB_LOOKUP_DIRECT,
|
||||
* as it only has meaning for full lookups.
|
||||
*
|
||||
* *ctx* is either **struct xdp_md** for XDP programs or
|
||||
* **struct sk_buff** tc cls_act programs.
|
||||
@@ -3798,7 +3802,7 @@ static __u64 (* const bpf_ktime_get_coarse_ns)(void) = (void *) 160;
|
||||
*
|
||||
* Returns
|
||||
* The **hash_algo** is returned on success,
|
||||
* **-EOPNOTSUP** if IMA is disabled or **-EINVAL** if
|
||||
* **-EOPNOTSUPP** if IMA is disabled or **-EINVAL** if
|
||||
* invalid arguments are passed.
|
||||
*/
|
||||
static long (* const bpf_ima_inode_hash)(struct inode *inode, void *dst, __u32 size) = (void *) 161;
|
||||
@@ -4412,7 +4416,7 @@ static long (* const bpf_skb_set_tstamp)(struct __sk_buff *skb, __u64 tstamp, __
|
||||
*
|
||||
* Returns
|
||||
* The **hash_algo** is returned on success,
|
||||
* **-EOPNOTSUP** if the hash calculation failed or **-EINVAL** if
|
||||
* **-EOPNOTSUPP** if the hash calculation failed or **-EINVAL** if
|
||||
* invalid arguments are passed.
|
||||
*/
|
||||
static long (* const bpf_ima_file_hash)(struct file *file, void *dst, __u32 size) = (void *) 193;
|
||||
|
||||
@@ -137,7 +137,8 @@
|
||||
/*
|
||||
* Helper function to perform a tail call with a constant/immediate map slot.
|
||||
*/
|
||||
#if __clang_major__ >= 8 && defined(__bpf__)
|
||||
#if (defined(__clang__) && __clang_major__ >= 8) || (!defined(__clang__) && __GNUC__ > 12)
|
||||
#if defined(__bpf__)
|
||||
static __always_inline void
|
||||
bpf_tail_call_static(void *ctx, const void *map, const __u32 slot)
|
||||
{
|
||||
@@ -165,6 +166,7 @@ bpf_tail_call_static(void *ctx, const void *map, const __u32 slot)
|
||||
: "r0", "r1", "r2", "r3", "r4", "r5");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum libbpf_pin_type {
|
||||
LIBBPF_PIN_NONE,
|
||||
|
||||
@@ -1929,6 +1929,7 @@ static int btf_dump_int_data(struct btf_dump *d,
|
||||
if (d->typed_dump->is_array_terminated)
|
||||
break;
|
||||
if (*(char *)data == '\0') {
|
||||
btf_dump_type_values(d, "'\\0'");
|
||||
d->typed_dump->is_array_terminated = true;
|
||||
break;
|
||||
}
|
||||
@@ -2031,6 +2032,7 @@ static int btf_dump_array_data(struct btf_dump *d,
|
||||
__u32 i, elem_type_id;
|
||||
__s64 elem_size;
|
||||
bool is_array_member;
|
||||
bool is_array_terminated;
|
||||
|
||||
elem_type_id = array->type;
|
||||
elem_type = skip_mods_and_typedefs(d->btf, elem_type_id, NULL);
|
||||
@@ -2066,12 +2068,15 @@ static int btf_dump_array_data(struct btf_dump *d,
|
||||
*/
|
||||
is_array_member = d->typed_dump->is_array_member;
|
||||
d->typed_dump->is_array_member = true;
|
||||
is_array_terminated = d->typed_dump->is_array_terminated;
|
||||
d->typed_dump->is_array_terminated = false;
|
||||
for (i = 0; i < array->nelems; i++, data += elem_size) {
|
||||
if (d->typed_dump->is_array_terminated)
|
||||
break;
|
||||
btf_dump_dump_type_data(d, NULL, elem_type, elem_type_id, data, 0, 0);
|
||||
}
|
||||
d->typed_dump->is_array_member = is_array_member;
|
||||
d->typed_dump->is_array_terminated = is_array_terminated;
|
||||
d->typed_dump->depth--;
|
||||
btf_dump_data_pfx(d);
|
||||
btf_dump_type_values(d, "]");
|
||||
|
||||
144
src/libbpf.c
144
src/libbpf.c
@@ -132,6 +132,7 @@ static const char * const attach_type_name[] = {
|
||||
[BPF_TRACE_UPROBE_MULTI] = "trace_uprobe_multi",
|
||||
[BPF_NETKIT_PRIMARY] = "netkit_primary",
|
||||
[BPF_NETKIT_PEER] = "netkit_peer",
|
||||
[BPF_TRACE_KPROBE_SESSION] = "trace_kprobe_session",
|
||||
};
|
||||
|
||||
static const char * const link_type_name[] = {
|
||||
@@ -149,6 +150,7 @@ static const char * const link_type_name[] = {
|
||||
[BPF_LINK_TYPE_TCX] = "tcx",
|
||||
[BPF_LINK_TYPE_UPROBE_MULTI] = "uprobe_multi",
|
||||
[BPF_LINK_TYPE_NETKIT] = "netkit",
|
||||
[BPF_LINK_TYPE_SOCKMAP] = "sockmap",
|
||||
};
|
||||
|
||||
static const char * const map_type_name[] = {
|
||||
@@ -1126,6 +1128,7 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
|
||||
const struct btf_type *mtype, *kern_mtype;
|
||||
__u32 mtype_id, kern_mtype_id;
|
||||
void *mdata, *kern_mdata;
|
||||
struct bpf_program *prog;
|
||||
__s64 msize, kern_msize;
|
||||
__u32 moff, kern_moff;
|
||||
__u32 kern_member_idx;
|
||||
@@ -1143,18 +1146,35 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
|
||||
|
||||
kern_member = find_member_by_name(kern_btf, kern_type, mname);
|
||||
if (!kern_member) {
|
||||
/* Skip all zeros or null fields if they are not
|
||||
* presented in the kernel BTF.
|
||||
*/
|
||||
if (libbpf_is_mem_zeroed(mdata, msize)) {
|
||||
pr_info("struct_ops %s: member %s not found in kernel, skipping it as it's set to zero\n",
|
||||
if (!libbpf_is_mem_zeroed(mdata, msize)) {
|
||||
pr_warn("struct_ops init_kern %s: Cannot find member %s in kernel BTF\n",
|
||||
map->name, mname);
|
||||
continue;
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
pr_warn("struct_ops init_kern %s: Cannot find member %s in kernel BTF\n",
|
||||
prog = st_ops->progs[i];
|
||||
if (prog) {
|
||||
/* If we had declaratively set struct_ops callback, we need to
|
||||
* first validate that it's actually a struct_ops program.
|
||||
* And then force its autoload to false, because it doesn't have
|
||||
* a chance of succeeding from POV of the current struct_ops map.
|
||||
* If this program is still referenced somewhere else, though,
|
||||
* then bpf_object_adjust_struct_ops_autoload() will update its
|
||||
* autoload accordingly.
|
||||
*/
|
||||
if (!is_valid_st_ops_program(obj, prog)) {
|
||||
pr_warn("struct_ops init_kern %s: member %s is declaratively assigned a non-struct_ops program\n",
|
||||
map->name, mname);
|
||||
return -EINVAL;
|
||||
}
|
||||
prog->autoload = false;
|
||||
st_ops->progs[i] = NULL;
|
||||
}
|
||||
|
||||
/* Skip all-zero/NULL fields if they are not present in the kernel BTF */
|
||||
pr_info("struct_ops %s: member %s not found in kernel, skipping it as it's set to zero\n",
|
||||
map->name, mname);
|
||||
return -ENOTSUP;
|
||||
continue;
|
||||
}
|
||||
|
||||
kern_member_idx = kern_member - btf_members(kern_type);
|
||||
@@ -1180,8 +1200,6 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
|
||||
}
|
||||
|
||||
if (btf_is_ptr(mtype)) {
|
||||
struct bpf_program *prog;
|
||||
|
||||
/* Update the value from the shadow type */
|
||||
prog = *(void **)mdata;
|
||||
st_ops->progs[i] = prog;
|
||||
@@ -1970,6 +1988,20 @@ static struct extern_desc *find_extern_by_name(const struct bpf_object *obj,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct extern_desc *find_extern_by_name_with_len(const struct bpf_object *obj,
|
||||
const void *name, int len)
|
||||
{
|
||||
const char *ext_name;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < obj->nr_extern; i++) {
|
||||
ext_name = obj->externs[i].name;
|
||||
if (strlen(ext_name) == len && strncmp(ext_name, name, len) == 0)
|
||||
return &obj->externs[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int set_kcfg_value_tri(struct extern_desc *ext, void *ext_val,
|
||||
char value)
|
||||
{
|
||||
@@ -7986,7 +8018,10 @@ static int bpf_object__sanitize_maps(struct bpf_object *obj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *ctx)
|
||||
typedef int (*kallsyms_cb_t)(unsigned long long sym_addr, char sym_type,
|
||||
const char *sym_name, void *ctx);
|
||||
|
||||
static int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *ctx)
|
||||
{
|
||||
char sym_type, sym_name[500];
|
||||
unsigned long long sym_addr;
|
||||
@@ -8026,8 +8061,13 @@ static int kallsyms_cb(unsigned long long sym_addr, char sym_type,
|
||||
struct bpf_object *obj = ctx;
|
||||
const struct btf_type *t;
|
||||
struct extern_desc *ext;
|
||||
char *res;
|
||||
|
||||
ext = find_extern_by_name(obj, sym_name);
|
||||
res = strstr(sym_name, ".llvm.");
|
||||
if (sym_type == 'd' && res)
|
||||
ext = find_extern_by_name_with_len(obj, sym_name, res - sym_name);
|
||||
else
|
||||
ext = find_extern_by_name(obj, sym_name);
|
||||
if (!ext || ext->type != EXT_KSYM)
|
||||
return 0;
|
||||
|
||||
@@ -9249,6 +9289,7 @@ static int attach_tp(const struct bpf_program *prog, long cookie, struct bpf_lin
|
||||
static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||
static int attach_trace(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||
static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||
static int attach_kprobe_session(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||
static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||
static int attach_lsm(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||
static int attach_iter(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||
@@ -9265,6 +9306,7 @@ static const struct bpf_sec_def section_defs[] = {
|
||||
SEC_DEF("uretprobe.s+", KPROBE, 0, SEC_SLEEPABLE, attach_uprobe),
|
||||
SEC_DEF("kprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
|
||||
SEC_DEF("kretprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
|
||||
SEC_DEF("kprobe.session+", KPROBE, BPF_TRACE_KPROBE_SESSION, SEC_NONE, attach_kprobe_session),
|
||||
SEC_DEF("uprobe.multi+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi),
|
||||
SEC_DEF("uretprobe.multi+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi),
|
||||
SEC_DEF("uprobe.multi.s+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_SLEEPABLE, attach_uprobe_multi),
|
||||
@@ -9835,16 +9877,28 @@ static int find_kernel_btf_id(struct bpf_object *obj, const char *attach_name,
|
||||
enum bpf_attach_type attach_type,
|
||||
int *btf_obj_fd, int *btf_type_id)
|
||||
{
|
||||
int ret, i;
|
||||
int ret, i, mod_len;
|
||||
const char *fn_name, *mod_name = NULL;
|
||||
|
||||
ret = find_attach_btf_id(obj->btf_vmlinux, attach_name, attach_type);
|
||||
if (ret > 0) {
|
||||
*btf_obj_fd = 0; /* vmlinux BTF */
|
||||
*btf_type_id = ret;
|
||||
return 0;
|
||||
fn_name = strchr(attach_name, ':');
|
||||
if (fn_name) {
|
||||
mod_name = attach_name;
|
||||
mod_len = fn_name - mod_name;
|
||||
fn_name++;
|
||||
}
|
||||
|
||||
if (!mod_name || strncmp(mod_name, "vmlinux", mod_len) == 0) {
|
||||
ret = find_attach_btf_id(obj->btf_vmlinux,
|
||||
mod_name ? fn_name : attach_name,
|
||||
attach_type);
|
||||
if (ret > 0) {
|
||||
*btf_obj_fd = 0; /* vmlinux BTF */
|
||||
*btf_type_id = ret;
|
||||
return 0;
|
||||
}
|
||||
if (ret != -ENOENT)
|
||||
return ret;
|
||||
}
|
||||
if (ret != -ENOENT)
|
||||
return ret;
|
||||
|
||||
ret = load_module_btfs(obj);
|
||||
if (ret)
|
||||
@@ -9853,7 +9907,12 @@ static int find_kernel_btf_id(struct bpf_object *obj, const char *attach_name,
|
||||
for (i = 0; i < obj->btf_module_cnt; i++) {
|
||||
const struct module_btf *mod = &obj->btf_modules[i];
|
||||
|
||||
ret = find_attach_btf_id(mod->btf, attach_name, attach_type);
|
||||
if (mod_name && strncmp(mod->name, mod_name, mod_len) != 0)
|
||||
continue;
|
||||
|
||||
ret = find_attach_btf_id(mod->btf,
|
||||
mod_name ? fn_name : attach_name,
|
||||
attach_type);
|
||||
if (ret > 0) {
|
||||
*btf_obj_fd = mod->fd;
|
||||
*btf_type_id = ret;
|
||||
@@ -11357,13 +11416,14 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
||||
struct kprobe_multi_resolve res = {
|
||||
.pattern = pattern,
|
||||
};
|
||||
enum bpf_attach_type attach_type;
|
||||
struct bpf_link *link = NULL;
|
||||
char errmsg[STRERR_BUFSIZE];
|
||||
const unsigned long *addrs;
|
||||
int err, link_fd, prog_fd;
|
||||
bool retprobe, session;
|
||||
const __u64 *cookies;
|
||||
const char **syms;
|
||||
bool retprobe;
|
||||
size_t cnt;
|
||||
|
||||
if (!OPTS_VALID(opts, bpf_kprobe_multi_opts))
|
||||
@@ -11402,6 +11462,12 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
||||
}
|
||||
|
||||
retprobe = OPTS_GET(opts, retprobe, false);
|
||||
session = OPTS_GET(opts, session, false);
|
||||
|
||||
if (retprobe && session)
|
||||
return libbpf_err_ptr(-EINVAL);
|
||||
|
||||
attach_type = session ? BPF_TRACE_KPROBE_SESSION : BPF_TRACE_KPROBE_MULTI;
|
||||
|
||||
lopts.kprobe_multi.syms = syms;
|
||||
lopts.kprobe_multi.addrs = addrs;
|
||||
@@ -11416,7 +11482,7 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
||||
}
|
||||
link->detach = &bpf_link__detach_fd;
|
||||
|
||||
link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, &lopts);
|
||||
link_fd = bpf_link_create(prog_fd, 0, attach_type, &lopts);
|
||||
if (link_fd < 0) {
|
||||
err = -errno;
|
||||
pr_warn("prog '%s': failed to attach: %s\n",
|
||||
@@ -11522,6 +11588,32 @@ static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, stru
|
||||
return libbpf_get_error(*link);
|
||||
}
|
||||
|
||||
static int attach_kprobe_session(const struct bpf_program *prog, long cookie,
|
||||
struct bpf_link **link)
|
||||
{
|
||||
LIBBPF_OPTS(bpf_kprobe_multi_opts, opts, .session = true);
|
||||
const char *spec;
|
||||
char *pattern;
|
||||
int n;
|
||||
|
||||
*link = NULL;
|
||||
|
||||
/* no auto-attach for SEC("kprobe.session") */
|
||||
if (strcmp(prog->sec_name, "kprobe.session") == 0)
|
||||
return 0;
|
||||
|
||||
spec = prog->sec_name + sizeof("kprobe.session/") - 1;
|
||||
n = sscanf(spec, "%m[a-zA-Z0-9_.*?]", &pattern);
|
||||
if (n < 1) {
|
||||
pr_warn("kprobe session pattern is invalid: %s\n", pattern);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*link = bpf_program__attach_kprobe_multi_opts(prog, pattern, &opts);
|
||||
free(pattern);
|
||||
return *link ? 0 : -errno;
|
||||
}
|
||||
|
||||
static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link)
|
||||
{
|
||||
char *probe_type = NULL, *binary_path = NULL, *func_name = NULL;
|
||||
@@ -12511,6 +12603,12 @@ bpf_program__attach_netns(const struct bpf_program *prog, int netns_fd)
|
||||
return bpf_program_attach_fd(prog, netns_fd, "netns", NULL);
|
||||
}
|
||||
|
||||
struct bpf_link *
|
||||
bpf_program__attach_sockmap(const struct bpf_program *prog, int map_fd)
|
||||
{
|
||||
return bpf_program_attach_fd(prog, map_fd, "sockmap", NULL);
|
||||
}
|
||||
|
||||
struct bpf_link *bpf_program__attach_xdp(const struct bpf_program *prog, int ifindex)
|
||||
{
|
||||
/* target_fd/target_ifindex use the same field in LINK_CREATE */
|
||||
|
||||
18
src/libbpf.h
18
src/libbpf.h
@@ -539,10 +539,12 @@ struct bpf_kprobe_multi_opts {
|
||||
size_t cnt;
|
||||
/* create return kprobes */
|
||||
bool retprobe;
|
||||
/* create session kprobes */
|
||||
bool session;
|
||||
size_t :0;
|
||||
};
|
||||
|
||||
#define bpf_kprobe_multi_opts__last_field retprobe
|
||||
#define bpf_kprobe_multi_opts__last_field session
|
||||
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
||||
@@ -795,6 +797,8 @@ bpf_program__attach_cgroup(const struct bpf_program *prog, int cgroup_fd);
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_netns(const struct bpf_program *prog, int netns_fd);
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_sockmap(const struct bpf_program *prog, int map_fd);
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_xdp(const struct bpf_program *prog, int ifindex);
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_freplace(const struct bpf_program *prog,
|
||||
@@ -1293,6 +1297,7 @@ LIBBPF_API int ring_buffer__add(struct ring_buffer *rb, int map_fd,
|
||||
ring_buffer_sample_fn sample_cb, void *ctx);
|
||||
LIBBPF_API int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms);
|
||||
LIBBPF_API int ring_buffer__consume(struct ring_buffer *rb);
|
||||
LIBBPF_API int ring_buffer__consume_n(struct ring_buffer *rb, size_t n);
|
||||
LIBBPF_API int ring_buffer__epoll_fd(const struct ring_buffer *rb);
|
||||
|
||||
/**
|
||||
@@ -1367,6 +1372,17 @@ LIBBPF_API int ring__map_fd(const struct ring *r);
|
||||
*/
|
||||
LIBBPF_API int ring__consume(struct ring *r);
|
||||
|
||||
/**
|
||||
* @brief **ring__consume_n()** consumes up to a requested amount of items from
|
||||
* a ringbuffer without event polling.
|
||||
*
|
||||
* @param r A ringbuffer object.
|
||||
* @param n Maximum amount of items to consume.
|
||||
* @return The number of items consumed, or a negative number if any of the
|
||||
* callbacks return an error.
|
||||
*/
|
||||
LIBBPF_API int ring__consume_n(struct ring *r, size_t n);
|
||||
|
||||
struct user_ring_buffer_opts {
|
||||
size_t sz; /* size of this struct, for forward/backward compatibility */
|
||||
};
|
||||
|
||||
@@ -416,3 +416,10 @@ LIBBPF_1.4.0 {
|
||||
btf__new_split;
|
||||
btf_ext__raw_data;
|
||||
} LIBBPF_1.3.0;
|
||||
|
||||
LIBBPF_1.5.0 {
|
||||
global:
|
||||
bpf_program__attach_sockmap;
|
||||
ring__consume_n;
|
||||
ring_buffer__consume_n;
|
||||
} LIBBPF_1.4.0;
|
||||
|
||||
@@ -518,11 +518,6 @@ int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void
|
||||
__s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name,
|
||||
__u32 kind);
|
||||
|
||||
typedef int (*kallsyms_cb_t)(unsigned long long sym_addr, char sym_type,
|
||||
const char *sym_name, void *ctx);
|
||||
|
||||
int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *arg);
|
||||
|
||||
/* handle direct returned errors */
|
||||
static inline int libbpf_err(int ret)
|
||||
{
|
||||
|
||||
@@ -98,7 +98,7 @@ __u32 get_kernel_version(void)
|
||||
return 0;
|
||||
|
||||
if (major == 4 && minor == 19 && patch > 255)
|
||||
return KERNEL_VERSION(major, minor, 255);
|
||||
return KERNEL_VERSION(major, minor, 255);;
|
||||
|
||||
return KERNEL_VERSION(major, minor, patch);
|
||||
}
|
||||
@@ -451,7 +451,8 @@ int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helpe
|
||||
/* If BPF verifier doesn't recognize BPF helper ID (enum bpf_func_id)
|
||||
* at all, it will emit something like "invalid func unknown#181".
|
||||
* If BPF verifier recognizes BPF helper but it's not supported for
|
||||
* given BPF program type, it will emit "unknown func bpf_sys_bpf#166".
|
||||
* given BPF program type, it will emit "unknown func bpf_sys_bpf#166"
|
||||
* or "program of this type cannot use helper bpf_sys_bpf#166".
|
||||
* In both cases, provided combination of BPF program type and BPF
|
||||
* helper is not supported by the kernel.
|
||||
* In all other cases, probe_prog_load() above will either succeed (e.g.,
|
||||
@@ -460,7 +461,8 @@ int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helpe
|
||||
* that), or we'll get some more specific BPF verifier error about
|
||||
* some unsatisfied conditions.
|
||||
*/
|
||||
if (ret == 0 && (strstr(buf, "invalid func ") || strstr(buf, "unknown func ")))
|
||||
if (ret == 0 && (strstr(buf, "invalid func ") || strstr(buf, "unknown func ") ||
|
||||
strstr(buf, "program of this type cannot use helper ")))
|
||||
return 0;
|
||||
return 1; /* assume supported */
|
||||
}
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
#define __LIBBPF_VERSION_H
|
||||
|
||||
#define LIBBPF_MAJOR_VERSION 1
|
||||
#define LIBBPF_MINOR_VERSION 4
|
||||
#define LIBBPF_MINOR_VERSION 5
|
||||
|
||||
#endif /* __LIBBPF_VERSION_H */
|
||||
|
||||
@@ -231,7 +231,7 @@ static inline int roundup_len(__u32 len)
|
||||
return (len + 7) / 8 * 8;
|
||||
}
|
||||
|
||||
static int64_t ringbuf_process_ring(struct ring *r)
|
||||
static int64_t ringbuf_process_ring(struct ring *r, size_t n)
|
||||
{
|
||||
int *len_ptr, len, err;
|
||||
/* 64-bit to avoid overflow in case of extreme application behavior */
|
||||
@@ -268,12 +268,42 @@ static int64_t ringbuf_process_ring(struct ring *r)
|
||||
}
|
||||
|
||||
smp_store_release(r->consumer_pos, cons_pos);
|
||||
|
||||
if (cnt >= n)
|
||||
goto done;
|
||||
}
|
||||
} while (got_new_data);
|
||||
done:
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/* Consume available ring buffer(s) data without event polling, up to n
|
||||
* records.
|
||||
*
|
||||
* Returns number of records consumed across all registered ring buffers (or
|
||||
* n, whichever is less), or negative number if any of the callbacks return
|
||||
* error.
|
||||
*/
|
||||
int ring_buffer__consume_n(struct ring_buffer *rb, size_t n)
|
||||
{
|
||||
int64_t err, res = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rb->ring_cnt; i++) {
|
||||
struct ring *ring = rb->rings[i];
|
||||
|
||||
err = ringbuf_process_ring(ring, n);
|
||||
if (err < 0)
|
||||
return libbpf_err(err);
|
||||
res += err;
|
||||
n -= err;
|
||||
|
||||
if (n == 0)
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Consume available ring buffer(s) data without event polling.
|
||||
* Returns number of records consumed across all registered ring buffers (or
|
||||
* INT_MAX, whichever is less), or negative number if any of the callbacks
|
||||
@@ -287,13 +317,15 @@ int ring_buffer__consume(struct ring_buffer *rb)
|
||||
for (i = 0; i < rb->ring_cnt; i++) {
|
||||
struct ring *ring = rb->rings[i];
|
||||
|
||||
err = ringbuf_process_ring(ring);
|
||||
err = ringbuf_process_ring(ring, INT_MAX);
|
||||
if (err < 0)
|
||||
return libbpf_err(err);
|
||||
res += err;
|
||||
if (res > INT_MAX) {
|
||||
res = INT_MAX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (res > INT_MAX)
|
||||
return INT_MAX;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -314,13 +346,13 @@ int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms)
|
||||
__u32 ring_id = rb->events[i].data.fd;
|
||||
struct ring *ring = rb->rings[ring_id];
|
||||
|
||||
err = ringbuf_process_ring(ring);
|
||||
err = ringbuf_process_ring(ring, INT_MAX);
|
||||
if (err < 0)
|
||||
return libbpf_err(err);
|
||||
res += err;
|
||||
}
|
||||
if (res > INT_MAX)
|
||||
return INT_MAX;
|
||||
res = INT_MAX;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -371,17 +403,22 @@ int ring__map_fd(const struct ring *r)
|
||||
return r->map_fd;
|
||||
}
|
||||
|
||||
int ring__consume(struct ring *r)
|
||||
int ring__consume_n(struct ring *r, size_t n)
|
||||
{
|
||||
int64_t res;
|
||||
int res;
|
||||
|
||||
res = ringbuf_process_ring(r);
|
||||
res = ringbuf_process_ring(r, n);
|
||||
if (res < 0)
|
||||
return libbpf_err(res);
|
||||
|
||||
return res > INT_MAX ? INT_MAX : res;
|
||||
}
|
||||
|
||||
int ring__consume(struct ring *r)
|
||||
{
|
||||
return ring__consume_n(r, INT_MAX);
|
||||
}
|
||||
|
||||
static void user_ringbuf_unmap_ring(struct user_ring_buffer *rb)
|
||||
{
|
||||
if (rb->consumer_pos) {
|
||||
|
||||
Reference in New Issue
Block a user