// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2020 Facebook */ #include <linux/bpf.h> #include <bpf/bpf_helpers.h> #include <bpf/bpf_core_read.h> #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record) struct seq_file; struct bpf_iter_meta { struct seq_file *seq; __u64 session_id; __u64 seq_num; }; struct bpf_map { __u32 id; char name[16]; __u32 max_entries; }; struct bpf_iter__bpf_map { struct bpf_iter_meta *meta; struct bpf_map *map; }; struct btf_type { __u32 name_off; }; struct btf_header { __u32 str_len; }; struct btf { const char *strings; struct btf_type **types; struct btf_header hdr; }; struct bpf_prog_aux { __u32 id; char name[16]; const char *attach_func_name; struct bpf_prog *dst_prog; struct bpf_func_info *func_info; struct btf *btf; }; struct bpf_prog { struct bpf_prog_aux *aux; }; struct bpf_iter__bpf_prog { struct bpf_iter_meta *meta; struct bpf_prog *prog; }; #pragma clang attribute pop static const char *get_name(struct btf *btf, long btf_id, const char *fallback) { struct btf_type **types, *t; unsigned int name_off; const char *str; if (!btf) return fallback; str = btf->strings; types = btf->types; bpf_probe_read_kernel(&t, sizeof(t), types + btf_id); name_off = BPF_CORE_READ(t, name_off); if (name_off >= btf->hdr.str_len) return fallback; return str + name_off; } __s64 bpf_map_sum_elem_count(struct bpf_map *map) __ksym; SEC("iter/bpf_map") int dump_bpf_map(struct bpf_iter__bpf_map *ctx) { struct seq_file *seq = ctx->meta->seq; __u64 seq_num = ctx->meta->seq_num; struct bpf_map *map = ctx->map; if (!map) return 0; if (seq_num == 0) BPF_SEQ_PRINTF(seq, " id name max_entries cur_entries\n"); BPF_SEQ_PRINTF(seq, "%4u %-16s %10d %10lld\n", map->id, map->name, map->max_entries, bpf_map_sum_elem_count(map)); return 0; } SEC("iter/bpf_prog") int dump_bpf_prog(struct bpf_iter__bpf_prog *ctx) { struct seq_file *seq = ctx->meta->seq; __u64 seq_num = ctx->meta->seq_num; struct bpf_prog *prog = ctx->prog; struct bpf_prog_aux *aux; if (!prog) return 0; aux = prog->aux; if (seq_num == 0) BPF_SEQ_PRINTF(seq, " id name attached\n"); BPF_SEQ_PRINTF(seq, "%4u %-16s %s %s\n", aux->id, get_name(aux->btf, aux->func_info[0].type_id, aux->name), aux->attach_func_name, aux->dst_prog->aux->name); return 0; } char LICENSE[] SEC("license") = "GPL";