From c2376051362e9d4a2718421dd050cf1c01dc6ab9 Mon Sep 17 00:00:00 2001 From: Bernhard Kaindl Date: Fri, 3 May 2024 12:00:00 +0000 Subject: [PATCH] libbpf tcptop: Fix "unrecognized bpf_ld_imm64 insn" on 4.19 Fix the BPF load error `unrecognized bpf_ld_imm64 insn` on 4.19 by converting rodata config variables to a map. tcptop can use CO-RE including 4.19 when a detached vmlinux BTF file is provided, generated from a DWARF vmlinux using pahole: pahole -J;objcopy --only-section=.BTF vmlinux /boot/vmlinux-$(uname -r) Signed-off-by: Bernhard Kaindl --- libbpf-tools/tcptop.bpf.c | 20 ++++++++++++++------ libbpf-tools/tcptop.c | 16 ++++++++++++---- libbpf-tools/tcptop.h | 6 ++++++ 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/libbpf-tools/tcptop.bpf.c b/libbpf-tools/tcptop.bpf.c index 9c27ba485112..5c9eb5c7b8bf 100644 --- a/libbpf-tools/tcptop.bpf.c +++ b/libbpf-tools/tcptop.bpf.c @@ -12,9 +12,12 @@ #define AF_INET 2 /* Internet IP Protocol */ #define AF_INET6 10 /* IP version 6 */ -const volatile bool filter_cg = false; -const volatile pid_t target_pid = -1; -const volatile int target_family = -1; +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, 1); + __type(key, u32); + __type(value, struct filter_cfg_t); +} filter_cfg_map SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY); @@ -32,20 +35,25 @@ struct { static int probe_ip(bool receiving, struct sock *sk, size_t size) { + int zero = 0; + struct filter_cfg_t *args = bpf_map_lookup_elem(&filter_cfg_map, &zero); + if (!args) + return 0; + struct ip_key_t ip_key = {}; struct traffic_t *trafficp; u16 family; u32 pid; - if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0)) + if (args->filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0)) return 0; pid = bpf_get_current_pid_tgid() >> 32; - if (target_pid != -1 && target_pid != pid) + if (args->target_pid != -1 && args->target_pid != pid) return 0; family = BPF_CORE_READ(sk, __sk_common.skc_family); - if (target_family != -1 && target_family != family) + if (args->target_family != -1 && args->target_family != family) return 0; /* drop */ diff --git a/libbpf-tools/tcptop.c b/libbpf-tools/tcptop.c index d19fb9397633..04a6ed5a012f 100644 --- a/libbpf-tools/tcptop.c +++ b/libbpf-tools/tcptop.c @@ -339,6 +339,7 @@ int main(int argc, char **argv) struct tcptop_bpf *obj; int family; int cgfd = -1; + int zero = 0; int err; err = argp_parse(&argp, argc, argv, 0, NULL, NULL); @@ -359,9 +360,11 @@ int main(int argc, char **argv) return 1; } - obj->rodata->target_pid = target_pid; - obj->rodata->target_family = family; - obj->rodata->filter_cg = cgroup_filtering; + struct filter_cfg_t filter_cfg = { + .filter_cg = cgroup_filtering, + .target_pid = target_pid, + .target_family = family, + }; err = tcptop_bpf__load(obj); if (err) { @@ -369,8 +372,13 @@ int main(int argc, char **argv) goto cleanup; } + int filter_cfg_fd = bpf_map__fd(obj->maps.filter_cfg_map); + if (bpf_map_update_elem(filter_cfg_fd, &zero, &filter_cfg, BPF_ANY)) { + warn("Failed to update filter config map\n"); + goto cleanup; + } + if (cgroup_filtering) { - int zero = 0; int cg_map_fd = bpf_map__fd(obj->maps.cgroup_map); cgfd = open(cgroup_path, O_RDONLY); diff --git a/libbpf-tools/tcptop.h b/libbpf-tools/tcptop.h index 9e086c744ec2..48809e8fd869 100644 --- a/libbpf-tools/tcptop.h +++ b/libbpf-tools/tcptop.h @@ -4,6 +4,12 @@ #define TASK_COMM_LEN 16 +struct filter_cfg_t { + bool filter_cg; + pid_t target_pid; + int target_family; +}; + struct ip_key_t { unsigned __int128 saddr; unsigned __int128 daddr;