0001
0002
0003 #include <linux/bpf.h>
0004 #include <bpf/bpf_helpers.h>
0005 #include <bpf/bpf_core_read.h>
0006
0007 #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)
0008 struct seq_file;
0009 struct bpf_iter_meta {
0010 struct seq_file *seq;
0011 __u64 session_id;
0012 __u64 seq_num;
0013 };
0014
0015 struct bpf_map {
0016 __u32 id;
0017 char name[16];
0018 __u32 max_entries;
0019 };
0020
0021 struct bpf_iter__bpf_map {
0022 struct bpf_iter_meta *meta;
0023 struct bpf_map *map;
0024 };
0025
0026 struct btf_type {
0027 __u32 name_off;
0028 };
0029
0030 struct btf_header {
0031 __u32 str_len;
0032 };
0033
0034 struct btf {
0035 const char *strings;
0036 struct btf_type **types;
0037 struct btf_header hdr;
0038 };
0039
0040 struct bpf_prog_aux {
0041 __u32 id;
0042 char name[16];
0043 const char *attach_func_name;
0044 struct bpf_prog *dst_prog;
0045 struct bpf_func_info *func_info;
0046 struct btf *btf;
0047 };
0048
0049 struct bpf_prog {
0050 struct bpf_prog_aux *aux;
0051 };
0052
0053 struct bpf_iter__bpf_prog {
0054 struct bpf_iter_meta *meta;
0055 struct bpf_prog *prog;
0056 };
0057 #pragma clang attribute pop
0058
0059 static const char *get_name(struct btf *btf, long btf_id, const char *fallback)
0060 {
0061 struct btf_type **types, *t;
0062 unsigned int name_off;
0063 const char *str;
0064
0065 if (!btf)
0066 return fallback;
0067 str = btf->strings;
0068 types = btf->types;
0069 bpf_probe_read_kernel(&t, sizeof(t), types + btf_id);
0070 name_off = BPF_CORE_READ(t, name_off);
0071 if (name_off >= btf->hdr.str_len)
0072 return fallback;
0073 return str + name_off;
0074 }
0075
0076 SEC("iter/bpf_map")
0077 int dump_bpf_map(struct bpf_iter__bpf_map *ctx)
0078 {
0079 struct seq_file *seq = ctx->meta->seq;
0080 __u64 seq_num = ctx->meta->seq_num;
0081 struct bpf_map *map = ctx->map;
0082
0083 if (!map)
0084 return 0;
0085
0086 if (seq_num == 0)
0087 BPF_SEQ_PRINTF(seq, " id name max_entries\n");
0088
0089 BPF_SEQ_PRINTF(seq, "%4u %-16s%6d\n", map->id, map->name, map->max_entries);
0090 return 0;
0091 }
0092
0093 SEC("iter/bpf_prog")
0094 int dump_bpf_prog(struct bpf_iter__bpf_prog *ctx)
0095 {
0096 struct seq_file *seq = ctx->meta->seq;
0097 __u64 seq_num = ctx->meta->seq_num;
0098 struct bpf_prog *prog = ctx->prog;
0099 struct bpf_prog_aux *aux;
0100
0101 if (!prog)
0102 return 0;
0103
0104 aux = prog->aux;
0105 if (seq_num == 0)
0106 BPF_SEQ_PRINTF(seq, " id name attached\n");
0107
0108 BPF_SEQ_PRINTF(seq, "%4u %-16s %s %s\n", aux->id,
0109 get_name(aux->btf, aux->func_info[0].type_id, aux->name),
0110 aux->attach_func_name, aux->dst_prog->aux->name);
0111 return 0;
0112 }
0113 char LICENSE[] SEC("license") = "GPL";