forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bpf: Add kernel module with user mode driver that populates bpffs.
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 <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
- Loading branch information
Showing
13 changed files
with
390 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
config USERMODE_DRIVER | ||
bool | ||
default n | ||
|
||
menuconfig BPF_PRELOAD | ||
bool "Preload BPF file system with kernel specific program and map iterators" | ||
depends on BPF | ||
select USERMODE_DRIVER | ||
help | ||
This builds kernel module with several embedded BPF programs that are | ||
pinned into BPF FS mount point as human readable files that are | ||
useful in debugging and introspection of BPF programs and maps. | ||
|
||
if BPF_PRELOAD | ||
config BPF_PRELOAD_UMD | ||
tristate "bpf_preload kernel module with user mode driver" | ||
depends on CC_CAN_LINK | ||
depends on m || CC_CAN_LINK_STATIC | ||
default m | ||
help | ||
This builds bpf_preload kernel module with embedded user mode driver. | ||
endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
|
||
LIBBPF_SRCS = $(srctree)/tools/lib/bpf/ | ||
LIBBPF_A = $(obj)/libbpf.a | ||
LIBBPF_OUT = $(abspath $(obj)) | ||
|
||
$(LIBBPF_A): | ||
$(Q)$(MAKE) -C $(LIBBPF_SRCS) OUTPUT=$(LIBBPF_OUT)/ $(LIBBPF_OUT)/libbpf.a | ||
|
||
userccflags += -I $(srctree)/tools/include/ -I $(srctree)/tools/include/uapi \ | ||
-I $(srctree)/tools/lib/ -Wno-unused-result | ||
|
||
userprogs := bpf_preload_umd | ||
|
||
bpf_preload_umd-objs := iterators/iterators.o | ||
bpf_preload_umd-userldlibs := $(LIBBPF_A) -lelf -lz | ||
|
||
$(obj)/bpf_preload_umd: $(LIBBPF_A) | ||
|
||
$(obj)/bpf_preload_umd_blob.o: $(obj)/bpf_preload_umd | ||
|
||
obj-$(CONFIG_BPF_PRELOAD_UMD) += bpf_preload.o | ||
bpf_preload-objs += bpf_preload_kern.o bpf_preload_umd_blob.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef _BPF_PRELOAD_H | ||
#define _BPF_PRELOAD_H | ||
|
||
#include <linux/usermode_driver.h> | ||
#include "iterators/bpf_preload_common.h" | ||
|
||
struct bpf_preload_ops { | ||
struct umd_info info; | ||
int (*preload)(struct bpf_preload_info *); | ||
int (*finish)(void); | ||
struct module *owner; | ||
}; | ||
extern struct bpf_preload_ops *bpf_preload_ops; | ||
#define BPF_PRELOAD_LINKS 2 | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
#include <linux/init.h> | ||
#include <linux/module.h> | ||
#include <linux/pid.h> | ||
#include <linux/fs.h> | ||
#include <linux/sched/signal.h> | ||
#include "bpf_preload.h" | ||
|
||
extern char bpf_preload_umd_start; | ||
extern char bpf_preload_umd_end; | ||
|
||
static int preload(struct bpf_preload_info *obj); | ||
static int finish(void); | ||
|
||
static struct bpf_preload_ops umd_ops = { | ||
.info.driver_name = "bpf_preload", | ||
.preload = preload, | ||
.finish = finish, | ||
.owner = THIS_MODULE, | ||
}; | ||
|
||
static int preload(struct bpf_preload_info *obj) | ||
{ | ||
int magic = BPF_PRELOAD_START; | ||
loff_t pos = 0; | ||
int i, err; | ||
ssize_t n; | ||
|
||
err = fork_usermode_driver(&umd_ops.info); | ||
if (err) | ||
return err; | ||
|
||
/* send the start magic to let UMD proceed with loading BPF progs */ | ||
n = kernel_write(umd_ops.info.pipe_to_umh, | ||
&magic, sizeof(magic), &pos); | ||
if (n != sizeof(magic)) | ||
return -EPIPE; | ||
|
||
/* receive bpf_link IDs and names from UMD */ | ||
pos = 0; | ||
for (i = 0; i < BPF_PRELOAD_LINKS; i++) { | ||
n = kernel_read(umd_ops.info.pipe_from_umh, | ||
&obj[i], sizeof(*obj), &pos); | ||
if (n != sizeof(*obj)) | ||
return -EPIPE; | ||
} | ||
return 0; | ||
} | ||
|
||
static int finish(void) | ||
{ | ||
int magic = BPF_PRELOAD_END; | ||
struct pid *tgid; | ||
loff_t pos = 0; | ||
ssize_t n; | ||
|
||
/* send the last magic to UMD. It will do a normal exit. */ | ||
n = kernel_write(umd_ops.info.pipe_to_umh, | ||
&magic, sizeof(magic), &pos); | ||
if (n != sizeof(magic)) | ||
return -EPIPE; | ||
tgid = umd_ops.info.tgid; | ||
wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); | ||
umd_ops.info.tgid = NULL; | ||
return 0; | ||
} | ||
|
||
static int __init load_umd(void) | ||
{ | ||
int err; | ||
|
||
err = umd_load_blob(&umd_ops.info, &bpf_preload_umd_start, | ||
&bpf_preload_umd_end - &bpf_preload_umd_start); | ||
if (err) | ||
return err; | ||
bpf_preload_ops = &umd_ops; | ||
return err; | ||
} | ||
|
||
static void __exit fini_umd(void) | ||
{ | ||
bpf_preload_ops = NULL; | ||
/* kill UMD in case it's still there due to earlier error */ | ||
kill_pid(umd_ops.info.tgid, SIGKILL, 1); | ||
umd_ops.info.tgid = NULL; | ||
umd_unload_blob(&umd_ops.info); | ||
} | ||
late_initcall(load_umd); | ||
module_exit(fini_umd); | ||
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
.section .init.rodata, "a" | ||
.global bpf_preload_umd_start | ||
bpf_preload_umd_start: | ||
.incbin "kernel/bpf/preload/bpf_preload_umd" | ||
.global bpf_preload_umd_end | ||
bpf_preload_umd_end: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef _BPF_PRELOAD_COMMON_H | ||
#define _BPF_PRELOAD_COMMON_H | ||
|
||
#define BPF_PRELOAD_START 0x5555 | ||
#define BPF_PRELOAD_END 0xAAAA | ||
|
||
struct bpf_preload_info { | ||
char link_name[16]; | ||
int link_id; | ||
}; | ||
|
||
#endif |
Oops, something went wrong.