bpf: Implement link_query for bpf iterators
This patch implemented bpf_link callback functions show_fdinfo and fill_link_info to support link_query interface. The general interface for show_fdinfo and fill_link_info will print/fill the target_name. Each targets can register show_fdinfo and fill_link_info callbacks to print/fill more target specific information. For example, the below is a fdinfo result for a bpf task iterator. $ cat /proc/1749/fdinfo/7 pos: 0 flags: 02000000 mnt_id: 14 link_type: iter link_id: 11 prog_tag: 990e1f8152f7e54f prog_id: 59 target_name: task Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20200821184418.574122-1-yhs@fb.com
This commit is contained in:
Родитель
149cb33955
Коммит
6b0a249a30
|
@ -1218,12 +1218,18 @@ typedef int (*bpf_iter_attach_target_t)(struct bpf_prog *prog,
|
|||
union bpf_iter_link_info *linfo,
|
||||
struct bpf_iter_aux_info *aux);
|
||||
typedef void (*bpf_iter_detach_target_t)(struct bpf_iter_aux_info *aux);
|
||||
typedef void (*bpf_iter_show_fdinfo_t) (const struct bpf_iter_aux_info *aux,
|
||||
struct seq_file *seq);
|
||||
typedef int (*bpf_iter_fill_link_info_t)(const struct bpf_iter_aux_info *aux,
|
||||
struct bpf_link_info *info);
|
||||
|
||||
#define BPF_ITER_CTX_ARG_MAX 2
|
||||
struct bpf_iter_reg {
|
||||
const char *target;
|
||||
bpf_iter_attach_target_t attach_target;
|
||||
bpf_iter_detach_target_t detach_target;
|
||||
bpf_iter_show_fdinfo_t show_fdinfo;
|
||||
bpf_iter_fill_link_info_t fill_link_info;
|
||||
u32 ctx_arg_info_size;
|
||||
struct bpf_ctx_arg_aux ctx_arg_info[BPF_ITER_CTX_ARG_MAX];
|
||||
const struct bpf_iter_seq_info *seq_info;
|
||||
|
|
|
@ -4071,6 +4071,13 @@ struct bpf_link_info {
|
|||
__u64 cgroup_id;
|
||||
__u32 attach_type;
|
||||
} cgroup;
|
||||
struct {
|
||||
__aligned_u64 target_name; /* in/out: target_name buffer ptr */
|
||||
__u32 target_name_len; /* in/out: target_name buffer len */
|
||||
union {
|
||||
__u32 map_id;
|
||||
} map;
|
||||
} iter;
|
||||
struct {
|
||||
__u32 netns_ino;
|
||||
__u32 attach_type;
|
||||
|
|
|
@ -377,10 +377,68 @@ out_unlock:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void bpf_iter_link_show_fdinfo(const struct bpf_link *link,
|
||||
struct seq_file *seq)
|
||||
{
|
||||
struct bpf_iter_link *iter_link =
|
||||
container_of(link, struct bpf_iter_link, link);
|
||||
bpf_iter_show_fdinfo_t show_fdinfo;
|
||||
|
||||
seq_printf(seq,
|
||||
"target_name:\t%s\n",
|
||||
iter_link->tinfo->reg_info->target);
|
||||
|
||||
show_fdinfo = iter_link->tinfo->reg_info->show_fdinfo;
|
||||
if (show_fdinfo)
|
||||
show_fdinfo(&iter_link->aux, seq);
|
||||
}
|
||||
|
||||
static int bpf_iter_link_fill_link_info(const struct bpf_link *link,
|
||||
struct bpf_link_info *info)
|
||||
{
|
||||
struct bpf_iter_link *iter_link =
|
||||
container_of(link, struct bpf_iter_link, link);
|
||||
char __user *ubuf = u64_to_user_ptr(info->iter.target_name);
|
||||
bpf_iter_fill_link_info_t fill_link_info;
|
||||
u32 ulen = info->iter.target_name_len;
|
||||
const char *target_name;
|
||||
u32 target_len;
|
||||
|
||||
if (!ulen ^ !ubuf)
|
||||
return -EINVAL;
|
||||
|
||||
target_name = iter_link->tinfo->reg_info->target;
|
||||
target_len = strlen(target_name);
|
||||
info->iter.target_name_len = target_len + 1;
|
||||
|
||||
if (ubuf) {
|
||||
if (ulen >= target_len + 1) {
|
||||
if (copy_to_user(ubuf, target_name, target_len + 1))
|
||||
return -EFAULT;
|
||||
} else {
|
||||
char zero = '\0';
|
||||
|
||||
if (copy_to_user(ubuf, target_name, ulen - 1))
|
||||
return -EFAULT;
|
||||
if (put_user(zero, ubuf + ulen - 1))
|
||||
return -EFAULT;
|
||||
return -ENOSPC;
|
||||
}
|
||||
}
|
||||
|
||||
fill_link_info = iter_link->tinfo->reg_info->fill_link_info;
|
||||
if (fill_link_info)
|
||||
return fill_link_info(&iter_link->aux, info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct bpf_link_ops bpf_iter_link_lops = {
|
||||
.release = bpf_iter_link_release,
|
||||
.dealloc = bpf_iter_link_dealloc,
|
||||
.update_prog = bpf_iter_link_replace,
|
||||
.show_fdinfo = bpf_iter_link_show_fdinfo,
|
||||
.fill_link_info = bpf_iter_link_fill_link_info,
|
||||
};
|
||||
|
||||
bool bpf_link_is_iter(struct bpf_link *link)
|
||||
|
|
|
@ -4071,6 +4071,13 @@ struct bpf_link_info {
|
|||
__u64 cgroup_id;
|
||||
__u32 attach_type;
|
||||
} cgroup;
|
||||
struct {
|
||||
__aligned_u64 target_name; /* in/out: target_name buffer ptr */
|
||||
__u32 target_name_len; /* in/out: target_name buffer len */
|
||||
union {
|
||||
__u32 map_id;
|
||||
} map;
|
||||
} iter;
|
||||
struct {
|
||||
__u32 netns_ino;
|
||||
__u32 attach_type;
|
||||
|
|
Загрузка…
Ссылка в новой задаче