// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2020 Facebook */ #include #include #include #include #include #include #include #include #include #include #include "iterators.skel.h" #include "bpf_preload_common.h" int to_kernel = -1; int from_kernel = 0; static int send_link_to_kernel(struct bpf_link *link, const char *link_name) { struct bpf_preload_info obj = {}; struct bpf_link_info info = {}; __u32 info_len = sizeof(info); int err; err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &info, &info_len); if (err) return err; obj.link_id = info.id; if (strlen(link_name) >= sizeof(obj.link_name)) return -E2BIG; strcpy(obj.link_name, link_name); if (write(to_kernel, &obj, sizeof(obj)) != sizeof(obj)) return -EPIPE; return 0; } int main(int argc, char **argv) { struct rlimit rlim = { RLIM_INFINITY, RLIM_INFINITY }; struct iterators_bpf *skel; int err, magic; int debug_fd; debug_fd = open("/dev/console", O_WRONLY | O_NOCTTY | O_CLOEXEC); if (debug_fd < 0) return 1; to_kernel = dup(1); close(1); dup(debug_fd); /* now stdin and stderr point to /dev/console */ read(from_kernel, &magic, sizeof(magic)); if (magic != BPF_PRELOAD_START) { printf("bad start magic %d\n", magic); return 1; } setrlimit(RLIMIT_MEMLOCK, &rlim); /* libbpf opens BPF object and loads it into the kernel */ skel = iterators_bpf__open_and_load(); if (!skel) { /* iterators.skel.h is little endian. * libbpf doesn't support automatic little->big conversion * of BPF bytecode yet. * The program load will fail in such case. */ printf("Failed load could be due to wrong endianness\n"); return 1; } err = iterators_bpf__attach(skel); if (err) goto cleanup; /* send two bpf_link IDs with names to the kernel */ err = send_link_to_kernel(skel->links.dump_bpf_map, "maps.debug"); if (err) goto cleanup; err = send_link_to_kernel(skel->links.dump_bpf_prog, "progs.debug"); if (err) goto cleanup; /* The kernel will proceed with pinnging the links in bpffs. * UMD will wait on read from pipe. */ read(from_kernel, &magic, sizeof(magic)); if (magic != BPF_PRELOAD_END) { printf("bad final magic %d\n", magic); err = -EINVAL; } cleanup: iterators_bpf__destroy(skel); return err != 0; }