diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 9d52b2f3a36df54f4af2150bfaba3fb76d7d1a65..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# bpftool - -#### Description -tool for inspection and simple manipulation of eBPF programs and maps - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md deleted file mode 100644 index 8b226ae2ec1d9582858cca8c3d598f13c5b6477b..0000000000000000000000000000000000000000 --- a/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# bpftool - -#### 介绍 -tool for inspection and simple manipulation of eBPF programs and maps - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/bpftool-Clear-errno-after-libcaps-checks.patch b/bpftool-Clear-errno-after-libcaps-checks.patch new file mode 100644 index 0000000000000000000000000000000000000000..1af4cfa5f91c35a6959b0a072cb554d8392bc63d --- /dev/null +++ b/bpftool-Clear-errno-after-libcaps-checks.patch @@ -0,0 +1,68 @@ +From e3c9b94734531a08c9bf51057ca3a9022cc90f91 Mon Sep 17 00:00:00 2001 +From: Quentin Monnet +Date: Mon, 15 Aug 2022 17:22:05 +0100 +Subject: bpftool: Clear errno after libcap's checks + +[ Upstream commit cea558855c39b7f1f02ff50dcf701ca6596bc964 ] + +When bpftool is linked against libcap, the library runs a "constructor" +function to compute the number of capabilities of the running kernel +[0], at the beginning of the execution of the program. As part of this, +it performs multiple calls to prctl(). Some of these may fail, and set +errno to a non-zero value: + + # strace -e prctl ./bpftool version + prctl(PR_CAPBSET_READ, CAP_MAC_OVERRIDE) = 1 + prctl(PR_CAPBSET_READ, 0x30 /* CAP_??? */) = -1 EINVAL (Invalid argument) + prctl(PR_CAPBSET_READ, CAP_CHECKPOINT_RESTORE) = 1 + prctl(PR_CAPBSET_READ, 0x2c /* CAP_??? */) = -1 EINVAL (Invalid argument) + prctl(PR_CAPBSET_READ, 0x2a /* CAP_??? */) = -1 EINVAL (Invalid argument) + prctl(PR_CAPBSET_READ, 0x29 /* CAP_??? */) = -1 EINVAL (Invalid argument) + ** fprintf added at the top of main(): we have errno == 1 + ./bpftool v7.0.0 + using libbpf v1.0 + features: libbfd, libbpf_strict, skeletons + +++ exited with 0 +++ + +This has been addressed in libcap 2.63 [1], but until this version is +available everywhere, we can fix it on bpftool side. + +Let's clean errno at the beginning of the main() function, to make sure +that these checks do not interfere with the batch mode, where we error +out if errno is set after a bpftool command. + + [0] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/tree/libcap/cap_alloc.c?h=libcap-2.65#n20 + [1] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=f25a1b7e69f7b33e6afb58b3e38f3450b7d2d9a0 + +Signed-off-by: Quentin Monnet +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20220815162205.45043-1-quentin@isovalent.com +Signed-off-by: Sasha Levin +--- + src/main.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 1854d6b978604..4fd4e3462ebce 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -398,6 +398,16 @@ int main(int argc, char **argv) + + setlinebuf(stdout); + ++#ifdef USE_LIBCAP ++ /* Libcap < 2.63 hooks before main() to compute the number of ++ * capabilities of the running kernel, and doing so it calls prctl() ++ * which may fail and set errno to non-zero. ++ * Let's reset errno to make sure this does not interfere with the ++ * batch mode. ++ */ ++ errno = 0; ++#endif ++ + last_do_help = do_help; + pretty_output = false; + json_output = false; +-- +cgit + diff --git a/bpftool-Fix-NULL-pointer-dereference-when-pin-PROG-M.patch b/bpftool-Fix-NULL-pointer-dereference-when-pin-PROG-M.patch new file mode 100644 index 0000000000000000000000000000000000000000..7d7dae98af82f7531f93b123efb0c4e54a3912c5 --- /dev/null +++ b/bpftool-Fix-NULL-pointer-dereference-when-pin-PROG-M.patch @@ -0,0 +1,48 @@ +From 8c80b2fca4112d724dde477aed13f7b0510a2792 Mon Sep 17 00:00:00 2001 +From: Pu Lehui +Date: Wed, 2 Nov 2022 16:40:34 +0800 +Subject: bpftool: Fix NULL pointer dereference when pin {PROG, MAP, LINK} + without FILE + +[ Upstream commit 34de8e6e0e1f66e431abf4123934a2581cb5f133 ] + +When using bpftool to pin {PROG, MAP, LINK} without FILE, +segmentation fault will occur. The reson is that the lack +of FILE will cause strlen to trigger NULL pointer dereference. +The corresponding stacktrace is shown below: + +do_pin + do_pin_any + do_pin_fd + mount_bpffs_for_pin + strlen(name) <- NULL pointer dereference + +Fix it by adding validation to the common process. + +Fixes: 75a1e792c335 ("tools: bpftool: Allow all prog/map handles for pinning objects") +Signed-off-by: Pu Lehui +Signed-off-by: Daniel Borkmann +Reviewed-by: Quentin Monnet +Link: https://lore.kernel.org/bpf/20221102084034.3342995-1-pulehui@huaweicloud.com +Signed-off-by: Sasha Levin +--- + src/common.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/common.c b/src/common.c +index 6ebf2b215ef49..eefa2b34e641a 100644 +--- a/src/common.c ++++ b/src/common.c +@@ -271,6 +271,9 @@ int do_pin_any(int argc, char **argv, int (*get_fd)(int *, char ***)) + int err; + int fd; + ++ if (!REQ_ARGS(3)) ++ return -EINVAL; ++ + fd = get_fd(&argc, &argv); + if (fd < 0) + return fd; +-- +cgit + diff --git a/bpftool-Fix-a-wrong-type-cast-in-btf_dumper_int.patch b/bpftool-Fix-a-wrong-type-cast-in-btf_dumper_int.patch new file mode 100644 index 0000000000000000000000000000000000000000..bde1f4aeaf084d20481432e7d3a2ce37ce64fa24 --- /dev/null +++ b/bpftool-Fix-a-wrong-type-cast-in-btf_dumper_int.patch @@ -0,0 +1,38 @@ +From 2afb93e4e4166a9b4022db58689986893a4c3653 Mon Sep 17 00:00:00 2001 +From: Lam Thai +Date: Wed, 24 Aug 2022 15:59:00 -0700 +Subject: bpftool: Fix a wrong type cast in btf_dumper_int + +[ Upstream commit 7184aef9c0f7a81db8fd18d183ee42481d89bf35 ] + +When `data` points to a boolean value, casting it to `int *` is problematic +and could lead to a wrong value being passed to `jsonw_bool`. Change the +cast to `bool *` instead. + +Fixes: b12d6ec09730 ("bpf: btf: add btf print functionality") +Signed-off-by: Lam Thai +Signed-off-by: Andrii Nakryiko +Reviewed-by: Quentin Monnet +Acked-by: John Fastabend +Link: https://lore.kernel.org/bpf/20220824225859.9038-1-lamthai@arista.com +Signed-off-by: Sasha Levin +--- + src/btf_dumper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/btf_dumper.c b/src/btf_dumper.c +index 0e9310727281a..13be487631992 100644 +--- a/src/btf_dumper.c ++++ b/src/btf_dumper.c +@@ -416,7 +416,7 @@ static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset, + *(char *)data); + break; + case BTF_INT_BOOL: +- jsonw_bool(jw, *(int *)data); ++ jsonw_bool(jw, *(bool *)data); + break; + default: + /* shouldn't happen */ +-- +cgit + diff --git a/bpftool-Fix-bug-for-long-instructions-in-program-CFG.patch b/bpftool-Fix-bug-for-long-instructions-in-program-CFG.patch new file mode 100644 index 0000000000000000000000000000000000000000..3679574c37ea574667b5d743a9abb1697fffde92 --- /dev/null +++ b/bpftool-Fix-bug-for-long-instructions-in-program-CFG.patch @@ -0,0 +1,44 @@ +From 27942f477d1069adab3f6c45f59146bc9379dd45 Mon Sep 17 00:00:00 2001 +From: Quentin Monnet +Date: Wed, 5 Apr 2023 14:21:15 +0100 +Subject: bpftool: Fix bug for long instructions in program CFG dumps + +[ Upstream commit 67cf52cdb6c8fa6365d29106555dacf95c9fd374 ] + +When dumping the control flow graphs for programs using the 16-byte long +load instruction, we need to skip the second part of this instruction +when looking for the next instruction to process. Otherwise, we end up +printing "BUG_ld_00" from the kernel disassembler in the CFG. + +Fixes: efcef17a6d65 ("tools: bpftool: generate .dot graph from CFG information") +Signed-off-by: Quentin Monnet +Link: https://lore.kernel.org/r/20230405132120.59886-3-quentin@isovalent.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + src/xlated_dumper.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/xlated_dumper.c b/src/xlated_dumper.c +index 8608cd68cdd07..13d614b16f6c2 100644 +--- a/src/xlated_dumper.c ++++ b/src/xlated_dumper.c +@@ -363,8 +363,15 @@ void dump_xlated_for_graph(struct dump_data *dd, void *buf_start, void *buf_end, + struct bpf_insn *insn_start = buf_start; + struct bpf_insn *insn_end = buf_end; + struct bpf_insn *cur = insn_start; ++ bool double_insn = false; + + for (; cur <= insn_end; cur++) { ++ if (double_insn) { ++ double_insn = false; ++ continue; ++ } ++ double_insn = cur->code == (BPF_LD | BPF_IMM | BPF_DW); ++ + printf("% 4d: ", (int)(cur - insn_start + start_idx)); + print_bpf_insn(&cbs, cur, true); + if (cur != insn_end) +-- +cgit + diff --git a/bpftool-define-a-local-bpf_perf_link-to-fix-accessin.patch b/bpftool-define-a-local-bpf_perf_link-to-fix-accessin.patch new file mode 100644 index 0000000000000000000000000000000000000000..a6f09c336ae82610a01b25f64cf5e3f237e15d4a --- /dev/null +++ b/bpftool-define-a-local-bpf_perf_link-to-fix-accessin.patch @@ -0,0 +1,69 @@ +From 0773871e3aa0ef8b928748ec53d77a1203b42543 Mon Sep 17 00:00:00 2001 +From: Alexander Lobakin +Date: Fri, 7 Jul 2023 10:54:23 +0100 +Subject: [PATCH] bpftool: Define a local bpf_perf_link to fix accessing its + fields + +When building bpftool with !CONFIG_PERF_EVENTS: + +skeleton/pid_iter.bpf.c:47:14: error: incomplete definition of type 'struct bpf_perf_link' + perf_link = container_of(link, struct bpf_perf_link, link); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helpers.h:74:22: note: expanded from macro 'container_of' + ((type *)(__mptr - offsetof(type, member))); \ + ^~~~~~~~~~~~~~~~~~~~~~ +tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helpers.h:68:60: note: expanded from macro 'offsetof' + #define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER) + ~~~~~~~~~~~^ +skeleton/pid_iter.bpf.c:44:9: note: forward declaration of 'struct bpf_perf_link' + struct bpf_perf_link *perf_link; + ^ + +&bpf_perf_link is being defined and used only under the ifdef. +Define struct bpf_perf_link___local with the `preserve_access_index` +attribute inside the pid_iter BPF prog to allow compiling on any +configs. CO-RE will substitute it with the real struct bpf_perf_link +accesses later on. +container_of() uses offsetof(), which does the necessary CO-RE +relocation if the field is specified with `preserve_access_index` - as +is the case for struct bpf_perf_link___local. + +Fixes: cbdaf71f7e65 ("bpftool: Add bpf_cookie to link output") +Suggested-by: Andrii Nakryiko +Signed-off-by: Alexander Lobakin +Signed-off-by: Quentin Monnet +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20230707095425.168126-3-quentin@isovalent.com +--- + src/skeleton/pid_iter.bpf.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/skeleton/pid_iter.bpf.c b/src/skeleton/pid_iter.bpf.c +index e2af8e5..3a4c4f7 100644 +--- a/src/skeleton/pid_iter.bpf.c ++++ b/src/skeleton/pid_iter.bpf.c +@@ -15,6 +15,11 @@ enum bpf_obj_type { + BPF_OBJ_BTF, + }; + ++struct bpf_perf_link___local { ++ struct bpf_link link; ++ struct file *perf_file; ++} __attribute__((preserve_access_index)); ++ + struct perf_event___local { + u64 bpf_cookie; + } __attribute__((preserve_access_index)); +@@ -45,10 +50,10 @@ static __always_inline __u32 get_obj_id(void *ent, enum bpf_obj_type type) + /* could be used only with BPF_LINK_TYPE_PERF_EVENT links */ + static __u64 get_bpf_cookie(struct bpf_link *link) + { ++ struct bpf_perf_link___local *perf_link; + struct perf_event___local *event; +- struct bpf_perf_link *perf_link; + +- perf_link = container_of(link, struct bpf_perf_link, link); ++ perf_link = container_of(link, struct bpf_perf_link___local, link); + event = BPF_CORE_READ(perf_link, perf_file, private_data); + return BPF_CORE_READ(event, bpf_cookie); + } diff --git a/bpftool-libbpf-v6.8.0.tar.gz b/bpftool-libbpf-v6.8.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..10b4c42444a2068943692a0b8cd97c0fecfb258b Binary files /dev/null and b/bpftool-libbpf-v6.8.0.tar.gz differ diff --git a/bpftool-profile-online-CPUs-instead-of-possible.patch b/bpftool-profile-online-CPUs-instead-of-possible.patch new file mode 100644 index 0000000000000000000000000000000000000000..dac66b2c194f2f98695fe93c6696a4cbd5bfc0db --- /dev/null +++ b/bpftool-profile-online-CPUs-instead-of-possible.patch @@ -0,0 +1,114 @@ +From 94c4eafbbde36de86685a78526ab52c2b5c2cd56 Mon Sep 17 00:00:00 2001 +From: Tonghao Zhang +Date: Thu, 2 Feb 2023 21:17:01 +0800 +Subject: bpftool: profile online CPUs instead of possible + +[ Upstream commit 377c16fa3f3c60d21e4b05314c8be034ce37f2eb ] + +The number of online cpu may be not equal to possible cpu. +"bpftool prog profile" can not create pmu event on possible +but on online cpu. + +$ dmidecode -s system-product-name +PowerEdge R620 +$ cat /sys/devices/system/cpu/possible +0-47 +$ cat /sys/devices/system/cpu/online +0-31 + +Disable cpu dynamically: +$ echo 0 > /sys/devices/system/cpu/cpuX/online + +If one cpu is offline, perf_event_open will return ENODEV. +To fix this issue: +* check value returned and skip offline cpu. +* close pmu_fd immediately on error path, avoid fd leaking. + +Fixes: 47c09d6a9f67 ("bpftool: Introduce "prog profile" command") +Signed-off-by: Tonghao Zhang +Cc: Quentin Monnet +Cc: Alexei Starovoitov +Cc: Daniel Borkmann +Cc: Andrii Nakryiko +Cc: Martin KaFai Lau +Cc: Song Liu +Cc: Yonghong Song +Cc: John Fastabend +Cc: KP Singh +Cc: Stanislav Fomichev +Cc: Hao Luo +Cc: Jiri Olsa +Acked-by: John Fastabend +Link: https://lore.kernel.org/r/20230202131701.29519-1-tong@infragraf.org +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + src/prog.c | 38 ++++++++++++++++++++++++++++++-------- + 1 file changed, 30 insertions(+), 8 deletions(-) + +diff --git a/src/prog.c b/src/prog.c +index 592536904dde2..d2bcce627b320 100644 +--- a/src/prog.c ++++ b/src/prog.c +@@ -1912,10 +1912,38 @@ static void profile_close_perf_events(struct profiler_bpf *obj) + profile_perf_event_cnt = 0; + } + ++static int profile_open_perf_event(int mid, int cpu, int map_fd) ++{ ++ int pmu_fd; ++ ++ pmu_fd = syscall(__NR_perf_event_open, &metrics[mid].attr, ++ -1 /*pid*/, cpu, -1 /*group_fd*/, 0); ++ if (pmu_fd < 0) { ++ if (errno == ENODEV) { ++ p_info("cpu %d may be offline, skip %s profiling.", ++ cpu, metrics[mid].name); ++ profile_perf_event_cnt++; ++ return 0; ++ } ++ return -1; ++ } ++ ++ if (bpf_map_update_elem(map_fd, ++ &profile_perf_event_cnt, ++ &pmu_fd, BPF_ANY) || ++ ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0)) { ++ close(pmu_fd); ++ return -1; ++ } ++ ++ profile_perf_events[profile_perf_event_cnt++] = pmu_fd; ++ return 0; ++} ++ + static int profile_open_perf_events(struct profiler_bpf *obj) + { + unsigned int cpu, m; +- int map_fd, pmu_fd; ++ int map_fd; + + profile_perf_events = calloc( + sizeof(int), obj->rodata->num_cpu * obj->rodata->num_metric); +@@ -1934,17 +1962,11 @@ static int profile_open_perf_events(struct profiler_bpf *obj) + if (!metrics[m].selected) + continue; + for (cpu = 0; cpu < obj->rodata->num_cpu; cpu++) { +- pmu_fd = syscall(__NR_perf_event_open, &metrics[m].attr, +- -1/*pid*/, cpu, -1/*group_fd*/, 0); +- if (pmu_fd < 0 || +- bpf_map_update_elem(map_fd, &profile_perf_event_cnt, +- &pmu_fd, BPF_ANY) || +- ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0)) { ++ if (profile_open_perf_event(m, cpu, map_fd)) { + p_err("failed to create event %s on cpu %d", + metrics[m].name, cpu); + return -1; + } +- profile_perf_events[profile_perf_event_cnt++] = pmu_fd; + } + } + return 0; +-- +cgit + diff --git a/bpftool-recognize-scheduler-programs.patch b/bpftool-recognize-scheduler-programs.patch new file mode 100644 index 0000000000000000000000000000000000000000..f50213a9c178c7d826844935bef0b94b81f8afd9 --- /dev/null +++ b/bpftool-recognize-scheduler-programs.patch @@ -0,0 +1,121 @@ +From 3882d69d1fdf997c0deab696af7be752e87877d5 Mon Sep 17 00:00:00 2001 +From: bitcoffee +Date: Thu, 12 Oct 2023 19:50:14 +0800 +Subject: [PATCH] bpftool: recognize scheduler programs + +Teach bpftool to recognize scheduler bpf programs. + +Signed-off-by: Roman Gushchin +Signed-off-by: Chen Hui +Signed-off-by: Ren Zhijie +Signed-off-by: Hui Tang +--- + include/uapi/linux/bpf.h | 6 ++++++ + libbpf/include/uapi/linux/bpf.h | 6 ++++++ + libbpf/src/bpf.c | 1 + + libbpf/src/libbpf.c | 3 ++- + src/common.c | 1 + + src/prog.c | 1 + + 6 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index 0210f85..f4e5102 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -952,6 +952,9 @@ enum bpf_prog_type { + BPF_PROG_TYPE_LSM, + BPF_PROG_TYPE_SK_LOOKUP, + BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ ++#ifndef __GENKSYMS__ ++ BPF_PROG_TYPE_SCHED, ++#endif + }; + + enum bpf_attach_type { +@@ -998,6 +1001,9 @@ enum bpf_attach_type { + BPF_SK_REUSEPORT_SELECT_OR_MIGRATE, + BPF_PERF_EVENT, + BPF_TRACE_KPROBE_MULTI, ++#ifndef __GENKSYMS__ ++ BPF_SCHED, ++#endif + __MAX_BPF_ATTACH_TYPE + }; + +diff --git a/libbpf/include/uapi/linux/bpf.h b/libbpf/include/uapi/linux/bpf.h +index 0210f85..f4e5102 100644 +--- a/libbpf/include/uapi/linux/bpf.h ++++ b/libbpf/include/uapi/linux/bpf.h +@@ -952,6 +952,9 @@ enum bpf_prog_type { + BPF_PROG_TYPE_LSM, + BPF_PROG_TYPE_SK_LOOKUP, + BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ ++#ifndef __GENKSYMS__ ++ BPF_PROG_TYPE_SCHED, ++#endif + }; + + enum bpf_attach_type { +@@ -998,6 +1001,9 @@ enum bpf_attach_type { + BPF_SK_REUSEPORT_SELECT_OR_MIGRATE, + BPF_PERF_EVENT, + BPF_TRACE_KPROBE_MULTI, ++#ifndef __GENKSYMS__ ++ BPF_SCHED, ++#endif + __MAX_BPF_ATTACH_TYPE + }; + +diff --git a/libbpf/src/bpf.c b/libbpf/src/bpf.c +index 4677644..a223340 100644 +--- a/libbpf/src/bpf.c ++++ b/libbpf/src/bpf.c +@@ -484,6 +484,7 @@ static int bpf_load_program_xattr2(const struct bpf_load_program_attr *load_attr + break; + case BPF_PROG_TYPE_TRACING: + case BPF_PROG_TYPE_EXT: ++ case BPF_PROG_TYPE_SCHED: + p.attach_btf_id = load_attr->attach_btf_id; + p.attach_prog_fd = load_attr->attach_prog_fd; + break; +diff --git a/libbpf/src/libbpf.c b/libbpf/src/libbpf.c +index 1a5ab2f..72a5c45 100644 +--- a/libbpf/src/libbpf.c ++++ b/libbpf/src/libbpf.c +@@ -7333,7 +7333,8 @@ static int bpf_object_init_progs(struct bpf_object *obj, const struct bpf_object + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" + if (prog->sec_def->prog_type == BPF_PROG_TYPE_TRACING || +- prog->sec_def->prog_type == BPF_PROG_TYPE_EXT) ++ prog->sec_def->prog_type == BPF_PROG_TYPE_EXT || ++ prog->type == BPF_PROG_TYPE_SCHED) + prog->attach_prog_fd = OPTS_GET(opts, attach_prog_fd, 0); + #pragma GCC diagnostic pop + +diff --git a/src/common.c b/src/common.c +index c740142..c2cff8e 100644 +--- a/src/common.c ++++ b/src/common.c +@@ -75,6 +75,7 @@ const char * const attach_type_name[__MAX_BPF_ATTACH_TYPE] = { + [BPF_SK_REUSEPORT_SELECT_OR_MIGRATE] = "sk_skb_reuseport_select_or_migrate", + [BPF_PERF_EVENT] = "perf_event", + [BPF_TRACE_KPROBE_MULTI] = "trace_kprobe_multi", ++ [BPF_SCHED] = "sched", + }; + + void p_err(const char *fmt, ...) +diff --git a/src/prog.c b/src/prog.c +index 5c2c63d..3e385d6 100644 +--- a/src/prog.c ++++ b/src/prog.c +@@ -69,6 +69,7 @@ const char * const prog_type_name[] = { + [BPF_PROG_TYPE_LSM] = "lsm", + [BPF_PROG_TYPE_SK_LOOKUP] = "sk_lookup", + [BPF_PROG_TYPE_SYSCALL] = "syscall", ++ [BPF_PROG_TYPE_SCHED] = "sched", + }; + + const size_t prog_type_name_size = ARRAY_SIZE(prog_type_name); +-- +2.33.0 + diff --git a/bpftool-use-a-local-bpf_perf_event_value-to-fix-acce.patch b/bpftool-use-a-local-bpf_perf_event_value-to-fix-acce.patch new file mode 100644 index 0000000000000000000000000000000000000000..88b35221eec75e5dd2f5b939cd369559c0e872bd --- /dev/null +++ b/bpftool-use-a-local-bpf_perf_event_value-to-fix-acce.patch @@ -0,0 +1,130 @@ +From b00d0c5587d2da425904a26b8537abca184df3e2 Mon Sep 17 00:00:00 2001 +From: Alexander Lobakin +Date: Fri, 7 Jul 2023 10:54:25 +0100 +Subject: [PATCH] bpftool: Use a local bpf_perf_event_value to fix accessing + its fields + +Fix the following error when building bpftool: + + CLANG profiler.bpf.o + CLANG pid_iter.bpf.o +skeleton/profiler.bpf.c:18:21: error: invalid application of 'sizeof' to an incomplete type 'struct bpf_perf_event_value' + __uint(value_size, sizeof(struct bpf_perf_event_value)); + ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helpers.h:13:39: note: expanded from macro '__uint' +tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value' +struct bpf_perf_event_value; + ^ + +struct bpf_perf_event_value is being used in the kernel only when +CONFIG_BPF_EVENTS is enabled, so it misses a BTF entry then. +Define struct bpf_perf_event_value___local with the +`preserve_access_index` attribute inside the pid_iter BPF prog to +allow compiling on any configs. It is a full mirror of a UAPI +structure, so is compatible both with and w/o CO-RE. +bpf_perf_event_read_value() requires a pointer of the original type, +so a cast is needed. + +Fixes: 47c09d6a9f67 ("bpftool: Introduce "prog profile" command") +Suggested-by: Andrii Nakryiko +Signed-off-by: Alexander Lobakin +Signed-off-by: Quentin Monnet +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20230707095425.168126-5-quentin@isovalent.com +--- + src/skeleton/profiler.bpf.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/src/skeleton/profiler.bpf.c b/src/skeleton/profiler.bpf.c +index ce5b65e..2f80edc 100644 +--- a/src/skeleton/profiler.bpf.c ++++ b/src/skeleton/profiler.bpf.c +@@ -4,6 +4,12 @@ + #include + #include + ++struct bpf_perf_event_value___local { ++ __u64 counter; ++ __u64 enabled; ++ __u64 running; ++} __attribute__((preserve_access_index)); ++ + /* map of perf event fds, num_cpu * num_metric entries */ + struct { + __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); +@@ -15,14 +21,14 @@ struct { + struct { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __uint(key_size, sizeof(u32)); +- __uint(value_size, sizeof(struct bpf_perf_event_value)); ++ __uint(value_size, sizeof(struct bpf_perf_event_value___local)); + } fentry_readings SEC(".maps"); + + /* accumulated readings */ + struct { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __uint(key_size, sizeof(u32)); +- __uint(value_size, sizeof(struct bpf_perf_event_value)); ++ __uint(value_size, sizeof(struct bpf_perf_event_value___local)); + } accum_readings SEC(".maps"); + + /* sample counts, one per cpu */ +@@ -39,7 +45,7 @@ const volatile __u32 num_metric = 1; + SEC("fentry/XXX") + int BPF_PROG(fentry_XXX) + { +- struct bpf_perf_event_value *ptrs[MAX_NUM_MATRICS]; ++ struct bpf_perf_event_value___local *ptrs[MAX_NUM_MATRICS]; + u32 key = bpf_get_smp_processor_id(); + u32 i; + +@@ -53,10 +59,10 @@ int BPF_PROG(fentry_XXX) + } + + for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) { +- struct bpf_perf_event_value reading; ++ struct bpf_perf_event_value___local reading; + int err; + +- err = bpf_perf_event_read_value(&events, key, &reading, ++ err = bpf_perf_event_read_value(&events, key, (void *)&reading, + sizeof(reading)); + if (err) + return 0; +@@ -68,14 +74,14 @@ int BPF_PROG(fentry_XXX) + } + + static inline void +-fexit_update_maps(u32 id, struct bpf_perf_event_value *after) ++fexit_update_maps(u32 id, struct bpf_perf_event_value___local *after) + { +- struct bpf_perf_event_value *before, diff; ++ struct bpf_perf_event_value___local *before, diff; + + before = bpf_map_lookup_elem(&fentry_readings, &id); + /* only account samples with a valid fentry_reading */ + if (before && before->counter) { +- struct bpf_perf_event_value *accum; ++ struct bpf_perf_event_value___local *accum; + + diff.counter = after->counter - before->counter; + diff.enabled = after->enabled - before->enabled; +@@ -93,7 +99,7 @@ fexit_update_maps(u32 id, struct bpf_perf_event_value *after) + SEC("fexit/XXX") + int BPF_PROG(fexit_XXX) + { +- struct bpf_perf_event_value readings[MAX_NUM_MATRICS]; ++ struct bpf_perf_event_value___local readings[MAX_NUM_MATRICS]; + u32 cpu = bpf_get_smp_processor_id(); + u32 i, zero = 0; + int err; +@@ -102,7 +108,8 @@ int BPF_PROG(fexit_XXX) + /* read all events before updating the maps, to reduce error */ + for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) { + err = bpf_perf_event_read_value(&events, cpu + i * num_cpu, +- readings + i, sizeof(*readings)); ++ (void *)(readings + i), ++ sizeof(*readings)); + if (err) + return 0; + } diff --git a/bpftool-use-a-local-copy-of-bpf_link_type_perf_event.patch b/bpftool-use-a-local-copy-of-bpf_link_type_perf_event.patch new file mode 100644 index 0000000000000000000000000000000000000000..dd1e94bdff813abfb7c292c4eec72cecd867ff0e --- /dev/null +++ b/bpftool-use-a-local-copy-of-bpf_link_type_perf_event.patch @@ -0,0 +1,51 @@ +From fc96090dd8e4e9aaa59b3fd14d39b21deef592db Mon Sep 17 00:00:00 2001 +From: Quentin Monnet +Date: Fri, 7 Jul 2023 10:54:24 +0100 +Subject: [PATCH] bpftool: Use a local copy of BPF_LINK_TYPE_PERF_EVENT in + pid_iter.bpf.c + +In order to allow the BPF program in bpftool's pid_iter.bpf.c to compile +correctly on hosts where vmlinux.h does not define +BPF_LINK_TYPE_PERF_EVENT (running kernel versions lower than 5.15, for +example), define and use a local copy of the enum value. This requires +LLVM 12 or newer to build the BPF program. + +Fixes: cbdaf71f7e65 ("bpftool: Add bpf_cookie to link output") +Signed-off-by: Quentin Monnet +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20230707095425.168126-4-quentin@isovalent.com +--- + src/skeleton/pid_iter.bpf.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/skeleton/pid_iter.bpf.c b/src/skeleton/pid_iter.bpf.c +index 3a4c4f7..26004f0 100644 +--- a/src/skeleton/pid_iter.bpf.c ++++ b/src/skeleton/pid_iter.bpf.c +@@ -24,6 +24,10 @@ struct perf_event___local { + u64 bpf_cookie; + } __attribute__((preserve_access_index)); + ++enum bpf_link_type___local { ++ BPF_LINK_TYPE_PERF_EVENT___local = 7, ++}; ++ + extern const void bpf_link_fops __ksym; + extern const void bpf_map_fops __ksym; + extern const void bpf_prog_fops __ksym; +@@ -93,10 +97,13 @@ int iter(struct bpf_iter__task_file *ctx) + e.pid = task->tgid; + e.id = get_obj_id(file->private_data, obj_type); + +- if (obj_type == BPF_OBJ_LINK) { ++ if (obj_type == BPF_OBJ_LINK && ++ bpf_core_enum_value_exists(enum bpf_link_type___local, ++ BPF_LINK_TYPE_PERF_EVENT___local)) { + struct bpf_link *link = (struct bpf_link *) file->private_data; + +- if (BPF_CORE_READ(link, type) == BPF_LINK_TYPE_PERF_EVENT) { ++ if (link->type == bpf_core_enum_value(enum bpf_link_type___local, ++ BPF_LINK_TYPE_PERF_EVENT___local)) { + e.has_bpf_cookie = true; + e.bpf_cookie = get_bpf_cookie(link); + } diff --git a/bpftool-use-a-local-copy-of-perf_event-to-fix-access.patch b/bpftool-use-a-local-copy-of-perf_event-to-fix-access.patch new file mode 100644 index 0000000000000000000000000000000000000000..5d35764bc43f311e8d8eaefe8f16008e5c105e38 --- /dev/null +++ b/bpftool-use-a-local-copy-of-perf_event-to-fix-access.patch @@ -0,0 +1,62 @@ +From 1f5829e1e8b0bd4b3ac11629fe66aea2eb519ca8 Mon Sep 17 00:00:00 2001 +From: Alexander Lobakin +Date: Fri, 7 Jul 2023 10:54:22 +0100 +Subject: [PATCH] bpftool: use a local copy of perf_event to fix accessing :: + Bpf_cookie + +When CONFIG_PERF_EVENTS is not set, struct perf_event remains empty. +However, the structure is being used by bpftool indirectly via BTF. +This leads to: + +skeleton/pid_iter.bpf.c:49:30: error: no member named 'bpf_cookie' in 'struct perf_event' + return BPF_CORE_READ(event, bpf_cookie); + ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~ + +... + +skeleton/pid_iter.bpf.c:49:9: error: returning 'void' from a function with incompatible result type '__u64' (aka 'unsigned long long') + return BPF_CORE_READ(event, bpf_cookie); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Tools and samples can't use any CONFIG_ definitions, so the fields +used there should always be present. +Define struct perf_event___local with the `preserve_access_index` +attribute inside the pid_iter BPF prog to allow compiling on any +configs. CO-RE will substitute it with the real struct perf_event +accesses later on. + +Fixes: cbdaf71f7e65 ("bpftool: Add bpf_cookie to link output") +Suggested-by: Andrii Nakryiko +Signed-off-by: Alexander Lobakin +Signed-off-by: Quentin Monnet +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20230707095425.168126-2-quentin@isovalent.com +--- + src/skeleton/pid_iter.bpf.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/skeleton/pid_iter.bpf.c b/src/skeleton/pid_iter.bpf.c +index eb05ea5..e2af8e5 100644 +--- a/src/skeleton/pid_iter.bpf.c ++++ b/src/skeleton/pid_iter.bpf.c +@@ -15,6 +15,10 @@ enum bpf_obj_type { + BPF_OBJ_BTF, + }; + ++struct perf_event___local { ++ u64 bpf_cookie; ++} __attribute__((preserve_access_index)); ++ + extern const void bpf_link_fops __ksym; + extern const void bpf_map_fops __ksym; + extern const void bpf_prog_fops __ksym; +@@ -41,8 +45,8 @@ static __always_inline __u32 get_obj_id(void *ent, enum bpf_obj_type type) + /* could be used only with BPF_LINK_TYPE_PERF_EVENT links */ + static __u64 get_bpf_cookie(struct bpf_link *link) + { ++ struct perf_event___local *event; + struct bpf_perf_link *perf_link; +- struct perf_event *event; + + perf_link = container_of(link, struct bpf_perf_link, link); + event = BPF_CORE_READ(perf_link, perf_file, private_data); diff --git a/bpftool.spec b/bpftool.spec new file mode 100644 index 0000000000000000000000000000000000000000..1775581acd205134c3c996737eed421e8d7d8f02 --- /dev/null +++ b/bpftool.spec @@ -0,0 +1,58 @@ +Name: bpftool +Version: 6.8.0 +Release: 1 +Summary: Tool for inspection and manipulation of BPF programs and maps +License: GPL-2.0-only +URL: https://www.kernel.org/ +BuildRequires: elfutils-devel libcap-devel binutils-devel clang python3-docutils llvm + +Source0: https://github.com/libbpf/bpftool/archive/refs/tags/%{name}-libbpf-v%{version}.tar.gz + +Patch0: bpftool-use-a-local-copy-of-perf_event-to-fix-access.patch +Patch1: bpftool-define-a-local-bpf_perf_link-to-fix-accessin.patch +Patch2: bpftool-use-a-local-copy-of-bpf_link_type_perf_event.patch +Patch3: bpftool-use-a-local-bpf_perf_event_value-to-fix-acce.patch +Patch4: bpftool-recognize-scheduler-programs.patch +Patch5: bpftool-Fix-a-wrong-type-cast-in-btf_dumper_int.patch +Patch6: bpftool-Clear-errno-after-libcaps-checks.patch +Patch7: bpftool-Fix-NULL-pointer-dereference-when-pin-PROG-M.patch +Patch8: bpftool-profile-online-CPUs-instead-of-possible.patch +Patch9: tools-bpftool-Remove-invalid-json-escape.patch +Patch10: bpftool-Fix-bug-for-long-instructions-in-program-CFG.patch + +%description +bpftool allows for inspection and simple modification of BPF objects (programs +and maps) on the system. + +%package bash-completion +Summary: Bash completion for bpftool +Requires: %{name} +Requires: bash-completion +Supplements: (%{name} and bash-completion) + +%description bash-completion +bash command line completion support for bpftool. + +%prep +%autosetup -p1 -n %{name}-%{version} + +%build +%make_build -C src V=1 +%make_build -C docs V=1 man + +%install +make -C src V=1 install DESTDIR=%{buildroot} prefix=%{_prefix} mandir=%{_mandir} +make -C docs V=1 install DESTDIR=%{buildroot} prefix=%{_prefix} mandir=%{_mandir} + +%files +%license LICENSE LICENSE.BSD-2-Clause LICENSE.GPL-2.0 +%doc README.md +%{_sbindir}/bpftool +%{_mandir}/man?/*.gz + +%files bash-completion +%{_datadir}/bash-completion/completions/bpftool + +%changelog +* Tue Nov 21 2023 liuxin - 6.8.0-1 +- Init package diff --git a/tools-bpftool-Remove-invalid-json-escape.patch b/tools-bpftool-Remove-invalid-json-escape.patch new file mode 100644 index 0000000000000000000000000000000000000000..bbc82e590e25d2d732a002689775439d8a4c91ee --- /dev/null +++ b/tools-bpftool-Remove-invalid-json-escape.patch @@ -0,0 +1,51 @@ +From 3ab6ec6c485b6a0b8811faa5e6166d67584001cc Mon Sep 17 00:00:00 2001 +From: Luis Gerhorst +Date: Mon, 27 Feb 2023 16:08:54 +0100 +Subject: tools: bpftool: Remove invalid \' json escape + +[ Upstream commit c679bbd611c08b0559ffae079330bc4e5574696a ] + +RFC8259 ("The JavaScript Object Notation (JSON) Data Interchange +Format") only specifies \", \\, \/, \b, \f, \n, \r, and \r as valid +two-character escape sequences. This does not include \', which is not +required in JSON because it exclusively uses double quotes as string +separators. + +Solidus (/) may be escaped, but does not have to. Only reverse +solidus (\), double quotes ("), and the control characters have to be +escaped. Therefore, with this fix, bpftool correctly supports all valid +two-character escape sequences (but still does not support characters +that require multi-character escape sequences). + +Witout this fix, attempting to load a JSON file generated by bpftool +using Python 3.10.6's default json.load() may fail with the error +"Invalid \escape" if the file contains the invalid escaped single +quote (\'). + +Fixes: b66e907cfee2 ("tools: bpftool: copy JSON writer from iproute2 repository") +Signed-off-by: Luis Gerhorst +Signed-off-by: Andrii Nakryiko +Reviewed-by: Quentin Monnet +Link: https://lore.kernel.org/bpf/20230227150853.16863-1-gerhorst@cs.fau.de +Signed-off-by: Sasha Levin +--- + src/json_writer.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/json_writer.c b/src/json_writer.c +index 7fea83bedf488..bca5dd0a59e34 100644 +--- a/src/json_writer.c ++++ b/src/json_writer.c +@@ -80,9 +80,6 @@ static void jsonw_puts(json_writer_t *self, const char *str) + case '"': + fputs("\\\"", self->out); + break; +- case '\'': +- fputs("\\\'", self->out); +- break; + default: + putc(*str, self->out); + } +-- +cgit +