mirror of
https://github.com/netdata/libbpf.git
synced 2026-03-21 00:39:07 +08:00
Compare commits
1 Commits
v1.4.1p_ne
...
netdata_pa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
252dca2412 |
@@ -1,5 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
printf "all:\n\ttouch bpf_testmod.ko\n\nclean:\n" > bpf_testmod/Makefile
|
printf "all:\n\ttouch bpf_testmod.ko\n\nclean:\n" > bpf_testmod/Makefile
|
||||||
printf "all:\n\ttouch bpf_test_no_cfi.ko\n\nclean:\n" > bpf_test_no_cfi/Makefile
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
printf "all:\n\ttouch bpf_testmod.ko\n\nclean:\n" > bpf_testmod/Makefile
|
printf "all:\n\ttouch bpf_testmod.ko\n\nclean:\n" > bpf_testmod/Makefile
|
||||||
printf "all:\n\ttouch bpf_test_no_cfi.ko\n\nclean:\n" > bpf_test_no_cfi/Makefile
|
|
||||||
|
|
||||||
|
|||||||
162098
.github/actions/build-selftests/vmlinux.h
vendored
162098
.github/actions/build-selftests/vmlinux.h
vendored
File diff suppressed because it is too large
Load Diff
1
.github/actions/vmtest/action.yml
vendored
1
.github/actions/vmtest/action.yml
vendored
@@ -37,7 +37,6 @@ runs:
|
|||||||
uses: libbpf/ci/setup-build-env@main
|
uses: libbpf/ci/setup-build-env@main
|
||||||
with:
|
with:
|
||||||
pahole: ${{ inputs.pahole }}
|
pahole: ${{ inputs.pahole }}
|
||||||
arch: ${{ inputs.arch }}
|
|
||||||
# 1. download CHECKPOINT kernel source
|
# 1. download CHECKPOINT kernel source
|
||||||
- name: Get checkpoint commit
|
- name: Get checkpoint commit
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
|||||||
- name: gcc-12
|
- name: gcc-12
|
||||||
target: RUN_GCC12
|
target: RUN_GCC12
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
name: Checkout
|
name: Checkout
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
name: Setup
|
name: Setup
|
||||||
@@ -63,14 +63,14 @@ jobs:
|
|||||||
- arch: s390x
|
- arch: s390x
|
||||||
- arch: x86
|
- arch: x86
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
name: Checkout
|
name: Checkout
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
name: Pre-Setup
|
name: Pre-Setup
|
||||||
- run: source /tmp/ci_setup && sudo -E $CI_ROOT/managers/ubuntu.sh
|
- run: source /tmp/ci_setup && sudo -E $CI_ROOT/managers/ubuntu.sh
|
||||||
if: matrix.arch == 'x86'
|
if: matrix.arch == 'x86'
|
||||||
name: Setup
|
name: Setup
|
||||||
- uses: uraimo/run-on-arch-action@v2.7.1
|
- uses: uraimo/run-on-arch-action@v2.0.5
|
||||||
name: Build in docker
|
name: Build in docker
|
||||||
if: matrix.arch != 'x86'
|
if: matrix.arch != 'x86'
|
||||||
with:
|
with:
|
||||||
|
|||||||
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v2
|
||||||
|
|||||||
2
.github/workflows/coverity.yml
vendored
2
.github/workflows/coverity.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
if: github.repository == 'libbpf/libbpf'
|
if: github.repository == 'libbpf/libbpf'
|
||||||
name: Coverity
|
name: Coverity
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
- name: Run coverity
|
- name: Run coverity
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
- name: Run ShellCheck
|
- name: Run ShellCheck
|
||||||
uses: ludeeus/action-shellcheck@master
|
uses: ludeeus/action-shellcheck@master
|
||||||
env:
|
env:
|
||||||
|
|||||||
2
.github/workflows/ondemand.yml
vendored
2
.github/workflows/ondemand.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: vmtest with customized pahole/Kernel
|
name: vmtest with customized pahole/Kernel
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
- uses: ./.github/actions/vmtest
|
- uses: ./.github/actions/vmtest
|
||||||
with:
|
with:
|
||||||
|
|||||||
2
.github/workflows/pahole.yml
vendored
2
.github/workflows/pahole.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
STAGING: tmp.master
|
STAGING: tmp.master
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
- uses: ./.github/actions/vmtest
|
- uses: ./.github/actions/vmtest
|
||||||
with:
|
with:
|
||||||
|
|||||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
|||||||
runs_on: s390x
|
runs_on: s390x
|
||||||
arch: 's390x'
|
arch: 's390x'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
name: Checkout
|
name: Checkout
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
name: Setup
|
name: Setup
|
||||||
|
|||||||
17
.mailmap
17
.mailmap
@@ -1,17 +0,0 @@
|
|||||||
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 @@
|
|||||||
3e9bc0472b910d4115e16e9c2d684c7757cb6c60
|
7c5e046bdcb2513f9decb3765d8bf92d604279cf
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
0737df6de94661ae55fd3343ce9abec32c687e62
|
98e20e5e13d2811898921f999288be7151a11954
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ Distributions packaging libbpf from this mirror:
|
|||||||
- [Gentoo](https://packages.gentoo.org/packages/dev-libs/libbpf)
|
- [Gentoo](https://packages.gentoo.org/packages/dev-libs/libbpf)
|
||||||
- [Debian](https://packages.debian.org/source/sid/libbpf)
|
- [Debian](https://packages.debian.org/source/sid/libbpf)
|
||||||
- [Arch](https://archlinux.org/packages/core/x86_64/libbpf/)
|
- [Arch](https://archlinux.org/packages/core/x86_64/libbpf/)
|
||||||
- [Ubuntu](https://packages.ubuntu.com/source/jammy/libbpf)
|
- [Ubuntu](https://packages.ubuntu.com/source/impish/libbpf)
|
||||||
- [Alpine](https://pkgs.alpinelinux.org/packages?name=libbpf)
|
- [Alpine](https://pkgs.alpinelinux.org/packages?name=libbpf)
|
||||||
|
|
||||||
Benefits of packaging from the mirror over packaging from kernel sources:
|
Benefits of packaging from the mirror over packaging from kernel sources:
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
From 61e8893a1e32ab57d15974427f41b75de608dbda Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrii Nakryiko <andrii@kernel.org>
|
||||||
|
Date: Mon, 4 Dec 2023 21:21:23 -0800
|
||||||
|
Subject: [PATCH] bpf: patch out BPF_F_TEST_REG_INVARIANTS for old kernels
|
||||||
|
|
||||||
|
CI-only patch to avoid setting BPF_F_TEST_REG_INVARIANTS flag for old
|
||||||
|
kernels that don't support it.
|
||||||
|
|
||||||
|
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
|
||||||
|
---
|
||||||
|
tools/include/uapi/linux/bpf.h | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
|
||||||
|
index e88746ba7d21..8344c9ce60e0 100644
|
||||||
|
--- a/tools/include/uapi/linux/bpf.h
|
||||||
|
+++ b/tools/include/uapi/linux/bpf.h
|
||||||
|
@@ -1201,7 +1201,7 @@ enum bpf_perf_event_type {
|
||||||
|
#define BPF_F_XDP_DEV_BOUND_ONLY (1U << 6)
|
||||||
|
|
||||||
|
/* The verifier internal test flag. Behavior is undefined */
|
||||||
|
-#define BPF_F_TEST_REG_INVARIANTS (1U << 7)
|
||||||
|
+#define BPF_F_TEST_REG_INVARIANTS (0)
|
||||||
|
|
||||||
|
/* link_create.kprobe_multi.flags used in LINK_CREATE command for
|
||||||
|
* BPF_TRACE_KPROBE_MULTI attach type to create return probe.
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
From fe69a1b1b6ed9ffc2c578c63f526026a8ab74f0c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anders Roxell <anders.roxell@linaro.org>
|
||||||
|
Date: Thu, 9 Nov 2023 18:43:28 +0100
|
||||||
|
Subject: [PATCH] selftests: bpf: xskxceiver: ksft_print_msg: fix format type
|
||||||
|
error
|
||||||
|
|
||||||
|
Crossbuilding selftests/bpf for architecture arm64, format specifies
|
||||||
|
type error show up like.
|
||||||
|
|
||||||
|
xskxceiver.c:912:34: error: format specifies type 'int' but the argument
|
||||||
|
has type '__u64' (aka 'unsigned long long') [-Werror,-Wformat]
|
||||||
|
ksft_print_msg("[%s] expected meta_count [%d], got meta_count [%d]\n",
|
||||||
|
~~
|
||||||
|
%llu
|
||||||
|
__func__, pkt->pkt_nb, meta->count);
|
||||||
|
^~~~~~~~~~~
|
||||||
|
xskxceiver.c:929:55: error: format specifies type 'unsigned long long' but
|
||||||
|
the argument has type 'u64' (aka 'unsigned long') [-Werror,-Wformat]
|
||||||
|
ksft_print_msg("Frag invalid addr: %llx len: %u\n", addr, len);
|
||||||
|
~~~~ ^~~~
|
||||||
|
|
||||||
|
Fixing the issues by casting to (unsigned long long) and changing the
|
||||||
|
specifiers to be %llu from %d and %u, since with u64s it might be %llx
|
||||||
|
or %lx, depending on architecture.
|
||||||
|
|
||||||
|
Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
|
||||||
|
Link: https://lore.kernel.org/r/20231109174328.1774571-1-anders.roxell@linaro.org
|
||||||
|
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
|
||||||
|
---
|
||||||
|
tools/testing/selftests/bpf/xskxceiver.c | 19 ++++++++++++-------
|
||||||
|
1 file changed, 12 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
|
||||||
|
index 591ca9637b23..b604c570309a 100644
|
||||||
|
--- a/tools/testing/selftests/bpf/xskxceiver.c
|
||||||
|
+++ b/tools/testing/selftests/bpf/xskxceiver.c
|
||||||
|
@@ -908,8 +908,9 @@ static bool is_metadata_correct(struct pkt *pkt, void *buffer, u64 addr)
|
||||||
|
struct xdp_info *meta = data - sizeof(struct xdp_info);
|
||||||
|
|
||||||
|
if (meta->count != pkt->pkt_nb) {
|
||||||
|
- ksft_print_msg("[%s] expected meta_count [%d], got meta_count [%d]\n",
|
||||||
|
- __func__, pkt->pkt_nb, meta->count);
|
||||||
|
+ ksft_print_msg("[%s] expected meta_count [%d], got meta_count [%llu]\n",
|
||||||
|
+ __func__, pkt->pkt_nb,
|
||||||
|
+ (unsigned long long)meta->count);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -926,11 +927,13 @@ static bool is_frag_valid(struct xsk_umem_info *umem, u64 addr, u32 len, u32 exp
|
||||||
|
|
||||||
|
if (addr >= umem->num_frames * umem->frame_size ||
|
||||||
|
addr + len > umem->num_frames * umem->frame_size) {
|
||||||
|
- ksft_print_msg("Frag invalid addr: %llx len: %u\n", addr, len);
|
||||||
|
+ ksft_print_msg("Frag invalid addr: %llx len: %u\n",
|
||||||
|
+ (unsigned long long)addr, len);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!umem->unaligned_mode && addr % umem->frame_size + len > umem->frame_size) {
|
||||||
|
- ksft_print_msg("Frag crosses frame boundary addr: %llx len: %u\n", addr, len);
|
||||||
|
+ ksft_print_msg("Frag crosses frame boundary addr: %llx len: %u\n",
|
||||||
|
+ (unsigned long long)addr, len);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1029,7 +1032,8 @@ static int complete_pkts(struct xsk_socket_info *xsk, int batch_size)
|
||||||
|
u64 addr = *xsk_ring_cons__comp_addr(&xsk->umem->cq, idx + rcvd - 1);
|
||||||
|
|
||||||
|
ksft_print_msg("[%s] Too many packets completed\n", __func__);
|
||||||
|
- ksft_print_msg("Last completion address: %llx\n", addr);
|
||||||
|
+ ksft_print_msg("Last completion address: %llx\n",
|
||||||
|
+ (unsigned long long)addr);
|
||||||
|
return TEST_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1513,8 +1517,9 @@ static int validate_tx_invalid_descs(struct ifobject *ifobject)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.tx_invalid_descs != ifobject->xsk->pkt_stream->nb_pkts / 2) {
|
||||||
|
- ksft_print_msg("[%s] tx_invalid_descs incorrect. Got [%u] expected [%u]\n",
|
||||||
|
- __func__, stats.tx_invalid_descs,
|
||||||
|
+ ksft_print_msg("[%s] tx_invalid_descs incorrect. Got [%llu] expected [%u]\n",
|
||||||
|
+ __func__,
|
||||||
|
+ (unsigned long long)stats.tx_invalid_descs,
|
||||||
|
ifobject->xsk->pkt_stream->nb_pkts);
|
||||||
|
return TEST_FAILURE;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
From f267f262815033452195f46c43b572159262f533 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Borkmann <daniel@iogearbox.net>
|
|
||||||
Date: Tue, 5 Mar 2024 10:08:28 +0100
|
|
||||||
Subject: [PATCH 2/2] xdp, bonding: Fix feature flags when there are no slave
|
|
||||||
devs anymore
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Commit 9b0ed890ac2a ("bonding: do not report NETDEV_XDP_ACT_XSK_ZEROCOPY")
|
|
||||||
changed the driver from reporting everything as supported before a device
|
|
||||||
was bonded into having the driver report that no XDP feature is supported
|
|
||||||
until a real device is bonded as it seems to be more truthful given
|
|
||||||
eventually real underlying devices decide what XDP features are supported.
|
|
||||||
|
|
||||||
The change however did not take into account when all slave devices get
|
|
||||||
removed from the bond device. In this case after 9b0ed890ac2a, the driver
|
|
||||||
keeps reporting a feature mask of 0x77, that is, NETDEV_XDP_ACT_MASK &
|
|
||||||
~NETDEV_XDP_ACT_XSK_ZEROCOPY whereas it should have reported a feature
|
|
||||||
mask of 0.
|
|
||||||
|
|
||||||
Fix it by resetting XDP feature flags in the same way as if no XDP program
|
|
||||||
is attached to the bond device. This was uncovered by the XDP bond selftest
|
|
||||||
which let BPF CI fail. After adjusting the starting masks on the latter
|
|
||||||
to 0 instead of NETDEV_XDP_ACT_MASK the test passes again together with
|
|
||||||
this fix.
|
|
||||||
|
|
||||||
Fixes: 9b0ed890ac2a ("bonding: do not report NETDEV_XDP_ACT_XSK_ZEROCOPY")
|
|
||||||
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
||||||
Cc: Magnus Karlsson <magnus.karlsson@intel.com>
|
|
||||||
Cc: Prashant Batra <prbatra.mail@gmail.com>
|
|
||||||
Cc: Toke Høiland-Jørgensen <toke@redhat.com>
|
|
||||||
Cc: Jakub Kicinski <kuba@kernel.org>
|
|
||||||
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
|
||||||
Message-ID: <20240305090829.17131-1-daniel@iogearbox.net>
|
|
||||||
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
|
|
||||||
---
|
|
||||||
drivers/net/bonding/bond_main.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
|
|
||||||
index a11748b8d69b..cd0683bcca03 100644
|
|
||||||
--- a/drivers/net/bonding/bond_main.c
|
|
||||||
+++ b/drivers/net/bonding/bond_main.c
|
|
||||||
@@ -1811,7 +1811,7 @@ void bond_xdp_set_features(struct net_device *bond_dev)
|
|
||||||
|
|
||||||
ASSERT_RTNL();
|
|
||||||
|
|
||||||
- if (!bond_xdp_check(bond)) {
|
|
||||||
+ if (!bond_xdp_check(bond) || !bond_has_slaves(bond)) {
|
|
||||||
xdp_clear_features_flag(bond_dev);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ task_fd_query_rawtp
|
|||||||
task_fd_query_tp
|
task_fd_query_tp
|
||||||
tc_bpf
|
tc_bpf
|
||||||
tcp_estats
|
tcp_estats
|
||||||
test_global_funcs/arg_tag_ctx*
|
tcp_rtt
|
||||||
tp_attach_query
|
tp_attach_query
|
||||||
usdt/urand_pid_attach
|
usdt/urand_pid_attach
|
||||||
xdp
|
xdp
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
# TEMPORARY
|
|
||||||
btf_dump/btf_dump: syntax
|
|
||||||
kprobe_multi_bench_attach
|
|
||||||
core_reloc/enum64val
|
|
||||||
core_reloc/size___diff_sz
|
|
||||||
core_reloc/type_based___diff_sz
|
|
||||||
test_ima # All of CI is broken on it following 6.3-rc1 merge
|
|
||||||
|
|
||||||
lwt_reroute # crashes kernel after netnext merge from 2ab1efad60ad "net/sched: cls_api: complement tcf_tfilter_dump_policy"
|
|
||||||
tc_links_ingress # started failing after net-next merge from 2ab1efad60ad "net/sched: cls_api: complement tcf_tfilter_dump_policy"
|
|
||||||
xdp_bonding/xdp_bonding_features # started failing after net merge from 359e54a93ab4 "l2tp: pass correct message length to ip6_append_data"
|
|
||||||
tc_redirect/tc_redirect_dtime # uapi breakage after net-next commit 885c36e59f46 ("net: Re-use and set mono_delivery_time bit for userspace tstamp packets")
|
|
||||||
migrate_reuseport/IPv4 TCP_NEW_SYN_RECV reqsk_timer_handler # flaky, under investigation
|
|
||||||
migrate_reuseport/IPv6 TCP_NEW_SYN_RECV reqsk_timer_handler # flaky, under investigation
|
|
||||||
@@ -10,4 +10,3 @@ send_signal/send_signal_nmi_thread
|
|||||||
|
|
||||||
lwt_reroute # crashes kernel, fix pending upstream
|
lwt_reroute # crashes kernel, fix pending upstream
|
||||||
tc_links_ingress # fails, same fix is pending upstream
|
tc_links_ingress # fails, same fix is pending upstream
|
||||||
tc_redirect # enough is enough, banned for life for flakiness
|
|
||||||
|
|||||||
@@ -2,16 +2,3 @@
|
|||||||
sockmap_listen/sockhash VSOCK test_vsock_redir
|
sockmap_listen/sockhash VSOCK test_vsock_redir
|
||||||
usdt/basic # failing verifier due to bounds check after LLVM update
|
usdt/basic # failing verifier due to bounds check after LLVM update
|
||||||
usdt/multispec # same as above
|
usdt/multispec # same as above
|
||||||
|
|
||||||
deny_namespace # not yet in bpf denylist
|
|
||||||
tc_redirect/tc_redirect_dtime # very flaky
|
|
||||||
lru_bug # not yet in bpf-next denylist
|
|
||||||
|
|
||||||
# Disabled temporarily for a crash.
|
|
||||||
# https://lore.kernel.org/bpf/c9923c1d-971d-4022-8dc8-1364e929d34c@gmail.com/
|
|
||||||
dummy_st_ops/dummy_init_ptr_arg
|
|
||||||
fexit_bpf2bpf
|
|
||||||
tailcalls
|
|
||||||
trace_ext
|
|
||||||
xdp_bpf2bpf
|
|
||||||
xdp_metadata
|
|
||||||
|
|||||||
@@ -37,14 +37,6 @@
|
|||||||
.off = 0, \
|
.off = 0, \
|
||||||
.imm = IMM })
|
.imm = IMM })
|
||||||
|
|
||||||
#define BPF_CALL_REL(DST) \
|
|
||||||
((struct bpf_insn) { \
|
|
||||||
.code = BPF_JMP | BPF_CALL, \
|
|
||||||
.dst_reg = 0, \
|
|
||||||
.src_reg = BPF_PSEUDO_CALL, \
|
|
||||||
.off = 0, \
|
|
||||||
.imm = DST })
|
|
||||||
|
|
||||||
#define BPF_EXIT_INSN() \
|
#define BPF_EXIT_INSN() \
|
||||||
((struct bpf_insn) { \
|
((struct bpf_insn) { \
|
||||||
.code = BPF_JMP | BPF_EXIT, \
|
.code = BPF_JMP | BPF_EXIT, \
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
#ifndef __LINUX_KERNEL_H
|
#ifndef __LINUX_KERNEL_H
|
||||||
#define __LINUX_KERNEL_H
|
#define __LINUX_KERNEL_H
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
|
|
||||||
#ifndef offsetof
|
#ifndef offsetof
|
||||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -42,7 +42,6 @@
|
|||||||
#define BPF_JSGE 0x70 /* SGE is signed '>=', GE in x86 */
|
#define BPF_JSGE 0x70 /* SGE is signed '>=', GE in x86 */
|
||||||
#define BPF_JSLT 0xc0 /* SLT is signed, '<' */
|
#define BPF_JSLT 0xc0 /* SLT is signed, '<' */
|
||||||
#define BPF_JSLE 0xd0 /* SLE is signed, '<=' */
|
#define BPF_JSLE 0xd0 /* SLE is signed, '<=' */
|
||||||
#define BPF_JCOND 0xe0 /* conditional pseudo jumps: may_goto, goto_or_nop */
|
|
||||||
#define BPF_CALL 0x80 /* function call */
|
#define BPF_CALL 0x80 /* function call */
|
||||||
#define BPF_EXIT 0x90 /* function return */
|
#define BPF_EXIT 0x90 /* function return */
|
||||||
|
|
||||||
@@ -51,10 +50,6 @@
|
|||||||
#define BPF_XCHG (0xe0 | BPF_FETCH) /* atomic exchange */
|
#define BPF_XCHG (0xe0 | BPF_FETCH) /* atomic exchange */
|
||||||
#define BPF_CMPXCHG (0xf0 | BPF_FETCH) /* atomic compare-and-write */
|
#define BPF_CMPXCHG (0xf0 | BPF_FETCH) /* atomic compare-and-write */
|
||||||
|
|
||||||
enum bpf_cond_pseudo_jmp {
|
|
||||||
BPF_MAY_GOTO = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Register numbers */
|
/* Register numbers */
|
||||||
enum {
|
enum {
|
||||||
BPF_REG_0 = 0,
|
BPF_REG_0 = 0,
|
||||||
@@ -82,29 +77,12 @@ struct bpf_insn {
|
|||||||
__s32 imm; /* signed immediate constant */
|
__s32 imm; /* signed immediate constant */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Deprecated: use struct bpf_lpm_trie_key_u8 (when the "data" member is needed for
|
/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */
|
||||||
* byte access) or struct bpf_lpm_trie_key_hdr (when using an alternative type for
|
|
||||||
* the trailing flexible array member) instead.
|
|
||||||
*/
|
|
||||||
struct bpf_lpm_trie_key {
|
struct bpf_lpm_trie_key {
|
||||||
__u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */
|
__u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */
|
||||||
__u8 data[0]; /* Arbitrary size */
|
__u8 data[0]; /* Arbitrary size */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Header for bpf_lpm_trie_key structs */
|
|
||||||
struct bpf_lpm_trie_key_hdr {
|
|
||||||
__u32 prefixlen;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry, with trailing byte array. */
|
|
||||||
struct bpf_lpm_trie_key_u8 {
|
|
||||||
union {
|
|
||||||
struct bpf_lpm_trie_key_hdr hdr;
|
|
||||||
__u32 prefixlen;
|
|
||||||
};
|
|
||||||
__u8 data[]; /* Arbitrary size */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bpf_cgroup_storage_key {
|
struct bpf_cgroup_storage_key {
|
||||||
__u64 cgroup_inode_id; /* cgroup inode id */
|
__u64 cgroup_inode_id; /* cgroup inode id */
|
||||||
__u32 attach_type; /* program attach type (enum bpf_attach_type) */
|
__u32 attach_type; /* program attach type (enum bpf_attach_type) */
|
||||||
@@ -639,11 +617,7 @@ union bpf_iter_link_info {
|
|||||||
* to NULL to begin the batched operation. After each subsequent
|
* to NULL to begin the batched operation. After each subsequent
|
||||||
* **BPF_MAP_LOOKUP_BATCH**, the caller should pass the resultant
|
* **BPF_MAP_LOOKUP_BATCH**, the caller should pass the resultant
|
||||||
* *out_batch* as the *in_batch* for the next operation to
|
* *out_batch* as the *in_batch* for the next operation to
|
||||||
* continue iteration from the current point. Both *in_batch* and
|
* continue iteration from the current point.
|
||||||
* *out_batch* must point to memory large enough to hold a key,
|
|
||||||
* except for maps of type **BPF_MAP_TYPE_{HASH, PERCPU_HASH,
|
|
||||||
* LRU_HASH, LRU_PERCPU_HASH}**, for which batch parameters
|
|
||||||
* must be at least 4 bytes wide regardless of key size.
|
|
||||||
*
|
*
|
||||||
* The *keys* and *values* are output parameters which must point
|
* The *keys* and *values* are output parameters which must point
|
||||||
* to memory large enough to hold *count* items based on the key
|
* to memory large enough to hold *count* items based on the key
|
||||||
@@ -873,36 +847,6 @@ union bpf_iter_link_info {
|
|||||||
* Returns zero on success. On error, -1 is returned and *errno*
|
* Returns zero on success. On error, -1 is returned and *errno*
|
||||||
* is set appropriately.
|
* is set appropriately.
|
||||||
*
|
*
|
||||||
* BPF_TOKEN_CREATE
|
|
||||||
* Description
|
|
||||||
* Create BPF token with embedded information about what
|
|
||||||
* BPF-related functionality it allows:
|
|
||||||
* - a set of allowed bpf() syscall commands;
|
|
||||||
* - a set of allowed BPF map types to be created with
|
|
||||||
* BPF_MAP_CREATE command, if BPF_MAP_CREATE itself is allowed;
|
|
||||||
* - a set of allowed BPF program types and BPF program attach
|
|
||||||
* types to be loaded with BPF_PROG_LOAD command, if
|
|
||||||
* BPF_PROG_LOAD itself is allowed.
|
|
||||||
*
|
|
||||||
* BPF token is created (derived) from an instance of BPF FS,
|
|
||||||
* assuming it has necessary delegation mount options specified.
|
|
||||||
* This BPF token can be passed as an extra parameter to various
|
|
||||||
* bpf() syscall commands to grant BPF subsystem functionality to
|
|
||||||
* unprivileged processes.
|
|
||||||
*
|
|
||||||
* When created, BPF token is "associated" with the owning
|
|
||||||
* user namespace of BPF FS instance (super block) that it was
|
|
||||||
* derived from, and subsequent BPF operations performed with
|
|
||||||
* BPF token would be performing capabilities checks (i.e.,
|
|
||||||
* CAP_BPF, CAP_PERFMON, CAP_NET_ADMIN, CAP_SYS_ADMIN) within
|
|
||||||
* that user namespace. Without BPF token, such capabilities
|
|
||||||
* have to be granted in init user namespace, making bpf()
|
|
||||||
* syscall incompatible with user namespace, for the most part.
|
|
||||||
*
|
|
||||||
* Return
|
|
||||||
* A new file descriptor (a nonnegative integer), or -1 if an
|
|
||||||
* error occurred (in which case, *errno* is set appropriately).
|
|
||||||
*
|
|
||||||
* NOTES
|
* NOTES
|
||||||
* eBPF objects (maps and programs) can be shared between processes.
|
* eBPF objects (maps and programs) can be shared between processes.
|
||||||
*
|
*
|
||||||
@@ -957,8 +901,6 @@ enum bpf_cmd {
|
|||||||
BPF_ITER_CREATE,
|
BPF_ITER_CREATE,
|
||||||
BPF_LINK_DETACH,
|
BPF_LINK_DETACH,
|
||||||
BPF_PROG_BIND_MAP,
|
BPF_PROG_BIND_MAP,
|
||||||
BPF_TOKEN_CREATE,
|
|
||||||
__MAX_BPF_CMD,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum bpf_map_type {
|
enum bpf_map_type {
|
||||||
@@ -1009,8 +951,6 @@ enum bpf_map_type {
|
|||||||
BPF_MAP_TYPE_BLOOM_FILTER,
|
BPF_MAP_TYPE_BLOOM_FILTER,
|
||||||
BPF_MAP_TYPE_USER_RINGBUF,
|
BPF_MAP_TYPE_USER_RINGBUF,
|
||||||
BPF_MAP_TYPE_CGRP_STORAGE,
|
BPF_MAP_TYPE_CGRP_STORAGE,
|
||||||
BPF_MAP_TYPE_ARENA,
|
|
||||||
__MAX_BPF_MAP_TYPE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Note that tracing related programs such as
|
/* Note that tracing related programs such as
|
||||||
@@ -1055,7 +995,6 @@ enum bpf_prog_type {
|
|||||||
BPF_PROG_TYPE_SK_LOOKUP,
|
BPF_PROG_TYPE_SK_LOOKUP,
|
||||||
BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */
|
BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */
|
||||||
BPF_PROG_TYPE_NETFILTER,
|
BPF_PROG_TYPE_NETFILTER,
|
||||||
__MAX_BPF_PROG_TYPE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum bpf_attach_type {
|
enum bpf_attach_type {
|
||||||
@@ -1115,7 +1054,6 @@ enum bpf_attach_type {
|
|||||||
BPF_CGROUP_UNIX_GETSOCKNAME,
|
BPF_CGROUP_UNIX_GETSOCKNAME,
|
||||||
BPF_NETKIT_PRIMARY,
|
BPF_NETKIT_PRIMARY,
|
||||||
BPF_NETKIT_PEER,
|
BPF_NETKIT_PEER,
|
||||||
BPF_TRACE_KPROBE_SESSION,
|
|
||||||
__MAX_BPF_ATTACH_TYPE
|
__MAX_BPF_ATTACH_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1136,7 +1074,6 @@ enum bpf_link_type {
|
|||||||
BPF_LINK_TYPE_TCX = 11,
|
BPF_LINK_TYPE_TCX = 11,
|
||||||
BPF_LINK_TYPE_UPROBE_MULTI = 12,
|
BPF_LINK_TYPE_UPROBE_MULTI = 12,
|
||||||
BPF_LINK_TYPE_NETKIT = 13,
|
BPF_LINK_TYPE_NETKIT = 13,
|
||||||
BPF_LINK_TYPE_SOCKMAP = 14,
|
|
||||||
__MAX_BPF_LINK_TYPE,
|
__MAX_BPF_LINK_TYPE,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1341,10 +1278,6 @@ enum {
|
|||||||
*/
|
*/
|
||||||
#define BPF_PSEUDO_KFUNC_CALL 2
|
#define BPF_PSEUDO_KFUNC_CALL 2
|
||||||
|
|
||||||
enum bpf_addr_space_cast {
|
|
||||||
BPF_ADDR_SPACE_CAST = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* flags for BPF_MAP_UPDATE_ELEM command */
|
/* flags for BPF_MAP_UPDATE_ELEM command */
|
||||||
enum {
|
enum {
|
||||||
BPF_ANY = 0, /* create new element or update existing */
|
BPF_ANY = 0, /* create new element or update existing */
|
||||||
@@ -1397,18 +1330,6 @@ enum {
|
|||||||
|
|
||||||
/* Get path from provided FD in BPF_OBJ_PIN/BPF_OBJ_GET commands */
|
/* Get path from provided FD in BPF_OBJ_PIN/BPF_OBJ_GET commands */
|
||||||
BPF_F_PATH_FD = (1U << 14),
|
BPF_F_PATH_FD = (1U << 14),
|
||||||
|
|
||||||
/* Flag for value_type_btf_obj_fd, the fd is available */
|
|
||||||
BPF_F_VTYPE_BTF_OBJ_FD = (1U << 15),
|
|
||||||
|
|
||||||
/* BPF token FD is passed in a corresponding command's token_fd field */
|
|
||||||
BPF_F_TOKEN_FD = (1U << 16),
|
|
||||||
|
|
||||||
/* When user space page faults in bpf_arena send SIGSEGV instead of inserting new page */
|
|
||||||
BPF_F_SEGV_ON_FAULT = (1U << 17),
|
|
||||||
|
|
||||||
/* Do not translate kernel bpf_arena pointers to user pointers */
|
|
||||||
BPF_F_NO_USER_CONV = (1U << 18),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Flags for BPF_PROG_QUERY. */
|
/* Flags for BPF_PROG_QUERY. */
|
||||||
@@ -1480,20 +1401,8 @@ union bpf_attr {
|
|||||||
* BPF_MAP_TYPE_BLOOM_FILTER - the lowest 4 bits indicate the
|
* BPF_MAP_TYPE_BLOOM_FILTER - the lowest 4 bits indicate the
|
||||||
* number of hash functions (if 0, the bloom filter will default
|
* number of hash functions (if 0, the bloom filter will default
|
||||||
* to using 5 hash functions).
|
* to using 5 hash functions).
|
||||||
*
|
|
||||||
* BPF_MAP_TYPE_ARENA - contains the address where user space
|
|
||||||
* is going to mmap() the arena. It has to be page aligned.
|
|
||||||
*/
|
*/
|
||||||
__u64 map_extra;
|
__u64 map_extra;
|
||||||
|
|
||||||
__s32 value_type_btf_obj_fd; /* fd pointing to a BTF
|
|
||||||
* type data for
|
|
||||||
* btf_vmlinux_value_type_id.
|
|
||||||
*/
|
|
||||||
/* BPF token FD to use with BPF_MAP_CREATE operation.
|
|
||||||
* If provided, map_flags should have BPF_F_TOKEN_FD flag set.
|
|
||||||
*/
|
|
||||||
__s32 map_token_fd;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
|
struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
|
||||||
@@ -1563,10 +1472,6 @@ union bpf_attr {
|
|||||||
* truncated), or smaller (if log buffer wasn't filled completely).
|
* truncated), or smaller (if log buffer wasn't filled completely).
|
||||||
*/
|
*/
|
||||||
__u32 log_true_size;
|
__u32 log_true_size;
|
||||||
/* BPF token FD to use with BPF_PROG_LOAD operation.
|
|
||||||
* If provided, prog_flags should have BPF_F_TOKEN_FD flag set.
|
|
||||||
*/
|
|
||||||
__s32 prog_token_fd;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct { /* anonymous struct used by BPF_OBJ_* commands */
|
struct { /* anonymous struct used by BPF_OBJ_* commands */
|
||||||
@@ -1664,10 +1569,8 @@ union bpf_attr {
|
|||||||
} query;
|
} query;
|
||||||
|
|
||||||
struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
|
struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
|
||||||
__u64 name;
|
__u64 name;
|
||||||
__u32 prog_fd;
|
__u32 prog_fd;
|
||||||
__u32 :32;
|
|
||||||
__aligned_u64 cookie;
|
|
||||||
} raw_tracepoint;
|
} raw_tracepoint;
|
||||||
|
|
||||||
struct { /* anonymous struct for BPF_BTF_LOAD */
|
struct { /* anonymous struct for BPF_BTF_LOAD */
|
||||||
@@ -1681,11 +1584,6 @@ union bpf_attr {
|
|||||||
* truncated), or smaller (if log buffer wasn't filled completely).
|
* truncated), or smaller (if log buffer wasn't filled completely).
|
||||||
*/
|
*/
|
||||||
__u32 btf_log_true_size;
|
__u32 btf_log_true_size;
|
||||||
__u32 btf_flags;
|
|
||||||
/* BPF token FD to use with BPF_BTF_LOAD operation.
|
|
||||||
* If provided, btf_flags should have BPF_F_TOKEN_FD flag set.
|
|
||||||
*/
|
|
||||||
__s32 btf_token_fd;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -1816,11 +1714,6 @@ union bpf_attr {
|
|||||||
__u32 flags; /* extra flags */
|
__u32 flags; /* extra flags */
|
||||||
} prog_bind_map;
|
} prog_bind_map;
|
||||||
|
|
||||||
struct { /* struct used by BPF_TOKEN_CREATE command */
|
|
||||||
__u32 flags;
|
|
||||||
__u32 bpffs_fd;
|
|
||||||
} token_create;
|
|
||||||
|
|
||||||
} __attribute__((aligned(8)));
|
} __attribute__((aligned(8)));
|
||||||
|
|
||||||
/* The description below is an attempt at providing documentation to eBPF
|
/* The description below is an attempt at providing documentation to eBPF
|
||||||
@@ -3396,10 +3289,6 @@ union bpf_attr {
|
|||||||
* for the nexthop. If the src addr cannot be derived,
|
* for the nexthop. If the src addr cannot be derived,
|
||||||
* **BPF_FIB_LKUP_RET_NO_SRC_ADDR** is returned. In this
|
* **BPF_FIB_LKUP_RET_NO_SRC_ADDR** is returned. In this
|
||||||
* case, *params*->dmac and *params*->smac are not set either.
|
* 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
|
* *ctx* is either **struct xdp_md** for XDP programs or
|
||||||
* **struct sk_buff** tc cls_act programs.
|
* **struct sk_buff** tc cls_act programs.
|
||||||
@@ -4950,9 +4839,9 @@ union bpf_attr {
|
|||||||
* going through the CPU's backlog queue.
|
* going through the CPU's backlog queue.
|
||||||
*
|
*
|
||||||
* The *flags* argument is reserved and must be 0. The helper is
|
* The *flags* argument is reserved and must be 0. The helper is
|
||||||
* currently only supported for tc BPF program types at the
|
* currently only supported for tc BPF program types at the ingress
|
||||||
* ingress hook and for veth and netkit target device types. The
|
* hook and for veth device types. The peer device must reside in a
|
||||||
* peer device must reside in a different network namespace.
|
* different network namespace.
|
||||||
* Return
|
* Return
|
||||||
* The helper returns **TC_ACT_REDIRECT** on success or
|
* The helper returns **TC_ACT_REDIRECT** on success or
|
||||||
* **TC_ACT_SHOT** on error.
|
* **TC_ACT_SHOT** on error.
|
||||||
@@ -5028,7 +4917,7 @@ union bpf_attr {
|
|||||||
* bytes will be copied to *dst*
|
* bytes will be copied to *dst*
|
||||||
* Return
|
* Return
|
||||||
* The **hash_algo** is returned on success,
|
* The **hash_algo** is returned on success,
|
||||||
* **-EOPNOTSUPP** if IMA is disabled or **-EINVAL** if
|
* **-EOPNOTSUP** if IMA is disabled or **-EINVAL** if
|
||||||
* invalid arguments are passed.
|
* invalid arguments are passed.
|
||||||
*
|
*
|
||||||
* struct socket *bpf_sock_from_file(struct file *file)
|
* struct socket *bpf_sock_from_file(struct file *file)
|
||||||
@@ -5514,7 +5403,7 @@ union bpf_attr {
|
|||||||
* bytes will be copied to *dst*
|
* bytes will be copied to *dst*
|
||||||
* Return
|
* Return
|
||||||
* The **hash_algo** is returned on success,
|
* The **hash_algo** is returned on success,
|
||||||
* **-EOPNOTSUPP** if the hash calculation failed or **-EINVAL** if
|
* **-EOPNOTSUP** if the hash calculation failed or **-EINVAL** if
|
||||||
* invalid arguments are passed.
|
* invalid arguments are passed.
|
||||||
*
|
*
|
||||||
* void *bpf_kptr_xchg(void *map_value, void *ptr)
|
* void *bpf_kptr_xchg(void *map_value, void *ptr)
|
||||||
@@ -6598,7 +6487,7 @@ struct bpf_map_info {
|
|||||||
__u32 btf_id;
|
__u32 btf_id;
|
||||||
__u32 btf_key_type_id;
|
__u32 btf_key_type_id;
|
||||||
__u32 btf_value_type_id;
|
__u32 btf_value_type_id;
|
||||||
__u32 btf_vmlinux_id;
|
__u32 :32; /* alignment pad */
|
||||||
__u64 map_extra;
|
__u64 map_extra;
|
||||||
} __attribute__((aligned(8)));
|
} __attribute__((aligned(8)));
|
||||||
|
|
||||||
@@ -6674,7 +6563,6 @@ struct bpf_link_info {
|
|||||||
__u32 count; /* in/out: kprobe_multi function count */
|
__u32 count; /* in/out: kprobe_multi function count */
|
||||||
__u32 flags;
|
__u32 flags;
|
||||||
__u64 missed;
|
__u64 missed;
|
||||||
__aligned_u64 cookies;
|
|
||||||
} kprobe_multi;
|
} kprobe_multi;
|
||||||
struct {
|
struct {
|
||||||
__aligned_u64 path;
|
__aligned_u64 path;
|
||||||
@@ -6694,7 +6582,6 @@ struct bpf_link_info {
|
|||||||
__aligned_u64 file_name; /* in/out */
|
__aligned_u64 file_name; /* in/out */
|
||||||
__u32 name_len;
|
__u32 name_len;
|
||||||
__u32 offset; /* offset from file_name */
|
__u32 offset; /* offset from file_name */
|
||||||
__u64 cookie;
|
|
||||||
} uprobe; /* BPF_PERF_EVENT_UPROBE, BPF_PERF_EVENT_URETPROBE */
|
} uprobe; /* BPF_PERF_EVENT_UPROBE, BPF_PERF_EVENT_URETPROBE */
|
||||||
struct {
|
struct {
|
||||||
__aligned_u64 func_name; /* in/out */
|
__aligned_u64 func_name; /* in/out */
|
||||||
@@ -6702,19 +6589,14 @@ struct bpf_link_info {
|
|||||||
__u32 offset; /* offset from func_name */
|
__u32 offset; /* offset from func_name */
|
||||||
__u64 addr;
|
__u64 addr;
|
||||||
__u64 missed;
|
__u64 missed;
|
||||||
__u64 cookie;
|
|
||||||
} kprobe; /* BPF_PERF_EVENT_KPROBE, BPF_PERF_EVENT_KRETPROBE */
|
} kprobe; /* BPF_PERF_EVENT_KPROBE, BPF_PERF_EVENT_KRETPROBE */
|
||||||
struct {
|
struct {
|
||||||
__aligned_u64 tp_name; /* in/out */
|
__aligned_u64 tp_name; /* in/out */
|
||||||
__u32 name_len;
|
__u32 name_len;
|
||||||
__u32 :32;
|
|
||||||
__u64 cookie;
|
|
||||||
} tracepoint; /* BPF_PERF_EVENT_TRACEPOINT */
|
} tracepoint; /* BPF_PERF_EVENT_TRACEPOINT */
|
||||||
struct {
|
struct {
|
||||||
__u64 config;
|
__u64 config;
|
||||||
__u32 type;
|
__u32 type;
|
||||||
__u32 :32;
|
|
||||||
__u64 cookie;
|
|
||||||
} event; /* BPF_PERF_EVENT_EVENT */
|
} event; /* BPF_PERF_EVENT_EVENT */
|
||||||
};
|
};
|
||||||
} perf_event;
|
} perf_event;
|
||||||
@@ -6726,10 +6608,6 @@ struct bpf_link_info {
|
|||||||
__u32 ifindex;
|
__u32 ifindex;
|
||||||
__u32 attach_type;
|
__u32 attach_type;
|
||||||
} netkit;
|
} netkit;
|
||||||
struct {
|
|
||||||
__u32 map_id;
|
|
||||||
__u32 attach_type;
|
|
||||||
} sockmap;
|
|
||||||
};
|
};
|
||||||
} __attribute__((aligned(8)));
|
} __attribute__((aligned(8)));
|
||||||
|
|
||||||
@@ -6948,8 +6826,6 @@ enum {
|
|||||||
* socket transition to LISTEN state.
|
* socket transition to LISTEN state.
|
||||||
*/
|
*/
|
||||||
BPF_SOCK_OPS_RTT_CB, /* Called on every RTT.
|
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.
|
BPF_SOCK_OPS_PARSE_HDR_OPT_CB, /* Parse the header option.
|
||||||
* It will be called to handle
|
* It will be called to handle
|
||||||
@@ -7028,7 +6904,6 @@ enum {
|
|||||||
BPF_TCP_LISTEN,
|
BPF_TCP_LISTEN,
|
||||||
BPF_TCP_CLOSING, /* Now a valid state */
|
BPF_TCP_CLOSING, /* Now a valid state */
|
||||||
BPF_TCP_NEW_SYN_RECV,
|
BPF_TCP_NEW_SYN_RECV,
|
||||||
BPF_TCP_BOUND_INACTIVE,
|
|
||||||
|
|
||||||
BPF_TCP_MAX_STATES /* Leave at the end! */
|
BPF_TCP_MAX_STATES /* Leave at the end! */
|
||||||
};
|
};
|
||||||
@@ -7132,7 +7007,6 @@ enum {
|
|||||||
BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
|
BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
|
||||||
BPF_FIB_LOOKUP_TBID = (1U << 3),
|
BPF_FIB_LOOKUP_TBID = (1U << 3),
|
||||||
BPF_FIB_LOOKUP_SRC = (1U << 4),
|
BPF_FIB_LOOKUP_SRC = (1U << 4),
|
||||||
BPF_FIB_LOOKUP_MARK = (1U << 5),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -7165,7 +7039,7 @@ struct bpf_fib_lookup {
|
|||||||
|
|
||||||
/* output: MTU value */
|
/* output: MTU value */
|
||||||
__u16 mtu_result;
|
__u16 mtu_result;
|
||||||
} __attribute__((packed, aligned(2)));
|
};
|
||||||
/* input: L3 device index for lookup
|
/* input: L3 device index for lookup
|
||||||
* output: device index from FIB lookup
|
* output: device index from FIB lookup
|
||||||
*/
|
*/
|
||||||
@@ -7210,19 +7084,8 @@ struct bpf_fib_lookup {
|
|||||||
__u32 tbid;
|
__u32 tbid;
|
||||||
};
|
};
|
||||||
|
|
||||||
union {
|
__u8 smac[6]; /* ETH_ALEN */
|
||||||
/* input */
|
__u8 dmac[6]; /* ETH_ALEN */
|
||||||
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 {
|
struct bpf_redir_neigh {
|
||||||
@@ -7309,10 +7172,6 @@ struct bpf_timer {
|
|||||||
__u64 __opaque[2];
|
__u64 __opaque[2];
|
||||||
} __attribute__((aligned(8)));
|
} __attribute__((aligned(8)));
|
||||||
|
|
||||||
struct bpf_wq {
|
|
||||||
__u64 __opaque[2];
|
|
||||||
} __attribute__((aligned(8)));
|
|
||||||
|
|
||||||
struct bpf_dynptr {
|
struct bpf_dynptr {
|
||||||
__u64 __opaque[2];
|
__u64 __opaque[2];
|
||||||
} __attribute__((aligned(8)));
|
} __attribute__((aligned(8)));
|
||||||
|
|||||||
@@ -116,8 +116,5 @@
|
|||||||
#define AT_HANDLE_FID AT_REMOVEDIR /* file handle is needed to
|
#define AT_HANDLE_FID AT_REMOVEDIR /* file handle is needed to
|
||||||
compare object identity and may not
|
compare object identity and may not
|
||||||
be usable to open_by_handle_at(2) */
|
be usable to open_by_handle_at(2) */
|
||||||
#if defined(__KERNEL__)
|
|
||||||
#define AT_GETATTR_NOSEC 0x80000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _UAPI_LINUX_FCNTL_H */
|
#endif /* _UAPI_LINUX_FCNTL_H */
|
||||||
|
|||||||
@@ -974,7 +974,6 @@ enum {
|
|||||||
IFLA_BOND_AD_LACP_ACTIVE,
|
IFLA_BOND_AD_LACP_ACTIVE,
|
||||||
IFLA_BOND_MISSED_MAX,
|
IFLA_BOND_MISSED_MAX,
|
||||||
IFLA_BOND_NS_IP6_TARGET,
|
IFLA_BOND_NS_IP6_TARGET,
|
||||||
IFLA_BOND_COUPLED_CONTROL,
|
|
||||||
__IFLA_BOND_MAX,
|
__IFLA_BOND_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ enum netdev_xdp_rx_metadata {
|
|||||||
enum netdev_xsk_flags {
|
enum netdev_xsk_flags {
|
||||||
NETDEV_XSK_FLAGS_TX_TIMESTAMP = 1,
|
NETDEV_XSK_FLAGS_TX_TIMESTAMP = 1,
|
||||||
NETDEV_XSK_FLAGS_TX_CHECKSUM = 2,
|
NETDEV_XSK_FLAGS_TX_CHECKSUM = 2,
|
||||||
|
|
||||||
|
/* private: */
|
||||||
|
NETDEV_XSK_FLAGS_MASK = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum netdev_queue_type {
|
enum netdev_queue_type {
|
||||||
@@ -70,10 +73,6 @@ enum netdev_queue_type {
|
|||||||
NETDEV_QUEUE_TYPE_TX,
|
NETDEV_QUEUE_TYPE_TX,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum netdev_qstats_scope {
|
|
||||||
NETDEV_QSTATS_SCOPE_QUEUE = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NETDEV_A_DEV_IFINDEX = 1,
|
NETDEV_A_DEV_IFINDEX = 1,
|
||||||
NETDEV_A_DEV_PAD,
|
NETDEV_A_DEV_PAD,
|
||||||
@@ -136,21 +135,6 @@ enum {
|
|||||||
NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
|
NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
NETDEV_A_QSTATS_IFINDEX = 1,
|
|
||||||
NETDEV_A_QSTATS_QUEUE_TYPE,
|
|
||||||
NETDEV_A_QSTATS_QUEUE_ID,
|
|
||||||
NETDEV_A_QSTATS_SCOPE,
|
|
||||||
NETDEV_A_QSTATS_RX_PACKETS = 8,
|
|
||||||
NETDEV_A_QSTATS_RX_BYTES,
|
|
||||||
NETDEV_A_QSTATS_TX_PACKETS,
|
|
||||||
NETDEV_A_QSTATS_TX_BYTES,
|
|
||||||
NETDEV_A_QSTATS_RX_ALLOC_FAIL,
|
|
||||||
|
|
||||||
__NETDEV_A_QSTATS_MAX,
|
|
||||||
NETDEV_A_QSTATS_MAX = (__NETDEV_A_QSTATS_MAX - 1)
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NETDEV_CMD_DEV_GET = 1,
|
NETDEV_CMD_DEV_GET = 1,
|
||||||
NETDEV_CMD_DEV_ADD_NTF,
|
NETDEV_CMD_DEV_ADD_NTF,
|
||||||
@@ -163,7 +147,6 @@ enum {
|
|||||||
NETDEV_CMD_PAGE_POOL_STATS_GET,
|
NETDEV_CMD_PAGE_POOL_STATS_GET,
|
||||||
NETDEV_CMD_QUEUE_GET,
|
NETDEV_CMD_QUEUE_GET,
|
||||||
NETDEV_CMD_NAPI_GET,
|
NETDEV_CMD_NAPI_GET,
|
||||||
NETDEV_CMD_QSTATS_GET,
|
|
||||||
|
|
||||||
__NETDEV_CMD_MAX,
|
__NETDEV_CMD_MAX,
|
||||||
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
|
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
|
||||||
|
|||||||
@@ -204,8 +204,6 @@ enum perf_branch_sample_type_shift {
|
|||||||
|
|
||||||
PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT = 18, /* save privilege mode */
|
PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT = 18, /* save privilege mode */
|
||||||
|
|
||||||
PERF_SAMPLE_BRANCH_COUNTERS_SHIFT = 19, /* save occurrences of events on a branch */
|
|
||||||
|
|
||||||
PERF_SAMPLE_BRANCH_MAX_SHIFT /* non-ABI */
|
PERF_SAMPLE_BRANCH_MAX_SHIFT /* non-ABI */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -237,8 +235,6 @@ enum perf_branch_sample_type {
|
|||||||
|
|
||||||
PERF_SAMPLE_BRANCH_PRIV_SAVE = 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
|
PERF_SAMPLE_BRANCH_PRIV_SAVE = 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
|
||||||
|
|
||||||
PERF_SAMPLE_BRANCH_COUNTERS = 1U << PERF_SAMPLE_BRANCH_COUNTERS_SHIFT,
|
|
||||||
|
|
||||||
PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
|
PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -986,12 +982,6 @@ enum perf_event_type {
|
|||||||
* { u64 nr;
|
* { u64 nr;
|
||||||
* { u64 hw_idx; } && PERF_SAMPLE_BRANCH_HW_INDEX
|
* { u64 hw_idx; } && PERF_SAMPLE_BRANCH_HW_INDEX
|
||||||
* { u64 from, to, flags } lbr[nr];
|
* { u64 from, to, flags } lbr[nr];
|
||||||
* #
|
|
||||||
* # The format of the counters is decided by the
|
|
||||||
* # "branch_counter_nr" and "branch_counter_width",
|
|
||||||
* # which are defined in the ABI.
|
|
||||||
* #
|
|
||||||
* { u64 counters; } cntr[nr] && PERF_SAMPLE_BRANCH_COUNTERS
|
|
||||||
* } && PERF_SAMPLE_BRANCH_STACK
|
* } && PERF_SAMPLE_BRANCH_STACK
|
||||||
*
|
*
|
||||||
* { u64 abi; # enum perf_sample_regs_abi
|
* { u64 abi; # enum perf_sample_regs_abi
|
||||||
@@ -1437,9 +1427,6 @@ struct perf_branch_entry {
|
|||||||
reserved:31;
|
reserved:31;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Size of used info bits in struct perf_branch_entry */
|
|
||||||
#define PERF_BRANCH_ENTRY_INFO_BITS_MAX 33
|
|
||||||
|
|
||||||
union perf_sample_weight {
|
union perf_sample_weight {
|
||||||
__u64 full;
|
__u64 full;
|
||||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
#!/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,22 +295,6 @@ Latest changes to BPF helper definitions.
|
|||||||
" -- src/bpf_helper_defs.h
|
" -- src/bpf_helper_defs.h
|
||||||
fi
|
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
|
# Use generated cover-letter as a template for "sync commit" with
|
||||||
# baseline and checkpoint commits from kernel repo (and leave summary
|
# baseline and checkpoint commits from kernel repo (and leave summary
|
||||||
# from cover letter intact, of course)
|
# from cover letter intact, of course)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
LIBBPF_MAJOR_VERSION := 1
|
LIBBPF_MAJOR_VERSION := 1
|
||||||
LIBBPF_MINOR_VERSION := 5
|
LIBBPF_MINOR_VERSION := 4
|
||||||
LIBBPF_PATCH_VERSION := 0
|
LIBBPF_PATCH_VERSION := 0
|
||||||
LIBBPF_VERSION := $(LIBBPF_MAJOR_VERSION).$(LIBBPF_MINOR_VERSION).$(LIBBPF_PATCH_VERSION)
|
LIBBPF_VERSION := $(LIBBPF_MAJOR_VERSION).$(LIBBPF_MINOR_VERSION).$(LIBBPF_PATCH_VERSION)
|
||||||
LIBBPF_MAJMIN_VERSION := $(LIBBPF_MAJOR_VERSION).$(LIBBPF_MINOR_VERSION).0
|
LIBBPF_MAJMIN_VERSION := $(LIBBPF_MAJOR_VERSION).$(LIBBPF_MINOR_VERSION).0
|
||||||
@@ -55,7 +55,7 @@ STATIC_OBJDIR := $(OBJDIR)/staticobjs
|
|||||||
OBJS := bpf.o btf.o libbpf.o libbpf_errno.o netlink.o \
|
OBJS := bpf.o btf.o libbpf.o libbpf_errno.o netlink.o \
|
||||||
nlattr.o str_error.o libbpf_probes.o bpf_prog_linfo.o \
|
nlattr.o str_error.o libbpf_probes.o bpf_prog_linfo.o \
|
||||||
btf_dump.o hashmap.o ringbuf.o strset.o linker.o gen_loader.o \
|
btf_dump.o hashmap.o ringbuf.o strset.o linker.o gen_loader.o \
|
||||||
relo_core.o usdt.o zip.o elf.o features.o
|
relo_core.o usdt.o zip.o elf.o
|
||||||
SHARED_OBJS := $(addprefix $(SHARED_OBJDIR)/,$(OBJS))
|
SHARED_OBJS := $(addprefix $(SHARED_OBJDIR)/,$(OBJS))
|
||||||
STATIC_OBJS := $(addprefix $(STATIC_OBJDIR)/,$(OBJS))
|
STATIC_OBJS := $(addprefix $(STATIC_OBJDIR)/,$(OBJS))
|
||||||
|
|
||||||
|
|||||||
59
src/bpf.c
59
src/bpf.c
@@ -103,7 +103,7 @@ int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts)
|
|||||||
* [0] https://lore.kernel.org/bpf/20201201215900.3569844-1-guro@fb.com/
|
* [0] https://lore.kernel.org/bpf/20201201215900.3569844-1-guro@fb.com/
|
||||||
* [1] d05512618056 ("bpf: Add bpf_ktime_get_coarse_ns helper")
|
* [1] d05512618056 ("bpf: Add bpf_ktime_get_coarse_ns helper")
|
||||||
*/
|
*/
|
||||||
int probe_memcg_account(int token_fd)
|
int probe_memcg_account(void)
|
||||||
{
|
{
|
||||||
const size_t attr_sz = offsetofend(union bpf_attr, attach_btf_obj_fd);
|
const size_t attr_sz = offsetofend(union bpf_attr, attach_btf_obj_fd);
|
||||||
struct bpf_insn insns[] = {
|
struct bpf_insn insns[] = {
|
||||||
@@ -120,9 +120,6 @@ int probe_memcg_account(int token_fd)
|
|||||||
attr.insns = ptr_to_u64(insns);
|
attr.insns = ptr_to_u64(insns);
|
||||||
attr.insn_cnt = insn_cnt;
|
attr.insn_cnt = insn_cnt;
|
||||||
attr.license = ptr_to_u64("GPL");
|
attr.license = ptr_to_u64("GPL");
|
||||||
attr.prog_token_fd = token_fd;
|
|
||||||
if (token_fd)
|
|
||||||
attr.prog_flags |= BPF_F_TOKEN_FD;
|
|
||||||
|
|
||||||
prog_fd = sys_bpf_fd(BPF_PROG_LOAD, &attr, attr_sz);
|
prog_fd = sys_bpf_fd(BPF_PROG_LOAD, &attr, attr_sz);
|
||||||
if (prog_fd >= 0) {
|
if (prog_fd >= 0) {
|
||||||
@@ -149,7 +146,7 @@ int bump_rlimit_memlock(void)
|
|||||||
struct rlimit rlim;
|
struct rlimit rlim;
|
||||||
|
|
||||||
/* if kernel supports memcg-based accounting, skip bumping RLIMIT_MEMLOCK */
|
/* if kernel supports memcg-based accounting, skip bumping RLIMIT_MEMLOCK */
|
||||||
if (memlock_bumped || feat_supported(NULL, FEAT_MEMCG_ACCOUNT))
|
if (memlock_bumped || kernel_supports(NULL, FEAT_MEMCG_ACCOUNT))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memlock_bumped = true;
|
memlock_bumped = true;
|
||||||
@@ -172,7 +169,7 @@ int bpf_map_create(enum bpf_map_type map_type,
|
|||||||
__u32 max_entries,
|
__u32 max_entries,
|
||||||
const struct bpf_map_create_opts *opts)
|
const struct bpf_map_create_opts *opts)
|
||||||
{
|
{
|
||||||
const size_t attr_sz = offsetofend(union bpf_attr, map_token_fd);
|
const size_t attr_sz = offsetofend(union bpf_attr, map_extra);
|
||||||
union bpf_attr attr;
|
union bpf_attr attr;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@@ -184,7 +181,7 @@ int bpf_map_create(enum bpf_map_type map_type,
|
|||||||
return libbpf_err(-EINVAL);
|
return libbpf_err(-EINVAL);
|
||||||
|
|
||||||
attr.map_type = map_type;
|
attr.map_type = map_type;
|
||||||
if (map_name && feat_supported(NULL, FEAT_PROG_NAME))
|
if (map_name && kernel_supports(NULL, FEAT_PROG_NAME))
|
||||||
libbpf_strlcpy(attr.map_name, map_name, sizeof(attr.map_name));
|
libbpf_strlcpy(attr.map_name, map_name, sizeof(attr.map_name));
|
||||||
attr.key_size = key_size;
|
attr.key_size = key_size;
|
||||||
attr.value_size = value_size;
|
attr.value_size = value_size;
|
||||||
@@ -194,7 +191,6 @@ int bpf_map_create(enum bpf_map_type map_type,
|
|||||||
attr.btf_key_type_id = OPTS_GET(opts, btf_key_type_id, 0);
|
attr.btf_key_type_id = OPTS_GET(opts, btf_key_type_id, 0);
|
||||||
attr.btf_value_type_id = OPTS_GET(opts, btf_value_type_id, 0);
|
attr.btf_value_type_id = OPTS_GET(opts, btf_value_type_id, 0);
|
||||||
attr.btf_vmlinux_value_type_id = OPTS_GET(opts, btf_vmlinux_value_type_id, 0);
|
attr.btf_vmlinux_value_type_id = OPTS_GET(opts, btf_vmlinux_value_type_id, 0);
|
||||||
attr.value_type_btf_obj_fd = OPTS_GET(opts, value_type_btf_obj_fd, 0);
|
|
||||||
|
|
||||||
attr.inner_map_fd = OPTS_GET(opts, inner_map_fd, 0);
|
attr.inner_map_fd = OPTS_GET(opts, inner_map_fd, 0);
|
||||||
attr.map_flags = OPTS_GET(opts, map_flags, 0);
|
attr.map_flags = OPTS_GET(opts, map_flags, 0);
|
||||||
@@ -202,8 +198,6 @@ int bpf_map_create(enum bpf_map_type map_type,
|
|||||||
attr.numa_node = OPTS_GET(opts, numa_node, 0);
|
attr.numa_node = OPTS_GET(opts, numa_node, 0);
|
||||||
attr.map_ifindex = OPTS_GET(opts, map_ifindex, 0);
|
attr.map_ifindex = OPTS_GET(opts, map_ifindex, 0);
|
||||||
|
|
||||||
attr.map_token_fd = OPTS_GET(opts, token_fd, 0);
|
|
||||||
|
|
||||||
fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, attr_sz);
|
fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, attr_sz);
|
||||||
return libbpf_err_errno(fd);
|
return libbpf_err_errno(fd);
|
||||||
}
|
}
|
||||||
@@ -238,7 +232,7 @@ int bpf_prog_load(enum bpf_prog_type prog_type,
|
|||||||
const struct bpf_insn *insns, size_t insn_cnt,
|
const struct bpf_insn *insns, size_t insn_cnt,
|
||||||
struct bpf_prog_load_opts *opts)
|
struct bpf_prog_load_opts *opts)
|
||||||
{
|
{
|
||||||
const size_t attr_sz = offsetofend(union bpf_attr, prog_token_fd);
|
const size_t attr_sz = offsetofend(union bpf_attr, log_true_size);
|
||||||
void *finfo = NULL, *linfo = NULL;
|
void *finfo = NULL, *linfo = NULL;
|
||||||
const char *func_info, *line_info;
|
const char *func_info, *line_info;
|
||||||
__u32 log_size, log_level, attach_prog_fd, attach_btf_obj_fd;
|
__u32 log_size, log_level, attach_prog_fd, attach_btf_obj_fd;
|
||||||
@@ -267,9 +261,8 @@ int bpf_prog_load(enum bpf_prog_type prog_type,
|
|||||||
attr.prog_flags = OPTS_GET(opts, prog_flags, 0);
|
attr.prog_flags = OPTS_GET(opts, prog_flags, 0);
|
||||||
attr.prog_ifindex = OPTS_GET(opts, prog_ifindex, 0);
|
attr.prog_ifindex = OPTS_GET(opts, prog_ifindex, 0);
|
||||||
attr.kern_version = OPTS_GET(opts, kern_version, 0);
|
attr.kern_version = OPTS_GET(opts, kern_version, 0);
|
||||||
attr.prog_token_fd = OPTS_GET(opts, token_fd, 0);
|
|
||||||
|
|
||||||
if (prog_name && feat_supported(NULL, FEAT_PROG_NAME))
|
if (prog_name && kernel_supports(NULL, FEAT_PROG_NAME))
|
||||||
libbpf_strlcpy(attr.prog_name, prog_name, sizeof(attr.prog_name));
|
libbpf_strlcpy(attr.prog_name, prog_name, sizeof(attr.prog_name));
|
||||||
attr.license = ptr_to_u64(license);
|
attr.license = ptr_to_u64(license);
|
||||||
|
|
||||||
@@ -766,7 +759,6 @@ int bpf_link_create(int prog_fd, int target_fd,
|
|||||||
return libbpf_err(-EINVAL);
|
return libbpf_err(-EINVAL);
|
||||||
break;
|
break;
|
||||||
case BPF_TRACE_KPROBE_MULTI:
|
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.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.cnt = OPTS_GET(opts, kprobe_multi.cnt, 0);
|
||||||
attr.link_create.kprobe_multi.syms = ptr_to_u64(OPTS_GET(opts, kprobe_multi.syms, 0));
|
attr.link_create.kprobe_multi.syms = ptr_to_u64(OPTS_GET(opts, kprobe_multi.syms, 0));
|
||||||
@@ -786,7 +778,6 @@ int bpf_link_create(int prog_fd, int target_fd,
|
|||||||
if (!OPTS_ZEROED(opts, uprobe_multi))
|
if (!OPTS_ZEROED(opts, uprobe_multi))
|
||||||
return libbpf_err(-EINVAL);
|
return libbpf_err(-EINVAL);
|
||||||
break;
|
break;
|
||||||
case BPF_TRACE_RAW_TP:
|
|
||||||
case BPF_TRACE_FENTRY:
|
case BPF_TRACE_FENTRY:
|
||||||
case BPF_TRACE_FEXIT:
|
case BPF_TRACE_FEXIT:
|
||||||
case BPF_MODIFY_RETURN:
|
case BPF_MODIFY_RETURN:
|
||||||
@@ -1175,34 +1166,23 @@ int bpf_link_get_info_by_fd(int link_fd, struct bpf_link_info *info, __u32 *info
|
|||||||
return bpf_obj_get_info_by_fd(link_fd, info, info_len);
|
return bpf_obj_get_info_by_fd(link_fd, info, info_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bpf_raw_tracepoint_open_opts(int prog_fd, struct bpf_raw_tp_opts *opts)
|
int bpf_raw_tracepoint_open(const char *name, int prog_fd)
|
||||||
{
|
{
|
||||||
const size_t attr_sz = offsetofend(union bpf_attr, raw_tracepoint);
|
const size_t attr_sz = offsetofend(union bpf_attr, raw_tracepoint);
|
||||||
union bpf_attr attr;
|
union bpf_attr attr;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (!OPTS_VALID(opts, bpf_raw_tp_opts))
|
|
||||||
return libbpf_err(-EINVAL);
|
|
||||||
|
|
||||||
memset(&attr, 0, attr_sz);
|
memset(&attr, 0, attr_sz);
|
||||||
|
attr.raw_tracepoint.name = ptr_to_u64(name);
|
||||||
attr.raw_tracepoint.prog_fd = prog_fd;
|
attr.raw_tracepoint.prog_fd = prog_fd;
|
||||||
attr.raw_tracepoint.name = ptr_to_u64(OPTS_GET(opts, tp_name, NULL));
|
|
||||||
attr.raw_tracepoint.cookie = OPTS_GET(opts, cookie, 0);
|
|
||||||
|
|
||||||
fd = sys_bpf_fd(BPF_RAW_TRACEPOINT_OPEN, &attr, attr_sz);
|
fd = sys_bpf_fd(BPF_RAW_TRACEPOINT_OPEN, &attr, attr_sz);
|
||||||
return libbpf_err_errno(fd);
|
return libbpf_err_errno(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bpf_raw_tracepoint_open(const char *name, int prog_fd)
|
|
||||||
{
|
|
||||||
LIBBPF_OPTS(bpf_raw_tp_opts, opts, .tp_name = name);
|
|
||||||
|
|
||||||
return bpf_raw_tracepoint_open_opts(prog_fd, &opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bpf_btf_load(const void *btf_data, size_t btf_size, struct bpf_btf_load_opts *opts)
|
int bpf_btf_load(const void *btf_data, size_t btf_size, struct bpf_btf_load_opts *opts)
|
||||||
{
|
{
|
||||||
const size_t attr_sz = offsetofend(union bpf_attr, btf_token_fd);
|
const size_t attr_sz = offsetofend(union bpf_attr, btf_log_true_size);
|
||||||
union bpf_attr attr;
|
union bpf_attr attr;
|
||||||
char *log_buf;
|
char *log_buf;
|
||||||
size_t log_size;
|
size_t log_size;
|
||||||
@@ -1227,10 +1207,6 @@ int bpf_btf_load(const void *btf_data, size_t btf_size, struct bpf_btf_load_opts
|
|||||||
|
|
||||||
attr.btf = ptr_to_u64(btf_data);
|
attr.btf = ptr_to_u64(btf_data);
|
||||||
attr.btf_size = btf_size;
|
attr.btf_size = btf_size;
|
||||||
|
|
||||||
attr.btf_flags = OPTS_GET(opts, btf_flags, 0);
|
|
||||||
attr.btf_token_fd = OPTS_GET(opts, token_fd, 0);
|
|
||||||
|
|
||||||
/* log_level == 0 and log_buf != NULL means "try loading without
|
/* log_level == 0 and log_buf != NULL means "try loading without
|
||||||
* log_buf, but retry with log_buf and log_level=1 on error", which is
|
* log_buf, but retry with log_buf and log_level=1 on error", which is
|
||||||
* consistent across low-level and high-level BTF and program loading
|
* consistent across low-level and high-level BTF and program loading
|
||||||
@@ -1311,20 +1287,3 @@ int bpf_prog_bind_map(int prog_fd, int map_fd,
|
|||||||
ret = sys_bpf(BPF_PROG_BIND_MAP, &attr, attr_sz);
|
ret = sys_bpf(BPF_PROG_BIND_MAP, &attr, attr_sz);
|
||||||
return libbpf_err_errno(ret);
|
return libbpf_err_errno(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bpf_token_create(int bpffs_fd, struct bpf_token_create_opts *opts)
|
|
||||||
{
|
|
||||||
const size_t attr_sz = offsetofend(union bpf_attr, token_create);
|
|
||||||
union bpf_attr attr;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
if (!OPTS_VALID(opts, bpf_token_create_opts))
|
|
||||||
return libbpf_err(-EINVAL);
|
|
||||||
|
|
||||||
memset(&attr, 0, attr_sz);
|
|
||||||
attr.token_create.bpffs_fd = bpffs_fd;
|
|
||||||
attr.token_create.flags = OPTS_GET(opts, flags, 0);
|
|
||||||
|
|
||||||
fd = sys_bpf_fd(BPF_TOKEN_CREATE, &attr, attr_sz);
|
|
||||||
return libbpf_err_errno(fd);
|
|
||||||
}
|
|
||||||
|
|||||||
88
src/bpf.h
88
src/bpf.h
@@ -35,7 +35,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LIBBPF_API int libbpf_set_memlock_rlim(size_t memlock_bytes);
|
int libbpf_set_memlock_rlim(size_t memlock_bytes);
|
||||||
|
|
||||||
struct bpf_map_create_opts {
|
struct bpf_map_create_opts {
|
||||||
size_t sz; /* size of this struct for forward/backward compatibility */
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
@@ -51,12 +51,8 @@ struct bpf_map_create_opts {
|
|||||||
|
|
||||||
__u32 numa_node;
|
__u32 numa_node;
|
||||||
__u32 map_ifindex;
|
__u32 map_ifindex;
|
||||||
__s32 value_type_btf_obj_fd;
|
|
||||||
|
|
||||||
__u32 token_fd;
|
|
||||||
size_t :0;
|
|
||||||
};
|
};
|
||||||
#define bpf_map_create_opts__last_field token_fd
|
#define bpf_map_create_opts__last_field map_ifindex
|
||||||
|
|
||||||
LIBBPF_API int bpf_map_create(enum bpf_map_type map_type,
|
LIBBPF_API int bpf_map_create(enum bpf_map_type map_type,
|
||||||
const char *map_name,
|
const char *map_name,
|
||||||
@@ -106,10 +102,9 @@ struct bpf_prog_load_opts {
|
|||||||
* If kernel doesn't support this feature, log_size is left unchanged.
|
* If kernel doesn't support this feature, log_size is left unchanged.
|
||||||
*/
|
*/
|
||||||
__u32 log_true_size;
|
__u32 log_true_size;
|
||||||
__u32 token_fd;
|
|
||||||
size_t :0;
|
size_t :0;
|
||||||
};
|
};
|
||||||
#define bpf_prog_load_opts__last_field token_fd
|
#define bpf_prog_load_opts__last_field log_true_size
|
||||||
|
|
||||||
LIBBPF_API int bpf_prog_load(enum bpf_prog_type prog_type,
|
LIBBPF_API int bpf_prog_load(enum bpf_prog_type prog_type,
|
||||||
const char *prog_name, const char *license,
|
const char *prog_name, const char *license,
|
||||||
@@ -135,12 +130,9 @@ struct bpf_btf_load_opts {
|
|||||||
* If kernel doesn't support this feature, log_size is left unchanged.
|
* If kernel doesn't support this feature, log_size is left unchanged.
|
||||||
*/
|
*/
|
||||||
__u32 log_true_size;
|
__u32 log_true_size;
|
||||||
|
|
||||||
__u32 btf_flags;
|
|
||||||
__u32 token_fd;
|
|
||||||
size_t :0;
|
size_t :0;
|
||||||
};
|
};
|
||||||
#define bpf_btf_load_opts__last_field token_fd
|
#define bpf_btf_load_opts__last_field log_true_size
|
||||||
|
|
||||||
LIBBPF_API int bpf_btf_load(const void *btf_data, size_t btf_size,
|
LIBBPF_API int bpf_btf_load(const void *btf_data, size_t btf_size,
|
||||||
struct bpf_btf_load_opts *opts);
|
struct bpf_btf_load_opts *opts);
|
||||||
@@ -190,14 +182,10 @@ LIBBPF_API int bpf_map_delete_batch(int fd, const void *keys,
|
|||||||
/**
|
/**
|
||||||
* @brief **bpf_map_lookup_batch()** allows for batch lookup of BPF map elements.
|
* @brief **bpf_map_lookup_batch()** allows for batch lookup of BPF map elements.
|
||||||
*
|
*
|
||||||
* The parameter *in_batch* is the address of the first element in the batch to
|
* The parameter *in_batch* is the address of the first element in the batch to read.
|
||||||
* read. *out_batch* is an output parameter that should be passed as *in_batch*
|
* *out_batch* is an output parameter that should be passed as *in_batch* to subsequent
|
||||||
* to subsequent calls to **bpf_map_lookup_batch()**. NULL can be passed for
|
* calls to **bpf_map_lookup_batch()**. NULL can be passed for *in_batch* to indicate
|
||||||
* *in_batch* to indicate that the batched lookup starts from the beginning of
|
* that the batched lookup starts from the beginning of the map.
|
||||||
* the map. Both *in_batch* and *out_batch* must point to memory large enough to
|
|
||||||
* hold a single key, except for maps of type **BPF_MAP_TYPE_{HASH, PERCPU_HASH,
|
|
||||||
* LRU_HASH, LRU_PERCPU_HASH}**, for which the memory size must be at
|
|
||||||
* least 4 bytes wide regardless of key size.
|
|
||||||
*
|
*
|
||||||
* The *keys* and *values* are output parameters which must point to memory large enough to
|
* The *keys* and *values* are output parameters which must point to memory large enough to
|
||||||
* hold *count* items based on the key and value size of the map *map_fd*. The *keys*
|
* hold *count* items based on the key and value size of the map *map_fd*. The *keys*
|
||||||
@@ -230,10 +218,7 @@ LIBBPF_API int bpf_map_lookup_batch(int fd, void *in_batch, void *out_batch,
|
|||||||
*
|
*
|
||||||
* @param fd BPF map file descriptor
|
* @param fd BPF map file descriptor
|
||||||
* @param in_batch address of the first element in batch to read, can pass NULL to
|
* @param in_batch address of the first element in batch to read, can pass NULL to
|
||||||
* get address of the first element in *out_batch*. If not NULL, must be large
|
* get address of the first element in *out_batch*
|
||||||
* enough to hold a key. For **BPF_MAP_TYPE_{HASH, PERCPU_HASH, LRU_HASH,
|
|
||||||
* LRU_PERCPU_HASH}**, the memory size must be at least 4 bytes wide regardless
|
|
||||||
* of key size.
|
|
||||||
* @param out_batch output parameter that should be passed to next call as *in_batch*
|
* @param out_batch output parameter that should be passed to next call as *in_batch*
|
||||||
* @param keys pointer to an array of *count* keys
|
* @param keys pointer to an array of *count* keys
|
||||||
* @param values pointer to an array large enough for *count* values
|
* @param values pointer to an array large enough for *count* values
|
||||||
@@ -507,10 +492,7 @@ LIBBPF_API int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len);
|
|||||||
* program corresponding to *prog_fd*.
|
* program corresponding to *prog_fd*.
|
||||||
*
|
*
|
||||||
* Populates up to *info_len* bytes of *info* and updates *info_len* with the
|
* Populates up to *info_len* bytes of *info* and updates *info_len* with the
|
||||||
* actual number of bytes written to *info*. Note that *info* should be
|
* actual number of bytes written to *info*.
|
||||||
* zero-initialized or initialized as expected by the requested *info*
|
|
||||||
* type. Failing to (zero-)initialize *info* under certain circumstances can
|
|
||||||
* result in this helper returning an error.
|
|
||||||
*
|
*
|
||||||
* @param prog_fd BPF program file descriptor
|
* @param prog_fd BPF program file descriptor
|
||||||
* @param info pointer to **struct bpf_prog_info** that will be populated with
|
* @param info pointer to **struct bpf_prog_info** that will be populated with
|
||||||
@@ -527,10 +509,7 @@ LIBBPF_API int bpf_prog_get_info_by_fd(int prog_fd, struct bpf_prog_info *info,
|
|||||||
* map corresponding to *map_fd*.
|
* map corresponding to *map_fd*.
|
||||||
*
|
*
|
||||||
* Populates up to *info_len* bytes of *info* and updates *info_len* with the
|
* Populates up to *info_len* bytes of *info* and updates *info_len* with the
|
||||||
* actual number of bytes written to *info*. Note that *info* should be
|
* actual number of bytes written to *info*.
|
||||||
* zero-initialized or initialized as expected by the requested *info*
|
|
||||||
* type. Failing to (zero-)initialize *info* under certain circumstances can
|
|
||||||
* result in this helper returning an error.
|
|
||||||
*
|
*
|
||||||
* @param map_fd BPF map file descriptor
|
* @param map_fd BPF map file descriptor
|
||||||
* @param info pointer to **struct bpf_map_info** that will be populated with
|
* @param info pointer to **struct bpf_map_info** that will be populated with
|
||||||
@@ -543,14 +522,11 @@ LIBBPF_API int bpf_prog_get_info_by_fd(int prog_fd, struct bpf_prog_info *info,
|
|||||||
LIBBPF_API int bpf_map_get_info_by_fd(int map_fd, struct bpf_map_info *info, __u32 *info_len);
|
LIBBPF_API int bpf_map_get_info_by_fd(int map_fd, struct bpf_map_info *info, __u32 *info_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief **bpf_btf_get_info_by_fd()** obtains information about the
|
* @brief **bpf_btf_get_info_by_fd()** obtains information about the
|
||||||
* BTF object corresponding to *btf_fd*.
|
* BTF object corresponding to *btf_fd*.
|
||||||
*
|
*
|
||||||
* Populates up to *info_len* bytes of *info* and updates *info_len* with the
|
* Populates up to *info_len* bytes of *info* and updates *info_len* with the
|
||||||
* actual number of bytes written to *info*. Note that *info* should be
|
* actual number of bytes written to *info*.
|
||||||
* zero-initialized or initialized as expected by the requested *info*
|
|
||||||
* type. Failing to (zero-)initialize *info* under certain circumstances can
|
|
||||||
* result in this helper returning an error.
|
|
||||||
*
|
*
|
||||||
* @param btf_fd BTF object file descriptor
|
* @param btf_fd BTF object file descriptor
|
||||||
* @param info pointer to **struct bpf_btf_info** that will be populated with
|
* @param info pointer to **struct bpf_btf_info** that will be populated with
|
||||||
@@ -567,10 +543,7 @@ LIBBPF_API int bpf_btf_get_info_by_fd(int btf_fd, struct bpf_btf_info *info, __u
|
|||||||
* link corresponding to *link_fd*.
|
* link corresponding to *link_fd*.
|
||||||
*
|
*
|
||||||
* Populates up to *info_len* bytes of *info* and updates *info_len* with the
|
* Populates up to *info_len* bytes of *info* and updates *info_len* with the
|
||||||
* actual number of bytes written to *info*. Note that *info* should be
|
* actual number of bytes written to *info*.
|
||||||
* zero-initialized or initialized as expected by the requested *info*
|
|
||||||
* type. Failing to (zero-)initialize *info* under certain circumstances can
|
|
||||||
* result in this helper returning an error.
|
|
||||||
*
|
*
|
||||||
* @param link_fd BPF link file descriptor
|
* @param link_fd BPF link file descriptor
|
||||||
* @param info pointer to **struct bpf_link_info** that will be populated with
|
* @param info pointer to **struct bpf_link_info** that will be populated with
|
||||||
@@ -617,15 +590,6 @@ LIBBPF_API int bpf_prog_query(int target_fd, enum bpf_attach_type type,
|
|||||||
__u32 query_flags, __u32 *attach_flags,
|
__u32 query_flags, __u32 *attach_flags,
|
||||||
__u32 *prog_ids, __u32 *prog_cnt);
|
__u32 *prog_ids, __u32 *prog_cnt);
|
||||||
|
|
||||||
struct bpf_raw_tp_opts {
|
|
||||||
size_t sz; /* size of this struct for forward/backward compatibility */
|
|
||||||
const char *tp_name;
|
|
||||||
__u64 cookie;
|
|
||||||
size_t :0;
|
|
||||||
};
|
|
||||||
#define bpf_raw_tp_opts__last_field cookie
|
|
||||||
|
|
||||||
LIBBPF_API int bpf_raw_tracepoint_open_opts(int prog_fd, struct bpf_raw_tp_opts *opts);
|
|
||||||
LIBBPF_API int bpf_raw_tracepoint_open(const char *name, int prog_fd);
|
LIBBPF_API int bpf_raw_tracepoint_open(const char *name, int prog_fd);
|
||||||
LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
|
LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
|
||||||
__u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
|
__u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
|
||||||
@@ -676,30 +640,6 @@ struct bpf_test_run_opts {
|
|||||||
LIBBPF_API int bpf_prog_test_run_opts(int prog_fd,
|
LIBBPF_API int bpf_prog_test_run_opts(int prog_fd,
|
||||||
struct bpf_test_run_opts *opts);
|
struct bpf_test_run_opts *opts);
|
||||||
|
|
||||||
struct bpf_token_create_opts {
|
|
||||||
size_t sz; /* size of this struct for forward/backward compatibility */
|
|
||||||
__u32 flags;
|
|
||||||
size_t :0;
|
|
||||||
};
|
|
||||||
#define bpf_token_create_opts__last_field flags
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief **bpf_token_create()** creates a new instance of BPF token derived
|
|
||||||
* from specified BPF FS mount point.
|
|
||||||
*
|
|
||||||
* BPF token created with this API can be passed to bpf() syscall for
|
|
||||||
* commands like BPF_PROG_LOAD, BPF_MAP_CREATE, etc.
|
|
||||||
*
|
|
||||||
* @param bpffs_fd FD for BPF FS instance from which to derive a BPF token
|
|
||||||
* instance.
|
|
||||||
* @param opts optional BPF token creation options, can be NULL
|
|
||||||
*
|
|
||||||
* @return BPF token FD > 0, on success; negative error code, otherwise (errno
|
|
||||||
* is also set to the error code)
|
|
||||||
*/
|
|
||||||
LIBBPF_API int bpf_token_create(int bpffs_fd,
|
|
||||||
struct bpf_token_create_opts *opts);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
#ifndef __BPF_CORE_READ_H__
|
#ifndef __BPF_CORE_READ_H__
|
||||||
#define __BPF_CORE_READ_H__
|
#define __BPF_CORE_READ_H__
|
||||||
|
|
||||||
#include "bpf_helpers.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* enum bpf_field_info_kind is passed as a second argument into
|
* enum bpf_field_info_kind is passed as a second argument into
|
||||||
* __builtin_preserve_field_info() built-in to get a specific aspect of
|
* __builtin_preserve_field_info() built-in to get a specific aspect of
|
||||||
@@ -46,7 +44,7 @@ enum bpf_enum_value_kind {
|
|||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
#define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \
|
#define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \
|
||||||
bpf_probe_read_kernel( \
|
bpf_probe_read_kernel( \
|
||||||
(void *)dst, \
|
(void *)dst, \
|
||||||
__CORE_RELO(src, fld, BYTE_SIZE), \
|
__CORE_RELO(src, fld, BYTE_SIZE), \
|
||||||
(const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET))
|
(const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET))
|
||||||
#else
|
#else
|
||||||
@@ -145,29 +143,8 @@ enum bpf_enum_value_kind {
|
|||||||
} \
|
} \
|
||||||
})
|
})
|
||||||
|
|
||||||
/* Differentiator between compilers builtin implementations. This is a
|
|
||||||
* requirement due to the compiler parsing differences where GCC optimizes
|
|
||||||
* early in parsing those constructs of type pointers to the builtin specific
|
|
||||||
* type, resulting in not being possible to collect the required type
|
|
||||||
* information in the builtin expansion.
|
|
||||||
*/
|
|
||||||
#ifdef __clang__
|
|
||||||
#define ___bpf_typeof(type) ((typeof(type) *) 0)
|
|
||||||
#else
|
|
||||||
#define ___bpf_typeof1(type, NR) ({ \
|
|
||||||
extern typeof(type) *___concat(bpf_type_tmp_, NR); \
|
|
||||||
___concat(bpf_type_tmp_, NR); \
|
|
||||||
})
|
|
||||||
#define ___bpf_typeof(type) ___bpf_typeof1(type, __COUNTER__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
#define ___bpf_field_ref1(field) (field)
|
#define ___bpf_field_ref1(field) (field)
|
||||||
#define ___bpf_field_ref2(type, field) (___bpf_typeof(type)->field)
|
#define ___bpf_field_ref2(type, field) (((typeof(type) *)0)->field)
|
||||||
#else
|
|
||||||
#define ___bpf_field_ref1(field) (&(field))
|
|
||||||
#define ___bpf_field_ref2(type, field) (&(___bpf_typeof(type)->field))
|
|
||||||
#endif
|
|
||||||
#define ___bpf_field_ref(args...) \
|
#define ___bpf_field_ref(args...) \
|
||||||
___bpf_apply(___bpf_field_ref, ___bpf_narg(args))(args)
|
___bpf_apply(___bpf_field_ref, ___bpf_narg(args))(args)
|
||||||
|
|
||||||
@@ -217,7 +194,7 @@ enum bpf_enum_value_kind {
|
|||||||
* BTF. Always succeeds.
|
* BTF. Always succeeds.
|
||||||
*/
|
*/
|
||||||
#define bpf_core_type_id_local(type) \
|
#define bpf_core_type_id_local(type) \
|
||||||
__builtin_btf_type_id(*___bpf_typeof(type), BPF_TYPE_ID_LOCAL)
|
__builtin_btf_type_id(*(typeof(type) *)0, BPF_TYPE_ID_LOCAL)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convenience macro to get BTF type ID of a target kernel's type that matches
|
* Convenience macro to get BTF type ID of a target kernel's type that matches
|
||||||
@@ -227,7 +204,7 @@ enum bpf_enum_value_kind {
|
|||||||
* - 0, if no matching type was found in a target kernel BTF.
|
* - 0, if no matching type was found in a target kernel BTF.
|
||||||
*/
|
*/
|
||||||
#define bpf_core_type_id_kernel(type) \
|
#define bpf_core_type_id_kernel(type) \
|
||||||
__builtin_btf_type_id(*___bpf_typeof(type), BPF_TYPE_ID_TARGET)
|
__builtin_btf_type_id(*(typeof(type) *)0, BPF_TYPE_ID_TARGET)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convenience macro to check that provided named type
|
* Convenience macro to check that provided named type
|
||||||
@@ -237,7 +214,7 @@ enum bpf_enum_value_kind {
|
|||||||
* 0, if no matching type is found.
|
* 0, if no matching type is found.
|
||||||
*/
|
*/
|
||||||
#define bpf_core_type_exists(type) \
|
#define bpf_core_type_exists(type) \
|
||||||
__builtin_preserve_type_info(*___bpf_typeof(type), BPF_TYPE_EXISTS)
|
__builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_EXISTS)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convenience macro to check that provided named type
|
* Convenience macro to check that provided named type
|
||||||
@@ -247,7 +224,7 @@ enum bpf_enum_value_kind {
|
|||||||
* 0, if the type does not match any in the target kernel
|
* 0, if the type does not match any in the target kernel
|
||||||
*/
|
*/
|
||||||
#define bpf_core_type_matches(type) \
|
#define bpf_core_type_matches(type) \
|
||||||
__builtin_preserve_type_info(*___bpf_typeof(type), BPF_TYPE_MATCHES)
|
__builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_MATCHES)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convenience macro to get the byte size of a provided named type
|
* Convenience macro to get the byte size of a provided named type
|
||||||
@@ -257,7 +234,7 @@ enum bpf_enum_value_kind {
|
|||||||
* 0, if no matching type is found.
|
* 0, if no matching type is found.
|
||||||
*/
|
*/
|
||||||
#define bpf_core_type_size(type) \
|
#define bpf_core_type_size(type) \
|
||||||
__builtin_preserve_type_info(*___bpf_typeof(type), BPF_TYPE_SIZE)
|
__builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_SIZE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convenience macro to check that provided enumerator value is defined in
|
* Convenience macro to check that provided enumerator value is defined in
|
||||||
@@ -267,13 +244,8 @@ enum bpf_enum_value_kind {
|
|||||||
* kernel's BTF;
|
* kernel's BTF;
|
||||||
* 0, if no matching enum and/or enum value within that enum is found.
|
* 0, if no matching enum and/or enum value within that enum is found.
|
||||||
*/
|
*/
|
||||||
#ifdef __clang__
|
|
||||||
#define bpf_core_enum_value_exists(enum_type, enum_value) \
|
#define bpf_core_enum_value_exists(enum_type, enum_value) \
|
||||||
__builtin_preserve_enum_value(*(typeof(enum_type) *)enum_value, BPF_ENUMVAL_EXISTS)
|
__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
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convenience macro to get the integer value of an enumerator value in
|
* Convenience macro to get the integer value of an enumerator value in
|
||||||
@@ -283,13 +255,8 @@ enum bpf_enum_value_kind {
|
|||||||
* present in target kernel's BTF;
|
* present in target kernel's BTF;
|
||||||
* 0, if no matching enum and/or enum value within that enum is found.
|
* 0, if no matching enum and/or enum value within that enum is found.
|
||||||
*/
|
*/
|
||||||
#ifdef __clang__
|
|
||||||
#define bpf_core_enum_value(enum_type, enum_value) \
|
#define bpf_core_enum_value(enum_type, enum_value) \
|
||||||
__builtin_preserve_enum_value(*(typeof(enum_type) *)enum_value, BPF_ENUMVAL_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
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bpf_core_read() abstracts away bpf_probe_read_kernel() call and captures
|
* bpf_core_read() abstracts away bpf_probe_read_kernel() call and captures
|
||||||
@@ -301,7 +268,7 @@ enum bpf_enum_value_kind {
|
|||||||
* a relocation, which records BTF type ID describing root struct/union and an
|
* a relocation, which records BTF type ID describing root struct/union and an
|
||||||
* accessor string which describes exact embedded field that was used to take
|
* accessor string which describes exact embedded field that was used to take
|
||||||
* an address. See detailed description of this relocation format and
|
* an address. See detailed description of this relocation format and
|
||||||
* semantics in comments to struct bpf_core_relo in include/uapi/linux/bpf.h.
|
* semantics in comments to struct bpf_field_reloc in libbpf_internal.h.
|
||||||
*
|
*
|
||||||
* This relocation allows libbpf to adjust BPF instruction to use correct
|
* This relocation allows libbpf to adjust BPF instruction to use correct
|
||||||
* actual field offset, based on target kernel BTF type that matches original
|
* actual field offset, based on target kernel BTF type that matches original
|
||||||
@@ -325,17 +292,6 @@ enum bpf_enum_value_kind {
|
|||||||
#define bpf_core_read_user_str(dst, sz, src) \
|
#define bpf_core_read_user_str(dst, sz, src) \
|
||||||
bpf_probe_read_user_str(dst, sz, (const void *)__builtin_preserve_access_index(src))
|
bpf_probe_read_user_str(dst, sz, (const void *)__builtin_preserve_access_index(src))
|
||||||
|
|
||||||
extern void *bpf_rdonly_cast(const void *obj, __u32 btf_id) __ksym __weak;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Cast 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() macros.
|
|
||||||
*/
|
|
||||||
#define bpf_core_cast(ptr, type) \
|
|
||||||
((typeof(type) *)bpf_rdonly_cast((ptr), bpf_core_type_id_kernel(type)))
|
|
||||||
|
|
||||||
#define ___concat(a, b) a ## b
|
#define ___concat(a, b) a ## b
|
||||||
#define ___apply(fn, n) ___concat(fn, n)
|
#define ___apply(fn, n) ___concat(fn, n)
|
||||||
#define ___nth(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, __11, N, ...) N
|
#define ___nth(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, __11, N, ...) N
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,6 @@
|
|||||||
#define __uint(name, val) int (*name)[val]
|
#define __uint(name, val) int (*name)[val]
|
||||||
#define __type(name, val) typeof(val) *name
|
#define __type(name, val) typeof(val) *name
|
||||||
#define __array(name, val) typeof(val) *name[]
|
#define __array(name, val) typeof(val) *name[]
|
||||||
#define __ulong(name, val) enum { ___bpf_concat(__unique_value, __COUNTER__) = val } name
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper macro to place programs, maps, license in
|
* Helper macro to place programs, maps, license in
|
||||||
@@ -137,8 +136,7 @@
|
|||||||
/*
|
/*
|
||||||
* Helper function to perform a tail call with a constant/immediate map slot.
|
* Helper function to perform a tail call with a constant/immediate map slot.
|
||||||
*/
|
*/
|
||||||
#if (defined(__clang__) && __clang_major__ >= 8) || (!defined(__clang__) && __GNUC__ > 12)
|
#if __clang_major__ >= 8 && defined(__bpf__)
|
||||||
#if defined(__bpf__)
|
|
||||||
static __always_inline void
|
static __always_inline void
|
||||||
bpf_tail_call_static(void *ctx, const void *map, const __u32 slot)
|
bpf_tail_call_static(void *ctx, const void *map, const __u32 slot)
|
||||||
{
|
{
|
||||||
@@ -166,7 +164,6 @@ bpf_tail_call_static(void *ctx, const void *map, const __u32 slot)
|
|||||||
: "r0", "r1", "r2", "r3", "r4", "r5");
|
: "r0", "r1", "r2", "r3", "r4", "r5");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
enum libbpf_pin_type {
|
enum libbpf_pin_type {
|
||||||
LIBBPF_PIN_NONE,
|
LIBBPF_PIN_NONE,
|
||||||
@@ -193,9 +190,6 @@ enum libbpf_tristate {
|
|||||||
|
|
||||||
#define __arg_ctx __attribute__((btf_decl_tag("arg:ctx")))
|
#define __arg_ctx __attribute__((btf_decl_tag("arg:ctx")))
|
||||||
#define __arg_nonnull __attribute((btf_decl_tag("arg:nonnull")))
|
#define __arg_nonnull __attribute((btf_decl_tag("arg:nonnull")))
|
||||||
#define __arg_nullable __attribute((btf_decl_tag("arg:nullable")))
|
|
||||||
#define __arg_trusted __attribute((btf_decl_tag("arg:trusted")))
|
|
||||||
#define __arg_arena __attribute((btf_decl_tag("arg:arena")))
|
|
||||||
|
|
||||||
#ifndef ___bpf_concat
|
#ifndef ___bpf_concat
|
||||||
#define ___bpf_concat(a, b) a ## b
|
#define ___bpf_concat(a, b) a ## b
|
||||||
|
|||||||
43
src/btf.c
43
src/btf.c
@@ -1079,11 +1079,6 @@ struct btf *btf__new(const void *data, __u32 size)
|
|||||||
return libbpf_ptr(btf_new(data, size, NULL));
|
return libbpf_ptr(btf_new(data, size, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct btf *btf__new_split(const void *data, __u32 size, struct btf *base_btf)
|
|
||||||
{
|
|
||||||
return libbpf_ptr(btf_new(data, size, base_btf));
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct btf *btf_parse_elf(const char *path, struct btf *base_btf,
|
static struct btf *btf_parse_elf(const char *path, struct btf *base_btf,
|
||||||
struct btf_ext **btf_ext)
|
struct btf_ext **btf_ext)
|
||||||
{
|
{
|
||||||
@@ -1322,9 +1317,7 @@ struct btf *btf__parse_split(const char *path, struct btf *base_btf)
|
|||||||
|
|
||||||
static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian);
|
static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian);
|
||||||
|
|
||||||
int btf_load_into_kernel(struct btf *btf,
|
int btf_load_into_kernel(struct btf *btf, char *log_buf, size_t log_sz, __u32 log_level)
|
||||||
char *log_buf, size_t log_sz, __u32 log_level,
|
|
||||||
int token_fd)
|
|
||||||
{
|
{
|
||||||
LIBBPF_OPTS(bpf_btf_load_opts, opts);
|
LIBBPF_OPTS(bpf_btf_load_opts, opts);
|
||||||
__u32 buf_sz = 0, raw_size;
|
__u32 buf_sz = 0, raw_size;
|
||||||
@@ -1374,10 +1367,6 @@ retry_load:
|
|||||||
opts.log_level = log_level;
|
opts.log_level = log_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.token_fd = token_fd;
|
|
||||||
if (token_fd)
|
|
||||||
opts.btf_flags |= BPF_F_TOKEN_FD;
|
|
||||||
|
|
||||||
btf->fd = bpf_btf_load(raw_data, raw_size, &opts);
|
btf->fd = bpf_btf_load(raw_data, raw_size, &opts);
|
||||||
if (btf->fd < 0) {
|
if (btf->fd < 0) {
|
||||||
/* time to turn on verbose mode and try again */
|
/* time to turn on verbose mode and try again */
|
||||||
@@ -1405,7 +1394,7 @@ done:
|
|||||||
|
|
||||||
int btf__load_into_kernel(struct btf *btf)
|
int btf__load_into_kernel(struct btf *btf)
|
||||||
{
|
{
|
||||||
return btf_load_into_kernel(btf, NULL, 0, 0, 0);
|
return btf_load_into_kernel(btf, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int btf__fd(const struct btf *btf)
|
int btf__fd(const struct btf *btf)
|
||||||
@@ -3050,16 +3039,12 @@ done:
|
|||||||
return btf_ext;
|
return btf_ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *btf_ext__raw_data(const struct btf_ext *btf_ext, __u32 *size)
|
const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, __u32 *size)
|
||||||
{
|
{
|
||||||
*size = btf_ext->data_size;
|
*size = btf_ext->data_size;
|
||||||
return btf_ext->data;
|
return btf_ext->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((alias("btf_ext__raw_data")))
|
|
||||||
const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, __u32 *size);
|
|
||||||
|
|
||||||
|
|
||||||
struct btf_dedup;
|
struct btf_dedup;
|
||||||
|
|
||||||
static struct btf_dedup *btf_dedup_new(struct btf *btf, const struct btf_dedup_opts *opts);
|
static struct btf_dedup *btf_dedup_new(struct btf *btf, const struct btf_dedup_opts *opts);
|
||||||
@@ -4941,9 +4926,10 @@ static int btf_dedup_remap_types(struct btf_dedup *d)
|
|||||||
*/
|
*/
|
||||||
struct btf *btf__load_vmlinux_btf(void)
|
struct btf *btf__load_vmlinux_btf(void)
|
||||||
{
|
{
|
||||||
const char *sysfs_btf_path = "/sys/kernel/btf/vmlinux";
|
|
||||||
/* fall back locations, trying to find vmlinux on disk */
|
|
||||||
const char *locations[] = {
|
const char *locations[] = {
|
||||||
|
/* try canonical vmlinux BTF through sysfs first */
|
||||||
|
"/sys/kernel/btf/vmlinux",
|
||||||
|
/* fall back to trying to find vmlinux on disk otherwise */
|
||||||
"/boot/vmlinux-%1$s",
|
"/boot/vmlinux-%1$s",
|
||||||
"/lib/modules/%1$s/vmlinux-%1$s",
|
"/lib/modules/%1$s/vmlinux-%1$s",
|
||||||
"/lib/modules/%1$s/build/vmlinux",
|
"/lib/modules/%1$s/build/vmlinux",
|
||||||
@@ -4957,23 +4943,8 @@ struct btf *btf__load_vmlinux_btf(void)
|
|||||||
struct btf *btf;
|
struct btf *btf;
|
||||||
int i, err;
|
int i, err;
|
||||||
|
|
||||||
/* is canonical sysfs location accessible? */
|
|
||||||
if (faccessat(AT_FDCWD, sysfs_btf_path, F_OK, AT_EACCESS) < 0) {
|
|
||||||
pr_warn("kernel BTF is missing at '%s', was CONFIG_DEBUG_INFO_BTF enabled?\n",
|
|
||||||
sysfs_btf_path);
|
|
||||||
} else {
|
|
||||||
btf = btf__parse(sysfs_btf_path, NULL);
|
|
||||||
if (!btf) {
|
|
||||||
err = -errno;
|
|
||||||
pr_warn("failed to read kernel BTF from '%s': %d\n", sysfs_btf_path, err);
|
|
||||||
return libbpf_err_ptr(err);
|
|
||||||
}
|
|
||||||
pr_debug("loaded kernel BTF from '%s'\n", sysfs_btf_path);
|
|
||||||
return btf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* try fallback locations */
|
|
||||||
uname(&buf);
|
uname(&buf);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(locations); i++) {
|
for (i = 0; i < ARRAY_SIZE(locations); i++) {
|
||||||
snprintf(path, PATH_MAX, locations[i], buf.release);
|
snprintf(path, PATH_MAX, locations[i], buf.release);
|
||||||
|
|
||||||
|
|||||||
@@ -1929,7 +1929,6 @@ static int btf_dump_int_data(struct btf_dump *d,
|
|||||||
if (d->typed_dump->is_array_terminated)
|
if (d->typed_dump->is_array_terminated)
|
||||||
break;
|
break;
|
||||||
if (*(char *)data == '\0') {
|
if (*(char *)data == '\0') {
|
||||||
btf_dump_type_values(d, "'\\0'");
|
|
||||||
d->typed_dump->is_array_terminated = true;
|
d->typed_dump->is_array_terminated = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2032,7 +2031,6 @@ static int btf_dump_array_data(struct btf_dump *d,
|
|||||||
__u32 i, elem_type_id;
|
__u32 i, elem_type_id;
|
||||||
__s64 elem_size;
|
__s64 elem_size;
|
||||||
bool is_array_member;
|
bool is_array_member;
|
||||||
bool is_array_terminated;
|
|
||||||
|
|
||||||
elem_type_id = array->type;
|
elem_type_id = array->type;
|
||||||
elem_type = skip_mods_and_typedefs(d->btf, elem_type_id, NULL);
|
elem_type = skip_mods_and_typedefs(d->btf, elem_type_id, NULL);
|
||||||
@@ -2068,15 +2066,12 @@ static int btf_dump_array_data(struct btf_dump *d,
|
|||||||
*/
|
*/
|
||||||
is_array_member = d->typed_dump->is_array_member;
|
is_array_member = d->typed_dump->is_array_member;
|
||||||
d->typed_dump->is_array_member = true;
|
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) {
|
for (i = 0; i < array->nelems; i++, data += elem_size) {
|
||||||
if (d->typed_dump->is_array_terminated)
|
if (d->typed_dump->is_array_terminated)
|
||||||
break;
|
break;
|
||||||
btf_dump_dump_type_data(d, NULL, elem_type, elem_type_id, data, 0, 0);
|
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_member = is_array_member;
|
||||||
d->typed_dump->is_array_terminated = is_array_terminated;
|
|
||||||
d->typed_dump->depth--;
|
d->typed_dump->depth--;
|
||||||
btf_dump_data_pfx(d);
|
btf_dump_data_pfx(d);
|
||||||
btf_dump_type_values(d, "]");
|
btf_dump_type_values(d, "]");
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#include "libbpf_internal.h"
|
#include "libbpf_internal.h"
|
||||||
#include "str_error.h"
|
#include "str_error.h"
|
||||||
|
|
||||||
|
#define STRERR_BUFSIZE 128
|
||||||
|
|
||||||
/* A SHT_GNU_versym section holds 16-bit words. This bit is set if
|
/* A SHT_GNU_versym section holds 16-bit words. This bit is set if
|
||||||
* the symbol is hidden and can only be seen when referenced using an
|
* the symbol is hidden and can only be seen when referenced using an
|
||||||
* explicit version number. This is a GNU extension.
|
* explicit version number. This is a GNU extension.
|
||||||
|
|||||||
583
src/features.c
583
src/features.c
@@ -1,583 +0,0 @@
|
|||||||
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
|
||||||
/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/filter.h>
|
|
||||||
#include "bpf.h"
|
|
||||||
#include "libbpf.h"
|
|
||||||
#include "libbpf_common.h"
|
|
||||||
#include "libbpf_internal.h"
|
|
||||||
#include "str_error.h"
|
|
||||||
|
|
||||||
static inline __u64 ptr_to_u64(const void *ptr)
|
|
||||||
{
|
|
||||||
return (__u64)(unsigned long)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int probe_fd(int fd)
|
|
||||||
{
|
|
||||||
if (fd >= 0)
|
|
||||||
close(fd);
|
|
||||||
return fd >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_prog_name(int token_fd)
|
|
||||||
{
|
|
||||||
const size_t attr_sz = offsetofend(union bpf_attr, prog_name);
|
|
||||||
struct bpf_insn insns[] = {
|
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
||||||
BPF_EXIT_INSN(),
|
|
||||||
};
|
|
||||||
union bpf_attr attr;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(&attr, 0, attr_sz);
|
|
||||||
attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
|
|
||||||
attr.license = ptr_to_u64("GPL");
|
|
||||||
attr.insns = ptr_to_u64(insns);
|
|
||||||
attr.insn_cnt = (__u32)ARRAY_SIZE(insns);
|
|
||||||
attr.prog_token_fd = token_fd;
|
|
||||||
if (token_fd)
|
|
||||||
attr.prog_flags |= BPF_F_TOKEN_FD;
|
|
||||||
libbpf_strlcpy(attr.prog_name, "libbpf_nametest", sizeof(attr.prog_name));
|
|
||||||
|
|
||||||
/* make sure loading with name works */
|
|
||||||
ret = sys_bpf_prog_load(&attr, attr_sz, PROG_LOAD_ATTEMPTS);
|
|
||||||
return probe_fd(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_global_data(int token_fd)
|
|
||||||
{
|
|
||||||
char *cp, errmsg[STRERR_BUFSIZE];
|
|
||||||
struct bpf_insn insns[] = {
|
|
||||||
BPF_LD_MAP_VALUE(BPF_REG_1, 0, 16),
|
|
||||||
BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
|
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
||||||
BPF_EXIT_INSN(),
|
|
||||||
};
|
|
||||||
LIBBPF_OPTS(bpf_map_create_opts, map_opts,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.map_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
LIBBPF_OPTS(bpf_prog_load_opts, prog_opts,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.prog_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
int ret, map, insn_cnt = ARRAY_SIZE(insns);
|
|
||||||
|
|
||||||
map = bpf_map_create(BPF_MAP_TYPE_ARRAY, "libbpf_global", sizeof(int), 32, 1, &map_opts);
|
|
||||||
if (map < 0) {
|
|
||||||
ret = -errno;
|
|
||||||
cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg));
|
|
||||||
pr_warn("Error in %s():%s(%d). Couldn't create simple array map.\n",
|
|
||||||
__func__, cp, -ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
insns[0].imm = map;
|
|
||||||
|
|
||||||
ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, &prog_opts);
|
|
||||||
close(map);
|
|
||||||
return probe_fd(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_btf(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0int";
|
|
||||||
__u32 types[] = {
|
|
||||||
/* int */
|
|
||||||
BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4),
|
|
||||||
};
|
|
||||||
|
|
||||||
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
|
|
||||||
strs, sizeof(strs), token_fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_btf_func(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0int\0x\0a";
|
|
||||||
/* void x(int a) {} */
|
|
||||||
__u32 types[] = {
|
|
||||||
/* int */
|
|
||||||
BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
|
|
||||||
/* FUNC_PROTO */ /* [2] */
|
|
||||||
BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 0),
|
|
||||||
BTF_PARAM_ENC(7, 1),
|
|
||||||
/* FUNC x */ /* [3] */
|
|
||||||
BTF_TYPE_ENC(5, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0), 2),
|
|
||||||
};
|
|
||||||
|
|
||||||
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
|
|
||||||
strs, sizeof(strs), token_fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_btf_func_global(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0int\0x\0a";
|
|
||||||
/* static void x(int a) {} */
|
|
||||||
__u32 types[] = {
|
|
||||||
/* int */
|
|
||||||
BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
|
|
||||||
/* FUNC_PROTO */ /* [2] */
|
|
||||||
BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 0),
|
|
||||||
BTF_PARAM_ENC(7, 1),
|
|
||||||
/* FUNC x BTF_FUNC_GLOBAL */ /* [3] */
|
|
||||||
BTF_TYPE_ENC(5, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 2),
|
|
||||||
};
|
|
||||||
|
|
||||||
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
|
|
||||||
strs, sizeof(strs), token_fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_btf_datasec(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0x\0.data";
|
|
||||||
/* static int a; */
|
|
||||||
__u32 types[] = {
|
|
||||||
/* int */
|
|
||||||
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
|
|
||||||
/* VAR x */ /* [2] */
|
|
||||||
BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1),
|
|
||||||
BTF_VAR_STATIC,
|
|
||||||
/* DATASEC val */ /* [3] */
|
|
||||||
BTF_TYPE_ENC(3, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
|
|
||||||
BTF_VAR_SECINFO_ENC(2, 0, 4),
|
|
||||||
};
|
|
||||||
|
|
||||||
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
|
|
||||||
strs, sizeof(strs), token_fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_btf_qmark_datasec(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0x\0?.data";
|
|
||||||
/* static int a; */
|
|
||||||
__u32 types[] = {
|
|
||||||
/* int */
|
|
||||||
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
|
|
||||||
/* VAR x */ /* [2] */
|
|
||||||
BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1),
|
|
||||||
BTF_VAR_STATIC,
|
|
||||||
/* DATASEC ?.data */ /* [3] */
|
|
||||||
BTF_TYPE_ENC(3, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
|
|
||||||
BTF_VAR_SECINFO_ENC(2, 0, 4),
|
|
||||||
};
|
|
||||||
|
|
||||||
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
|
|
||||||
strs, sizeof(strs), token_fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_btf_float(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0float";
|
|
||||||
__u32 types[] = {
|
|
||||||
/* float */
|
|
||||||
BTF_TYPE_FLOAT_ENC(1, 4),
|
|
||||||
};
|
|
||||||
|
|
||||||
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
|
|
||||||
strs, sizeof(strs), token_fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_btf_decl_tag(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0tag";
|
|
||||||
__u32 types[] = {
|
|
||||||
/* int */
|
|
||||||
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
|
|
||||||
/* VAR x */ /* [2] */
|
|
||||||
BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1),
|
|
||||||
BTF_VAR_STATIC,
|
|
||||||
/* attr */
|
|
||||||
BTF_TYPE_DECL_TAG_ENC(1, 2, -1),
|
|
||||||
};
|
|
||||||
|
|
||||||
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
|
|
||||||
strs, sizeof(strs), token_fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_btf_type_tag(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0tag";
|
|
||||||
__u32 types[] = {
|
|
||||||
/* int */
|
|
||||||
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
|
|
||||||
/* attr */
|
|
||||||
BTF_TYPE_TYPE_TAG_ENC(1, 1), /* [2] */
|
|
||||||
/* ptr */
|
|
||||||
BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2), /* [3] */
|
|
||||||
};
|
|
||||||
|
|
||||||
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
|
|
||||||
strs, sizeof(strs), token_fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_array_mmap(int token_fd)
|
|
||||||
{
|
|
||||||
LIBBPF_OPTS(bpf_map_create_opts, opts,
|
|
||||||
.map_flags = BPF_F_MMAPABLE | (token_fd ? BPF_F_TOKEN_FD : 0),
|
|
||||||
.token_fd = token_fd,
|
|
||||||
);
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "libbpf_mmap", sizeof(int), sizeof(int), 1, &opts);
|
|
||||||
return probe_fd(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_exp_attach_type(int token_fd)
|
|
||||||
{
|
|
||||||
LIBBPF_OPTS(bpf_prog_load_opts, opts,
|
|
||||||
.expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.prog_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
struct bpf_insn insns[] = {
|
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
||||||
BPF_EXIT_INSN(),
|
|
||||||
};
|
|
||||||
int fd, insn_cnt = ARRAY_SIZE(insns);
|
|
||||||
|
|
||||||
/* use any valid combination of program type and (optional)
|
|
||||||
* non-zero expected attach type (i.e., not a BPF_CGROUP_INET_INGRESS)
|
|
||||||
* to see if kernel supports expected_attach_type field for
|
|
||||||
* BPF_PROG_LOAD command
|
|
||||||
*/
|
|
||||||
fd = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SOCK, NULL, "GPL", insns, insn_cnt, &opts);
|
|
||||||
return probe_fd(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_probe_read_kernel(int token_fd)
|
|
||||||
{
|
|
||||||
LIBBPF_OPTS(bpf_prog_load_opts, opts,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.prog_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
struct bpf_insn insns[] = {
|
|
||||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), /* r1 = r10 (fp) */
|
|
||||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), /* r1 += -8 */
|
|
||||||
BPF_MOV64_IMM(BPF_REG_2, 8), /* r2 = 8 */
|
|
||||||
BPF_MOV64_IMM(BPF_REG_3, 0), /* r3 = 0 */
|
|
||||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_probe_read_kernel),
|
|
||||||
BPF_EXIT_INSN(),
|
|
||||||
};
|
|
||||||
int fd, insn_cnt = ARRAY_SIZE(insns);
|
|
||||||
|
|
||||||
fd = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", insns, insn_cnt, &opts);
|
|
||||||
return probe_fd(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_prog_bind_map(int token_fd)
|
|
||||||
{
|
|
||||||
char *cp, errmsg[STRERR_BUFSIZE];
|
|
||||||
struct bpf_insn insns[] = {
|
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
||||||
BPF_EXIT_INSN(),
|
|
||||||
};
|
|
||||||
LIBBPF_OPTS(bpf_map_create_opts, map_opts,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.map_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
LIBBPF_OPTS(bpf_prog_load_opts, prog_opts,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.prog_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
int ret, map, prog, insn_cnt = ARRAY_SIZE(insns);
|
|
||||||
|
|
||||||
map = bpf_map_create(BPF_MAP_TYPE_ARRAY, "libbpf_det_bind", sizeof(int), 32, 1, &map_opts);
|
|
||||||
if (map < 0) {
|
|
||||||
ret = -errno;
|
|
||||||
cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg));
|
|
||||||
pr_warn("Error in %s():%s(%d). Couldn't create simple array map.\n",
|
|
||||||
__func__, cp, -ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
prog = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, &prog_opts);
|
|
||||||
if (prog < 0) {
|
|
||||||
close(map);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bpf_prog_bind_map(prog, map, NULL);
|
|
||||||
|
|
||||||
close(map);
|
|
||||||
close(prog);
|
|
||||||
|
|
||||||
return ret >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_module_btf(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0int";
|
|
||||||
__u32 types[] = {
|
|
||||||
/* int */
|
|
||||||
BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4),
|
|
||||||
};
|
|
||||||
struct bpf_btf_info info;
|
|
||||||
__u32 len = sizeof(info);
|
|
||||||
char name[16];
|
|
||||||
int fd, err;
|
|
||||||
|
|
||||||
fd = libbpf__load_raw_btf((char *)types, sizeof(types), strs, sizeof(strs), token_fd);
|
|
||||||
if (fd < 0)
|
|
||||||
return 0; /* BTF not supported at all */
|
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
|
||||||
info.name = ptr_to_u64(name);
|
|
||||||
info.name_len = sizeof(name);
|
|
||||||
|
|
||||||
/* check that BPF_OBJ_GET_INFO_BY_FD supports specifying name pointer;
|
|
||||||
* kernel's module BTF support coincides with support for
|
|
||||||
* name/name_len fields in struct bpf_btf_info.
|
|
||||||
*/
|
|
||||||
err = bpf_btf_get_info_by_fd(fd, &info, &len);
|
|
||||||
close(fd);
|
|
||||||
return !err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_perf_link(int token_fd)
|
|
||||||
{
|
|
||||||
struct bpf_insn insns[] = {
|
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
||||||
BPF_EXIT_INSN(),
|
|
||||||
};
|
|
||||||
LIBBPF_OPTS(bpf_prog_load_opts, opts,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.prog_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
int prog_fd, link_fd, err;
|
|
||||||
|
|
||||||
prog_fd = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL",
|
|
||||||
insns, ARRAY_SIZE(insns), &opts);
|
|
||||||
if (prog_fd < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
/* use invalid perf_event FD to get EBADF, if link is supported;
|
|
||||||
* otherwise EINVAL should be returned
|
|
||||||
*/
|
|
||||||
link_fd = bpf_link_create(prog_fd, -1, BPF_PERF_EVENT, NULL);
|
|
||||||
err = -errno; /* close() can clobber errno */
|
|
||||||
|
|
||||||
if (link_fd >= 0)
|
|
||||||
close(link_fd);
|
|
||||||
close(prog_fd);
|
|
||||||
|
|
||||||
return link_fd < 0 && err == -EBADF;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_uprobe_multi_link(int token_fd)
|
|
||||||
{
|
|
||||||
LIBBPF_OPTS(bpf_prog_load_opts, load_opts,
|
|
||||||
.expected_attach_type = BPF_TRACE_UPROBE_MULTI,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.prog_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
LIBBPF_OPTS(bpf_link_create_opts, link_opts);
|
|
||||||
struct bpf_insn insns[] = {
|
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
|
||||||
BPF_EXIT_INSN(),
|
|
||||||
};
|
|
||||||
int prog_fd, link_fd, err;
|
|
||||||
unsigned long offset = 0;
|
|
||||||
|
|
||||||
prog_fd = bpf_prog_load(BPF_PROG_TYPE_KPROBE, NULL, "GPL",
|
|
||||||
insns, ARRAY_SIZE(insns), &load_opts);
|
|
||||||
if (prog_fd < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
/* Creating uprobe in '/' binary should fail with -EBADF. */
|
|
||||||
link_opts.uprobe_multi.path = "/";
|
|
||||||
link_opts.uprobe_multi.offsets = &offset;
|
|
||||||
link_opts.uprobe_multi.cnt = 1;
|
|
||||||
|
|
||||||
link_fd = bpf_link_create(prog_fd, -1, BPF_TRACE_UPROBE_MULTI, &link_opts);
|
|
||||||
err = -errno; /* close() can clobber errno */
|
|
||||||
|
|
||||||
if (link_fd >= 0)
|
|
||||||
close(link_fd);
|
|
||||||
close(prog_fd);
|
|
||||||
|
|
||||||
return link_fd < 0 && err == -EBADF;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_bpf_cookie(int token_fd)
|
|
||||||
{
|
|
||||||
struct bpf_insn insns[] = {
|
|
||||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_attach_cookie),
|
|
||||||
BPF_EXIT_INSN(),
|
|
||||||
};
|
|
||||||
LIBBPF_OPTS(bpf_prog_load_opts, opts,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.prog_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
int ret, insn_cnt = ARRAY_SIZE(insns);
|
|
||||||
|
|
||||||
ret = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", insns, insn_cnt, &opts);
|
|
||||||
return probe_fd(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_btf_enum64(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0enum64";
|
|
||||||
__u32 types[] = {
|
|
||||||
BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 0), 8),
|
|
||||||
};
|
|
||||||
|
|
||||||
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
|
|
||||||
strs, sizeof(strs), token_fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int probe_kern_arg_ctx_tag(int token_fd)
|
|
||||||
{
|
|
||||||
static const char strs[] = "\0a\0b\0arg:ctx\0";
|
|
||||||
const __u32 types[] = {
|
|
||||||
/* [1] INT */
|
|
||||||
BTF_TYPE_INT_ENC(1 /* "a" */, BTF_INT_SIGNED, 0, 32, 4),
|
|
||||||
/* [2] PTR -> VOID */
|
|
||||||
BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
|
|
||||||
/* [3] FUNC_PROTO `int(void *a)` */
|
|
||||||
BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 1),
|
|
||||||
BTF_PARAM_ENC(1 /* "a" */, 2),
|
|
||||||
/* [4] FUNC 'a' -> FUNC_PROTO (main prog) */
|
|
||||||
BTF_TYPE_ENC(1 /* "a" */, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 3),
|
|
||||||
/* [5] FUNC_PROTO `int(void *b __arg_ctx)` */
|
|
||||||
BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 1),
|
|
||||||
BTF_PARAM_ENC(3 /* "b" */, 2),
|
|
||||||
/* [6] FUNC 'b' -> FUNC_PROTO (subprog) */
|
|
||||||
BTF_TYPE_ENC(3 /* "b" */, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 5),
|
|
||||||
/* [7] DECL_TAG 'arg:ctx' -> func 'b' arg 'b' */
|
|
||||||
BTF_TYPE_DECL_TAG_ENC(5 /* "arg:ctx" */, 6, 0),
|
|
||||||
};
|
|
||||||
const struct bpf_insn insns[] = {
|
|
||||||
/* main prog */
|
|
||||||
BPF_CALL_REL(+1),
|
|
||||||
BPF_EXIT_INSN(),
|
|
||||||
/* global subprog */
|
|
||||||
BPF_EMIT_CALL(BPF_FUNC_get_func_ip), /* needs PTR_TO_CTX */
|
|
||||||
BPF_EXIT_INSN(),
|
|
||||||
};
|
|
||||||
const struct bpf_func_info_min func_infos[] = {
|
|
||||||
{ 0, 4 }, /* main prog -> FUNC 'a' */
|
|
||||||
{ 2, 6 }, /* subprog -> FUNC 'b' */
|
|
||||||
};
|
|
||||||
LIBBPF_OPTS(bpf_prog_load_opts, opts,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.prog_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
int prog_fd, btf_fd, insn_cnt = ARRAY_SIZE(insns);
|
|
||||||
|
|
||||||
btf_fd = libbpf__load_raw_btf((char *)types, sizeof(types), strs, sizeof(strs), token_fd);
|
|
||||||
if (btf_fd < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
opts.prog_btf_fd = btf_fd;
|
|
||||||
opts.func_info = &func_infos;
|
|
||||||
opts.func_info_cnt = ARRAY_SIZE(func_infos);
|
|
||||||
opts.func_info_rec_size = sizeof(func_infos[0]);
|
|
||||||
|
|
||||||
prog_fd = bpf_prog_load(BPF_PROG_TYPE_KPROBE, "det_arg_ctx",
|
|
||||||
"GPL", insns, insn_cnt, &opts);
|
|
||||||
close(btf_fd);
|
|
||||||
|
|
||||||
return probe_fd(prog_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef int (*feature_probe_fn)(int /* token_fd */);
|
|
||||||
|
|
||||||
static struct kern_feature_cache feature_cache;
|
|
||||||
|
|
||||||
static struct kern_feature_desc {
|
|
||||||
const char *desc;
|
|
||||||
feature_probe_fn probe;
|
|
||||||
} feature_probes[__FEAT_CNT] = {
|
|
||||||
[FEAT_PROG_NAME] = {
|
|
||||||
"BPF program name", probe_kern_prog_name,
|
|
||||||
},
|
|
||||||
[FEAT_GLOBAL_DATA] = {
|
|
||||||
"global variables", probe_kern_global_data,
|
|
||||||
},
|
|
||||||
[FEAT_BTF] = {
|
|
||||||
"minimal BTF", probe_kern_btf,
|
|
||||||
},
|
|
||||||
[FEAT_BTF_FUNC] = {
|
|
||||||
"BTF functions", probe_kern_btf_func,
|
|
||||||
},
|
|
||||||
[FEAT_BTF_GLOBAL_FUNC] = {
|
|
||||||
"BTF global function", probe_kern_btf_func_global,
|
|
||||||
},
|
|
||||||
[FEAT_BTF_DATASEC] = {
|
|
||||||
"BTF data section and variable", probe_kern_btf_datasec,
|
|
||||||
},
|
|
||||||
[FEAT_ARRAY_MMAP] = {
|
|
||||||
"ARRAY map mmap()", probe_kern_array_mmap,
|
|
||||||
},
|
|
||||||
[FEAT_EXP_ATTACH_TYPE] = {
|
|
||||||
"BPF_PROG_LOAD expected_attach_type attribute",
|
|
||||||
probe_kern_exp_attach_type,
|
|
||||||
},
|
|
||||||
[FEAT_PROBE_READ_KERN] = {
|
|
||||||
"bpf_probe_read_kernel() helper", probe_kern_probe_read_kernel,
|
|
||||||
},
|
|
||||||
[FEAT_PROG_BIND_MAP] = {
|
|
||||||
"BPF_PROG_BIND_MAP support", probe_prog_bind_map,
|
|
||||||
},
|
|
||||||
[FEAT_MODULE_BTF] = {
|
|
||||||
"module BTF support", probe_module_btf,
|
|
||||||
},
|
|
||||||
[FEAT_BTF_FLOAT] = {
|
|
||||||
"BTF_KIND_FLOAT support", probe_kern_btf_float,
|
|
||||||
},
|
|
||||||
[FEAT_PERF_LINK] = {
|
|
||||||
"BPF perf link support", probe_perf_link,
|
|
||||||
},
|
|
||||||
[FEAT_BTF_DECL_TAG] = {
|
|
||||||
"BTF_KIND_DECL_TAG support", probe_kern_btf_decl_tag,
|
|
||||||
},
|
|
||||||
[FEAT_BTF_TYPE_TAG] = {
|
|
||||||
"BTF_KIND_TYPE_TAG support", probe_kern_btf_type_tag,
|
|
||||||
},
|
|
||||||
[FEAT_MEMCG_ACCOUNT] = {
|
|
||||||
"memcg-based memory accounting", probe_memcg_account,
|
|
||||||
},
|
|
||||||
[FEAT_BPF_COOKIE] = {
|
|
||||||
"BPF cookie support", probe_kern_bpf_cookie,
|
|
||||||
},
|
|
||||||
[FEAT_BTF_ENUM64] = {
|
|
||||||
"BTF_KIND_ENUM64 support", probe_kern_btf_enum64,
|
|
||||||
},
|
|
||||||
[FEAT_SYSCALL_WRAPPER] = {
|
|
||||||
"Kernel using syscall wrapper", probe_kern_syscall_wrapper,
|
|
||||||
},
|
|
||||||
[FEAT_UPROBE_MULTI_LINK] = {
|
|
||||||
"BPF multi-uprobe link support", probe_uprobe_multi_link,
|
|
||||||
},
|
|
||||||
[FEAT_ARG_CTX_TAG] = {
|
|
||||||
"kernel-side __arg_ctx tag", probe_kern_arg_ctx_tag,
|
|
||||||
},
|
|
||||||
[FEAT_BTF_QMARK_DATASEC] = {
|
|
||||||
"BTF DATASEC names starting from '?'", probe_kern_btf_qmark_datasec,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id)
|
|
||||||
{
|
|
||||||
struct kern_feature_desc *feat = &feature_probes[feat_id];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* assume global feature cache, unless custom one is provided */
|
|
||||||
if (!cache)
|
|
||||||
cache = &feature_cache;
|
|
||||||
|
|
||||||
if (READ_ONCE(cache->res[feat_id]) == FEAT_UNKNOWN) {
|
|
||||||
ret = feat->probe(cache->token_fd);
|
|
||||||
if (ret > 0) {
|
|
||||||
WRITE_ONCE(cache->res[feat_id], FEAT_SUPPORTED);
|
|
||||||
} else if (ret == 0) {
|
|
||||||
WRITE_ONCE(cache->res[feat_id], FEAT_MISSING);
|
|
||||||
} else {
|
|
||||||
pr_warn("Detection of kernel %s support failed: %d\n", feat->desc, ret);
|
|
||||||
WRITE_ONCE(cache->res[feat_id], FEAT_MISSING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return READ_ONCE(cache->res[feat_id]) == FEAT_SUPPORTED;
|
|
||||||
}
|
|
||||||
1419
src/libbpf.c
1419
src/libbpf.c
File diff suppressed because it is too large
Load Diff
52
src/libbpf.h
52
src/libbpf.h
@@ -177,29 +177,10 @@ struct bpf_object_open_opts {
|
|||||||
* logs through its print callback.
|
* logs through its print callback.
|
||||||
*/
|
*/
|
||||||
__u32 kernel_log_level;
|
__u32 kernel_log_level;
|
||||||
/* Path to BPF FS mount point to derive BPF token from.
|
|
||||||
*
|
|
||||||
* Created BPF token will be used for all bpf() syscall operations
|
|
||||||
* that accept BPF token (e.g., map creation, BTF and program loads,
|
|
||||||
* etc) automatically within instantiated BPF object.
|
|
||||||
*
|
|
||||||
* If bpf_token_path is not specified, libbpf will consult
|
|
||||||
* LIBBPF_BPF_TOKEN_PATH environment variable. If set, it will be
|
|
||||||
* taken as a value of bpf_token_path option and will force libbpf to
|
|
||||||
* either create BPF token from provided custom BPF FS path, or will
|
|
||||||
* disable implicit BPF token creation, if envvar value is an empty
|
|
||||||
* string. bpf_token_path overrides LIBBPF_BPF_TOKEN_PATH, if both are
|
|
||||||
* set at the same time.
|
|
||||||
*
|
|
||||||
* Setting bpf_token_path option to empty string disables libbpf's
|
|
||||||
* automatic attempt to create BPF token from default BPF FS mount
|
|
||||||
* point (/sys/fs/bpf), in case this default behavior is undesirable.
|
|
||||||
*/
|
|
||||||
const char *bpf_token_path;
|
|
||||||
|
|
||||||
size_t :0;
|
size_t :0;
|
||||||
};
|
};
|
||||||
#define bpf_object_open_opts__last_field bpf_token_path
|
#define bpf_object_open_opts__last_field kernel_log_level
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief **bpf_object__open()** creates a bpf_object by opening
|
* @brief **bpf_object__open()** creates a bpf_object by opening
|
||||||
@@ -539,12 +520,10 @@ struct bpf_kprobe_multi_opts {
|
|||||||
size_t cnt;
|
size_t cnt;
|
||||||
/* create return kprobes */
|
/* create return kprobes */
|
||||||
bool retprobe;
|
bool retprobe;
|
||||||
/* create session kprobes */
|
|
||||||
bool session;
|
|
||||||
size_t :0;
|
size_t :0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define bpf_kprobe_multi_opts__last_field session
|
#define bpf_kprobe_multi_opts__last_field retprobe
|
||||||
|
|
||||||
LIBBPF_API struct bpf_link *
|
LIBBPF_API struct bpf_link *
|
||||||
bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
||||||
@@ -762,20 +741,9 @@ bpf_program__attach_tracepoint_opts(const struct bpf_program *prog,
|
|||||||
const char *tp_name,
|
const char *tp_name,
|
||||||
const struct bpf_tracepoint_opts *opts);
|
const struct bpf_tracepoint_opts *opts);
|
||||||
|
|
||||||
struct bpf_raw_tracepoint_opts {
|
|
||||||
size_t sz; /* size of this struct for forward/backward compatibility */
|
|
||||||
__u64 cookie;
|
|
||||||
size_t :0;
|
|
||||||
};
|
|
||||||
#define bpf_raw_tracepoint_opts__last_field cookie
|
|
||||||
|
|
||||||
LIBBPF_API struct bpf_link *
|
LIBBPF_API struct bpf_link *
|
||||||
bpf_program__attach_raw_tracepoint(const struct bpf_program *prog,
|
bpf_program__attach_raw_tracepoint(const struct bpf_program *prog,
|
||||||
const char *tp_name);
|
const char *tp_name);
|
||||||
LIBBPF_API struct bpf_link *
|
|
||||||
bpf_program__attach_raw_tracepoint_opts(const struct bpf_program *prog,
|
|
||||||
const char *tp_name,
|
|
||||||
struct bpf_raw_tracepoint_opts *opts);
|
|
||||||
|
|
||||||
struct bpf_trace_opts {
|
struct bpf_trace_opts {
|
||||||
/* size of this struct, for forward/backward compatibility */
|
/* size of this struct, for forward/backward compatibility */
|
||||||
@@ -797,8 +765,6 @@ bpf_program__attach_cgroup(const struct bpf_program *prog, int cgroup_fd);
|
|||||||
LIBBPF_API struct bpf_link *
|
LIBBPF_API struct bpf_link *
|
||||||
bpf_program__attach_netns(const struct bpf_program *prog, int netns_fd);
|
bpf_program__attach_netns(const struct bpf_program *prog, int netns_fd);
|
||||||
LIBBPF_API struct bpf_link *
|
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);
|
bpf_program__attach_xdp(const struct bpf_program *prog, int ifindex);
|
||||||
LIBBPF_API struct bpf_link *
|
LIBBPF_API struct bpf_link *
|
||||||
bpf_program__attach_freplace(const struct bpf_program *prog,
|
bpf_program__attach_freplace(const struct bpf_program *prog,
|
||||||
@@ -1029,7 +995,7 @@ LIBBPF_API int bpf_map__set_map_extra(struct bpf_map *map, __u64 map_extra);
|
|||||||
|
|
||||||
LIBBPF_API int bpf_map__set_initial_value(struct bpf_map *map,
|
LIBBPF_API int bpf_map__set_initial_value(struct bpf_map *map,
|
||||||
const void *data, size_t size);
|
const void *data, size_t size);
|
||||||
LIBBPF_API void *bpf_map__initial_value(const struct bpf_map *map, size_t *psize);
|
LIBBPF_API void *bpf_map__initial_value(struct bpf_map *map, size_t *psize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief **bpf_map__is_internal()** tells the caller whether or not the
|
* @brief **bpf_map__is_internal()** tells the caller whether or not the
|
||||||
@@ -1297,7 +1263,6 @@ LIBBPF_API int ring_buffer__add(struct ring_buffer *rb, int map_fd,
|
|||||||
ring_buffer_sample_fn sample_cb, void *ctx);
|
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__poll(struct ring_buffer *rb, int timeout_ms);
|
||||||
LIBBPF_API int ring_buffer__consume(struct ring_buffer *rb);
|
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);
|
LIBBPF_API int ring_buffer__epoll_fd(const struct ring_buffer *rb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1372,17 +1337,6 @@ LIBBPF_API int ring__map_fd(const struct ring *r);
|
|||||||
*/
|
*/
|
||||||
LIBBPF_API int ring__consume(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 {
|
struct user_ring_buffer_opts {
|
||||||
size_t sz; /* size of this struct, for forward/backward compatibility */
|
size_t sz; /* size of this struct, for forward/backward compatibility */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ LIBBPF_0.3.0 {
|
|||||||
btf__parse_raw_split;
|
btf__parse_raw_split;
|
||||||
btf__parse_split;
|
btf__parse_split;
|
||||||
btf__new_empty_split;
|
btf__new_empty_split;
|
||||||
|
btf__new_split;
|
||||||
ring_buffer__epoll_fd;
|
ring_buffer__epoll_fd;
|
||||||
} LIBBPF_0.2.0;
|
} LIBBPF_0.2.0;
|
||||||
|
|
||||||
@@ -325,6 +326,7 @@ LIBBPF_0.7.0 {
|
|||||||
bpf_xdp_detach;
|
bpf_xdp_detach;
|
||||||
bpf_xdp_query;
|
bpf_xdp_query;
|
||||||
bpf_xdp_query_id;
|
bpf_xdp_query_id;
|
||||||
|
btf_ext__raw_data;
|
||||||
libbpf_probe_bpf_helper;
|
libbpf_probe_bpf_helper;
|
||||||
libbpf_probe_bpf_map_type;
|
libbpf_probe_bpf_map_type;
|
||||||
libbpf_probe_bpf_prog_type;
|
libbpf_probe_bpf_prog_type;
|
||||||
@@ -409,17 +411,4 @@ LIBBPF_1.3.0 {
|
|||||||
} LIBBPF_1.2.0;
|
} LIBBPF_1.2.0;
|
||||||
|
|
||||||
LIBBPF_1.4.0 {
|
LIBBPF_1.4.0 {
|
||||||
global:
|
|
||||||
bpf_program__attach_raw_tracepoint_opts;
|
|
||||||
bpf_raw_tracepoint_open_opts;
|
|
||||||
bpf_token_create;
|
|
||||||
btf__new_split;
|
|
||||||
btf_ext__raw_data;
|
|
||||||
} LIBBPF_1.3.0;
|
} LIBBPF_1.3.0;
|
||||||
|
|
||||||
LIBBPF_1.5.0 {
|
|
||||||
global:
|
|
||||||
bpf_program__attach_sockmap;
|
|
||||||
ring__consume_n;
|
|
||||||
ring_buffer__consume_n;
|
|
||||||
} LIBBPF_1.4.0;
|
|
||||||
|
|||||||
@@ -15,24 +15,9 @@
|
|||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <libelf.h>
|
#include <libelf.h>
|
||||||
#include "relo_core.h"
|
#include "relo_core.h"
|
||||||
|
|
||||||
/* Android's libc doesn't support AT_EACCESS in faccessat() implementation
|
|
||||||
* ([0]), and just returns -EINVAL even if file exists and is accessible.
|
|
||||||
* See [1] for issues caused by this.
|
|
||||||
*
|
|
||||||
* So just redefine it to 0 on Android.
|
|
||||||
*
|
|
||||||
* [0] https://android.googlesource.com/platform/bionic/+/refs/heads/android13-release/libc/bionic/faccessat.cpp#50
|
|
||||||
* [1] https://github.com/libbpf/libbpf-bootstrap/issues/250#issuecomment-1911324250
|
|
||||||
*/
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
#undef AT_EACCESS
|
|
||||||
#define AT_EACCESS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||||
|
|
||||||
@@ -372,39 +357,18 @@ enum kern_feature_id {
|
|||||||
FEAT_SYSCALL_WRAPPER,
|
FEAT_SYSCALL_WRAPPER,
|
||||||
/* BPF multi-uprobe link support */
|
/* BPF multi-uprobe link support */
|
||||||
FEAT_UPROBE_MULTI_LINK,
|
FEAT_UPROBE_MULTI_LINK,
|
||||||
/* Kernel supports arg:ctx tag (__arg_ctx) for global subprogs natively */
|
|
||||||
FEAT_ARG_CTX_TAG,
|
|
||||||
/* Kernel supports '?' at the front of datasec names */
|
|
||||||
FEAT_BTF_QMARK_DATASEC,
|
|
||||||
__FEAT_CNT,
|
__FEAT_CNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum kern_feature_result {
|
int probe_memcg_account(void);
|
||||||
FEAT_UNKNOWN = 0,
|
|
||||||
FEAT_SUPPORTED = 1,
|
|
||||||
FEAT_MISSING = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kern_feature_cache {
|
|
||||||
enum kern_feature_result res[__FEAT_CNT];
|
|
||||||
int token_fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id);
|
|
||||||
bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id);
|
bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id);
|
||||||
|
|
||||||
int probe_kern_syscall_wrapper(int token_fd);
|
|
||||||
int probe_memcg_account(int token_fd);
|
|
||||||
int bump_rlimit_memlock(void);
|
int bump_rlimit_memlock(void);
|
||||||
|
|
||||||
int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz);
|
int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz);
|
||||||
int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz);
|
int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz);
|
||||||
int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
||||||
const char *str_sec, size_t str_len,
|
const char *str_sec, size_t str_len);
|
||||||
int token_fd);
|
int btf_load_into_kernel(struct btf *btf, char *log_buf, size_t log_sz, __u32 log_level);
|
||||||
int btf_load_into_kernel(struct btf *btf,
|
|
||||||
char *log_buf, size_t log_sz, __u32 log_level,
|
|
||||||
int token_fd);
|
|
||||||
|
|
||||||
struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf);
|
struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf);
|
||||||
void btf_get_kernel_prefix_kind(enum bpf_attach_type attach_type,
|
void btf_get_kernel_prefix_kind(enum bpf_attach_type attach_type,
|
||||||
@@ -518,6 +482,11 @@ 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,
|
__s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name,
|
||||||
__u32 kind);
|
__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 */
|
/* handle direct returned errors */
|
||||||
static inline int libbpf_err(int ret)
|
static inline int libbpf_err(int ret)
|
||||||
{
|
{
|
||||||
@@ -563,17 +532,6 @@ static inline bool is_ldimm64_insn(struct bpf_insn *insn)
|
|||||||
return insn->code == (BPF_LD | BPF_IMM | BPF_DW);
|
return insn->code == (BPF_LD | BPF_IMM | BPF_DW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unconditionally dup FD, ensuring it doesn't use [0, 2] range.
|
|
||||||
* Original FD is not closed or altered in any other way.
|
|
||||||
* Preserves original FD value, if it's invalid (negative).
|
|
||||||
*/
|
|
||||||
static inline int dup_good_fd(int fd)
|
|
||||||
{
|
|
||||||
if (fd < 0)
|
|
||||||
return fd;
|
|
||||||
return fcntl(fd, F_DUPFD_CLOEXEC, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if fd is stdin, stdout, or stderr, dup to a fd greater than 2
|
/* if fd is stdin, stdout, or stderr, dup to a fd greater than 2
|
||||||
* Takes ownership of the fd passed in, and closes it if calling
|
* Takes ownership of the fd passed in, and closes it if calling
|
||||||
* fcntl(fd, F_DUPFD_CLOEXEC, 3).
|
* fcntl(fd, F_DUPFD_CLOEXEC, 3).
|
||||||
@@ -585,7 +543,7 @@ static inline int ensure_good_fd(int fd)
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return fd;
|
return fd;
|
||||||
if (fd < 3) {
|
if (fd < 3) {
|
||||||
fd = dup_good_fd(fd);
|
fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
close(old_fd);
|
close(old_fd);
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
@@ -597,15 +555,6 @@ static inline int ensure_good_fd(int fd)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sys_dup2(int oldfd, int newfd)
|
|
||||||
{
|
|
||||||
#ifdef __NR_dup2
|
|
||||||
return syscall(__NR_dup2, oldfd, newfd);
|
|
||||||
#else
|
|
||||||
return syscall(__NR_dup3, oldfd, newfd, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Point *fixed_fd* to the same file that *tmp_fd* points to.
|
/* Point *fixed_fd* to the same file that *tmp_fd* points to.
|
||||||
* Regardless of success, *tmp_fd* is closed.
|
* Regardless of success, *tmp_fd* is closed.
|
||||||
* Whatever *fixed_fd* pointed to is closed silently.
|
* Whatever *fixed_fd* pointed to is closed silently.
|
||||||
@@ -614,7 +563,7 @@ static inline int reuse_fd(int fixed_fd, int tmp_fd)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = sys_dup2(tmp_fd, fixed_fd);
|
err = dup2(tmp_fd, fixed_fd);
|
||||||
err = err < 0 ? -errno : 0;
|
err = err < 0 ? -errno : 0;
|
||||||
close(tmp_fd); /* clean up temporary FD */
|
close(tmp_fd); /* clean up temporary FD */
|
||||||
return err;
|
return err;
|
||||||
@@ -664,6 +613,4 @@ int elf_resolve_syms_offsets(const char *binary_path, int cnt,
|
|||||||
int elf_resolve_pattern_offsets(const char *binary_path, const char *pattern,
|
int elf_resolve_pattern_offsets(const char *binary_path, const char *pattern,
|
||||||
unsigned long **poffsets, size_t *pcnt);
|
unsigned long **poffsets, size_t *pcnt);
|
||||||
|
|
||||||
int probe_fd(int fd);
|
|
||||||
|
|
||||||
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
|
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ static __u32 get_debian_kernel_version(struct utsname *info)
|
|||||||
if (sscanf(p, "Debian %u.%u.%u", &major, &minor, &patch) != 3)
|
if (sscanf(p, "Debian %u.%u.%u", &major, &minor, &patch) != 3)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (major == 4 && minor == 19 && patch > 255)
|
||||||
|
return KERNEL_VERSION(major, minor, 255);
|
||||||
|
|
||||||
return KERNEL_VERSION(major, minor, patch);
|
return KERNEL_VERSION(major, minor, patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,8 +222,7 @@ int libbpf_probe_bpf_prog_type(enum bpf_prog_type prog_type, const void *opts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
||||||
const char *str_sec, size_t str_len,
|
const char *str_sec, size_t str_len)
|
||||||
int token_fd)
|
|
||||||
{
|
{
|
||||||
struct btf_header hdr = {
|
struct btf_header hdr = {
|
||||||
.magic = BTF_MAGIC,
|
.magic = BTF_MAGIC,
|
||||||
@@ -230,10 +232,6 @@ int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
|||||||
.str_off = types_len,
|
.str_off = types_len,
|
||||||
.str_len = str_len,
|
.str_len = str_len,
|
||||||
};
|
};
|
||||||
LIBBPF_OPTS(bpf_btf_load_opts, opts,
|
|
||||||
.token_fd = token_fd,
|
|
||||||
.btf_flags = token_fd ? BPF_F_TOKEN_FD : 0,
|
|
||||||
);
|
|
||||||
int btf_fd, btf_len;
|
int btf_fd, btf_len;
|
||||||
__u8 *raw_btf;
|
__u8 *raw_btf;
|
||||||
|
|
||||||
@@ -246,7 +244,7 @@ int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
|||||||
memcpy(raw_btf + hdr.hdr_len, raw_types, hdr.type_len);
|
memcpy(raw_btf + hdr.hdr_len, raw_types, hdr.type_len);
|
||||||
memcpy(raw_btf + hdr.hdr_len + hdr.type_len, str_sec, hdr.str_len);
|
memcpy(raw_btf + hdr.hdr_len + hdr.type_len, str_sec, hdr.str_len);
|
||||||
|
|
||||||
btf_fd = bpf_btf_load(raw_btf, btf_len, &opts);
|
btf_fd = bpf_btf_load(raw_btf, btf_len, NULL);
|
||||||
|
|
||||||
free(raw_btf);
|
free(raw_btf);
|
||||||
return btf_fd;
|
return btf_fd;
|
||||||
@@ -276,7 +274,7 @@ static int load_local_storage_btf(void)
|
|||||||
};
|
};
|
||||||
|
|
||||||
return libbpf__load_raw_btf((char *)types, sizeof(types),
|
return libbpf__load_raw_btf((char *)types, sizeof(types),
|
||||||
strs, sizeof(strs), 0);
|
strs, sizeof(strs));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int probe_map_create(enum bpf_map_type map_type)
|
static int probe_map_create(enum bpf_map_type map_type)
|
||||||
@@ -331,20 +329,12 @@ static int probe_map_create(enum bpf_map_type map_type)
|
|||||||
case BPF_MAP_TYPE_STRUCT_OPS:
|
case BPF_MAP_TYPE_STRUCT_OPS:
|
||||||
/* we'll get -ENOTSUPP for invalid BTF type ID for struct_ops */
|
/* we'll get -ENOTSUPP for invalid BTF type ID for struct_ops */
|
||||||
opts.btf_vmlinux_value_type_id = 1;
|
opts.btf_vmlinux_value_type_id = 1;
|
||||||
opts.value_type_btf_obj_fd = -1;
|
|
||||||
exp_err = -524; /* -ENOTSUPP */
|
exp_err = -524; /* -ENOTSUPP */
|
||||||
break;
|
break;
|
||||||
case BPF_MAP_TYPE_BLOOM_FILTER:
|
case BPF_MAP_TYPE_BLOOM_FILTER:
|
||||||
key_size = 0;
|
key_size = 0;
|
||||||
max_entries = 1;
|
max_entries = 1;
|
||||||
break;
|
break;
|
||||||
case BPF_MAP_TYPE_ARENA:
|
|
||||||
key_size = 0;
|
|
||||||
value_size = 0;
|
|
||||||
max_entries = 1; /* one page */
|
|
||||||
opts.map_extra = 0; /* can mmap() at any address */
|
|
||||||
opts.map_flags = BPF_F_MMAPABLE;
|
|
||||||
break;
|
|
||||||
case BPF_MAP_TYPE_HASH:
|
case BPF_MAP_TYPE_HASH:
|
||||||
case BPF_MAP_TYPE_ARRAY:
|
case BPF_MAP_TYPE_ARRAY:
|
||||||
case BPF_MAP_TYPE_PROG_ARRAY:
|
case BPF_MAP_TYPE_PROG_ARRAY:
|
||||||
@@ -448,8 +438,7 @@ 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)
|
/* If BPF verifier doesn't recognize BPF helper ID (enum bpf_func_id)
|
||||||
* at all, it will emit something like "invalid func unknown#181".
|
* at all, it will emit something like "invalid func unknown#181".
|
||||||
* If BPF verifier recognizes BPF helper but it's not supported for
|
* 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
|
* In both cases, provided combination of BPF program type and BPF
|
||||||
* helper is not supported by the kernel.
|
* helper is not supported by the kernel.
|
||||||
* In all other cases, probe_prog_load() above will either succeed (e.g.,
|
* In all other cases, probe_prog_load() above will either succeed (e.g.,
|
||||||
@@ -458,8 +447,7 @@ 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
|
* that), or we'll get some more specific BPF verifier error about
|
||||||
* some unsatisfied conditions.
|
* 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 0;
|
||||||
return 1; /* assume supported */
|
return 1; /* assume supported */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
#define __LIBBPF_VERSION_H
|
#define __LIBBPF_VERSION_H
|
||||||
|
|
||||||
#define LIBBPF_MAJOR_VERSION 1
|
#define LIBBPF_MAJOR_VERSION 1
|
||||||
#define LIBBPF_MINOR_VERSION 5
|
#define LIBBPF_MINOR_VERSION 4
|
||||||
|
|
||||||
#endif /* __LIBBPF_VERSION_H */
|
#endif /* __LIBBPF_VERSION_H */
|
||||||
|
|||||||
@@ -2732,7 +2732,7 @@ static int finalize_btf(struct bpf_linker *linker)
|
|||||||
|
|
||||||
/* Emit .BTF.ext section */
|
/* Emit .BTF.ext section */
|
||||||
if (linker->btf_ext) {
|
if (linker->btf_ext) {
|
||||||
raw_data = btf_ext__raw_data(linker->btf_ext, &raw_sz);
|
raw_data = btf_ext__get_raw_data(linker->btf_ext, &raw_sz);
|
||||||
if (!raw_data)
|
if (!raw_data)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|||||||
@@ -496,8 +496,8 @@ int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts)
|
|||||||
if (err)
|
if (err)
|
||||||
return libbpf_err(err);
|
return libbpf_err(err);
|
||||||
|
|
||||||
OPTS_SET(opts, feature_flags, md.flags);
|
opts->feature_flags = md.flags;
|
||||||
OPTS_SET(opts, xdp_zc_max_segs, md.xdp_zc_max_segs);
|
opts->xdp_zc_max_segs = md.xdp_zc_max_segs;
|
||||||
|
|
||||||
skip_feature_flags:
|
skip_feature_flags:
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ static inline int roundup_len(__u32 len)
|
|||||||
return (len + 7) / 8 * 8;
|
return (len + 7) / 8 * 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t ringbuf_process_ring(struct ring *r, size_t n)
|
static int64_t ringbuf_process_ring(struct ring *r)
|
||||||
{
|
{
|
||||||
int *len_ptr, len, err;
|
int *len_ptr, len, err;
|
||||||
/* 64-bit to avoid overflow in case of extreme application behavior */
|
/* 64-bit to avoid overflow in case of extreme application behavior */
|
||||||
@@ -268,42 +268,12 @@ static int64_t ringbuf_process_ring(struct ring *r, size_t n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
smp_store_release(r->consumer_pos, cons_pos);
|
smp_store_release(r->consumer_pos, cons_pos);
|
||||||
|
|
||||||
if (cnt >= n)
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
} while (got_new_data);
|
} while (got_new_data);
|
||||||
done:
|
done:
|
||||||
return cnt;
|
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.
|
/* Consume available ring buffer(s) data without event polling.
|
||||||
* Returns number of records consumed across all registered ring buffers (or
|
* Returns number of records consumed across all registered ring buffers (or
|
||||||
* INT_MAX, whichever is less), or negative number if any of the callbacks
|
* INT_MAX, whichever is less), or negative number if any of the callbacks
|
||||||
@@ -317,15 +287,13 @@ int ring_buffer__consume(struct ring_buffer *rb)
|
|||||||
for (i = 0; i < rb->ring_cnt; i++) {
|
for (i = 0; i < rb->ring_cnt; i++) {
|
||||||
struct ring *ring = rb->rings[i];
|
struct ring *ring = rb->rings[i];
|
||||||
|
|
||||||
err = ringbuf_process_ring(ring, INT_MAX);
|
err = ringbuf_process_ring(ring);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return libbpf_err(err);
|
return libbpf_err(err);
|
||||||
res += err;
|
res += err;
|
||||||
if (res > INT_MAX) {
|
|
||||||
res = INT_MAX;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (res > INT_MAX)
|
||||||
|
return INT_MAX;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,13 +314,13 @@ int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms)
|
|||||||
__u32 ring_id = rb->events[i].data.fd;
|
__u32 ring_id = rb->events[i].data.fd;
|
||||||
struct ring *ring = rb->rings[ring_id];
|
struct ring *ring = rb->rings[ring_id];
|
||||||
|
|
||||||
err = ringbuf_process_ring(ring, INT_MAX);
|
err = ringbuf_process_ring(ring);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return libbpf_err(err);
|
return libbpf_err(err);
|
||||||
res += err;
|
res += err;
|
||||||
}
|
}
|
||||||
if (res > INT_MAX)
|
if (res > INT_MAX)
|
||||||
res = INT_MAX;
|
return INT_MAX;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,22 +371,17 @@ int ring__map_fd(const struct ring *r)
|
|||||||
return r->map_fd;
|
return r->map_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ring__consume_n(struct ring *r, size_t n)
|
int ring__consume(struct ring *r)
|
||||||
{
|
{
|
||||||
int res;
|
int64_t res;
|
||||||
|
|
||||||
res = ringbuf_process_ring(r, n);
|
res = ringbuf_process_ring(r);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return libbpf_err(res);
|
return libbpf_err(res);
|
||||||
|
|
||||||
return res > INT_MAX ? INT_MAX : 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)
|
static void user_ringbuf_unmap_ring(struct user_ring_buffer *rb)
|
||||||
{
|
{
|
||||||
if (rb->consumer_pos) {
|
if (rb->consumer_pos) {
|
||||||
|
|||||||
@@ -2,8 +2,5 @@
|
|||||||
#ifndef __LIBBPF_STR_ERROR_H
|
#ifndef __LIBBPF_STR_ERROR_H
|
||||||
#define __LIBBPF_STR_ERROR_H
|
#define __LIBBPF_STR_ERROR_H
|
||||||
|
|
||||||
#define STRERR_BUFSIZE 128
|
|
||||||
|
|
||||||
char *libbpf_strerror_r(int err, char *dst, int len);
|
char *libbpf_strerror_r(int err, char *dst, int len);
|
||||||
|
|
||||||
#endif /* __LIBBPF_STR_ERROR_H */
|
#endif /* __LIBBPF_STR_ERROR_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user