1
2
3#include <linux/bpf.h>
4#include <bpf/bpf_helpers.h>
5#include <bpf/bpf_tracing.h>
6#include <bpf/bpf_core_read.h>
7
8#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)
9struct seq_file;
10struct bpf_iter_meta {
11 struct seq_file *seq;
12 __u64 session_id;
13 __u64 seq_num;
14};
15
16struct bpf_map {
17 __u32 id;
18 char name[16];
19 __u32 max_entries;
20};
21
22struct bpf_iter__bpf_map {
23 struct bpf_iter_meta *meta;
24 struct bpf_map *map;
25};
26
27struct btf_type {
28 __u32 name_off;
29};
30
31struct btf_header {
32 __u32 str_len;
33};
34
35struct btf {
36 const char *strings;
37 struct btf_type **types;
38 struct btf_header hdr;
39};
40
41struct bpf_prog_aux {
42 __u32 id;
43 char name[16];
44 const char *attach_func_name;
45 struct bpf_prog *linked_prog;
46 struct bpf_func_info *func_info;
47 struct btf *btf;
48};
49
50struct bpf_prog {
51 struct bpf_prog_aux *aux;
52};
53
54struct bpf_iter__bpf_prog {
55 struct bpf_iter_meta *meta;
56 struct bpf_prog *prog;
57};
58#pragma clang attribute pop
59
60static const char *get_name(struct btf *btf, long btf_id, const char *fallback)
61{
62 struct btf_type **types, *t;
63 unsigned int name_off;
64 const char *str;
65
66 if (!btf)
67 return fallback;
68 str = btf->strings;
69 types = btf->types;
70 bpf_probe_read_kernel(&t, sizeof(t), types + btf_id);
71 name_off = BPF_CORE_READ(t, name_off);
72 if (name_off >= btf->hdr.str_len)
73 return fallback;
74 return str + name_off;
75}
76
77SEC("iter/bpf_map")
78int dump_bpf_map(struct bpf_iter__bpf_map *ctx)
79{
80 struct seq_file *seq = ctx->meta->seq;
81 __u64 seq_num = ctx->meta->seq_num;
82 struct bpf_map *map = ctx->map;
83
84 if (!map)
85 return 0;
86
87 if (seq_num == 0)
88 BPF_SEQ_PRINTF(seq, " id name max_entries\n");
89
90 BPF_SEQ_PRINTF(seq, "%4u %-16s%6d\n", map->id, map->name, map->max_entries);
91 return 0;
92}
93
94SEC("iter/bpf_prog")
95int dump_bpf_prog(struct bpf_iter__bpf_prog *ctx)
96{
97 struct seq_file *seq = ctx->meta->seq;
98 __u64 seq_num = ctx->meta->seq_num;
99 struct bpf_prog *prog = ctx->prog;
100 struct bpf_prog_aux *aux;
101
102 if (!prog)
103 return 0;
104
105 aux = prog->aux;
106 if (seq_num == 0)
107 BPF_SEQ_PRINTF(seq, " id name attached\n");
108
109 BPF_SEQ_PRINTF(seq, "%4u %-16s %s %s\n", aux->id,
110 get_name(aux->btf, aux->func_info[0].type_id, aux->name),
111 aux->attach_func_name, aux->linked_prog->aux->name);
112 return 0;
113}
114char LICENSE[] SEC("license") = "GPL";
115