^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (c) 2020 Facebook */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/bpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/filter.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/btf_ids.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) struct bpf_iter_seq_prog_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) u32 prog_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) static void *bpf_prog_seq_start(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct bpf_iter_seq_prog_info *info = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct bpf_prog *prog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) prog = bpf_prog_get_curr_or_next(&info->prog_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) if (!prog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (*pos == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return prog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static void *bpf_prog_seq_next(struct seq_file *seq, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct bpf_iter_seq_prog_info *info = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ++info->prog_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) bpf_prog_put((struct bpf_prog *)v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return bpf_prog_get_curr_or_next(&info->prog_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct bpf_iter__bpf_prog {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) __bpf_md_ptr(struct bpf_iter_meta *, meta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) __bpf_md_ptr(struct bpf_prog *, prog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) DEFINE_BPF_ITER_FUNC(bpf_prog, struct bpf_iter_meta *meta, struct bpf_prog *prog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int __bpf_prog_seq_show(struct seq_file *seq, void *v, bool in_stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct bpf_iter__bpf_prog ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct bpf_iter_meta meta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct bpf_prog *prog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ctx.meta = &meta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ctx.prog = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) meta.seq = seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) prog = bpf_iter_get_info(&meta, in_stop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (prog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ret = bpf_iter_run_prog(prog, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int bpf_prog_seq_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return __bpf_prog_seq_show(seq, v, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static void bpf_prog_seq_stop(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (!v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) (void)__bpf_prog_seq_show(seq, v, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) bpf_prog_put((struct bpf_prog *)v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static const struct seq_operations bpf_prog_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .start = bpf_prog_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .next = bpf_prog_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .stop = bpf_prog_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .show = bpf_prog_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) BTF_ID_LIST(btf_bpf_prog_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) BTF_ID(struct, bpf_prog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static const struct bpf_iter_seq_info bpf_prog_seq_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .seq_ops = &bpf_prog_seq_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .init_seq_private = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .fini_seq_private = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .seq_priv_size = sizeof(struct bpf_iter_seq_prog_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static struct bpf_iter_reg bpf_prog_reg_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .target = "bpf_prog",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .ctx_arg_info_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .ctx_arg_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) { offsetof(struct bpf_iter__bpf_prog, prog),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) PTR_TO_BTF_ID_OR_NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .seq_info = &bpf_prog_seq_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int __init bpf_prog_iter_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) bpf_prog_reg_info.ctx_arg_info[0].btf_id = *btf_bpf_prog_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return bpf_iter_reg_target(&bpf_prog_reg_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) late_initcall(bpf_prog_iter_init);