mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-27 17:05:48 +07:00
d71fa5c976
Add kernel module with user mode driver that populates bpffs with BPF iterators. $ mount bpffs /my/bpffs/ -t bpf $ ls -la /my/bpffs/ total 4 drwxrwxrwt 2 root root 0 Jul 2 00:27 . drwxr-xr-x 19 root root 4096 Jul 2 00:09 .. -rw------- 1 root root 0 Jul 2 00:27 maps.debug -rw------- 1 root root 0 Jul 2 00:27 progs.debug The user mode driver will load BPF Type Formats, create BPF maps, populate BPF maps, load two BPF programs, attach them to BPF iterators, and finally send two bpf_link IDs back to the kernel. The kernel will pin two bpf_links into newly mounted bpffs instance under names "progs.debug" and "maps.debug". These two files become human readable. $ cat /my/bpffs/progs.debug id name attached 11 dump_bpf_map bpf_iter_bpf_map 12 dump_bpf_prog bpf_iter_bpf_prog 27 test_pkt_access 32 test_main test_pkt_access test_pkt_access 33 test_subprog1 test_pkt_access_subprog1 test_pkt_access 34 test_subprog2 test_pkt_access_subprog2 test_pkt_access 35 test_subprog3 test_pkt_access_subprog3 test_pkt_access 36 new_get_skb_len get_skb_len test_pkt_access 37 new_get_skb_ifindex get_skb_ifindex test_pkt_access 38 new_get_constant get_constant test_pkt_access The BPF program dump_bpf_prog() in iterators.bpf.c is printing this data about all BPF programs currently loaded in the system. This information is unstable and will change from kernel to kernel as ".debug" suffix conveys. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20200819042759.51280-4-alexei.starovoitov@gmail.com
95 lines
2.3 KiB
C
95 lines
2.3 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Copyright (c) 2020 Facebook */
|
|
#include <argp.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/resource.h>
|
|
#include <bpf/libbpf.h>
|
|
#include <bpf/bpf.h>
|
|
#include <sys/mount.h>
|
|
#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;
|
|
}
|