114 lines
2.3 KiB
C
114 lines
2.3 KiB
C
|
// 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;
|
||
|
}
|
||
|
|
||
|
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\n");
|
||
|
|
||
|
BPF_SEQ_PRINTF(seq, "%4u %-16s%6d\n", map->id, map->name, map->max_entries);
|
||
|
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";
|