1 // SPDX-License-Identifier: GPL-2.0
2 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
3 #include <linux/init.h>
4 #include <linux/module.h>
5 #include "bpf_preload.h"
6 #include "iterators/iterators.lskel.h"
7 
8 static struct bpf_link *maps_link, *progs_link;
9 static struct iterators_bpf *skel;
10 
free_links_and_skel(void)11 static void free_links_and_skel(void)
12 {
13 	if (!IS_ERR_OR_NULL(maps_link))
14 		bpf_link_put(maps_link);
15 	if (!IS_ERR_OR_NULL(progs_link))
16 		bpf_link_put(progs_link);
17 	iterators_bpf__destroy(skel);
18 }
19 
preload(struct bpf_preload_info * obj)20 static int preload(struct bpf_preload_info *obj)
21 {
22 	strlcpy(obj[0].link_name, "maps.debug", sizeof(obj[0].link_name));
23 	obj[0].link = maps_link;
24 	strlcpy(obj[1].link_name, "progs.debug", sizeof(obj[1].link_name));
25 	obj[1].link = progs_link;
26 	return 0;
27 }
28 
29 static struct bpf_preload_ops ops = {
30 	.preload = preload,
31 	.owner = THIS_MODULE,
32 };
33 
load_skel(void)34 static int load_skel(void)
35 {
36 	int err;
37 
38 	skel = iterators_bpf__open();
39 	if (!skel)
40 		return -ENOMEM;
41 	err = iterators_bpf__load(skel);
42 	if (err)
43 		goto out;
44 	err = iterators_bpf__attach(skel);
45 	if (err)
46 		goto out;
47 	maps_link = bpf_link_get_from_fd(skel->links.dump_bpf_map_fd);
48 	if (IS_ERR(maps_link)) {
49 		err = PTR_ERR(maps_link);
50 		goto out;
51 	}
52 	progs_link = bpf_link_get_from_fd(skel->links.dump_bpf_prog_fd);
53 	if (IS_ERR(progs_link)) {
54 		err = PTR_ERR(progs_link);
55 		goto out;
56 	}
57 	/* Avoid taking over stdin/stdout/stderr of init process. Zeroing out
58 	 * makes skel_closenz() a no-op later in iterators_bpf__destroy().
59 	 */
60 	close_fd(skel->links.dump_bpf_map_fd);
61 	skel->links.dump_bpf_map_fd = 0;
62 	close_fd(skel->links.dump_bpf_prog_fd);
63 	skel->links.dump_bpf_prog_fd = 0;
64 	return 0;
65 out:
66 	free_links_and_skel();
67 	return err;
68 }
69 
load(void)70 static int __init load(void)
71 {
72 	int err;
73 
74 	err = load_skel();
75 	if (err)
76 		return err;
77 	bpf_preload_ops = &ops;
78 	return err;
79 }
80 
fini(void)81 static void __exit fini(void)
82 {
83 	bpf_preload_ops = NULL;
84 	free_links_and_skel();
85 }
86 late_initcall(load);
87 module_exit(fini);
88 MODULE_LICENSE("GPL");
89