Skip to content

Commit 6b0a249

Browse files
yonghong-songAlexei Starovoitov
authored andcommitted
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
1 parent 149cb33 commit 6b0a249

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

include/linux/bpf.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,12 +1218,18 @@ typedef int (*bpf_iter_attach_target_t)(struct bpf_prog *prog,
12181218
union bpf_iter_link_info *linfo,
12191219
struct bpf_iter_aux_info *aux);
12201220
typedef void (*bpf_iter_detach_target_t)(struct bpf_iter_aux_info *aux);
1221+
typedef void (*bpf_iter_show_fdinfo_t) (const struct bpf_iter_aux_info *aux,
1222+
struct seq_file *seq);
1223+
typedef int (*bpf_iter_fill_link_info_t)(const struct bpf_iter_aux_info *aux,
1224+
struct bpf_link_info *info);
12211225

12221226
#define BPF_ITER_CTX_ARG_MAX 2
12231227
struct bpf_iter_reg {
12241228
const char *target;
12251229
bpf_iter_attach_target_t attach_target;
12261230
bpf_iter_detach_target_t detach_target;
1231+
bpf_iter_show_fdinfo_t show_fdinfo;
1232+
bpf_iter_fill_link_info_t fill_link_info;
12271233
u32 ctx_arg_info_size;
12281234
struct bpf_ctx_arg_aux ctx_arg_info[BPF_ITER_CTX_ARG_MAX];
12291235
const struct bpf_iter_seq_info *seq_info;

include/uapi/linux/bpf.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4071,6 +4071,13 @@ struct bpf_link_info {
40714071
__u64 cgroup_id;
40724072
__u32 attach_type;
40734073
} cgroup;
4074+
struct {
4075+
__aligned_u64 target_name; /* in/out: target_name buffer ptr */
4076+
__u32 target_name_len; /* in/out: target_name buffer len */
4077+
union {
4078+
__u32 map_id;
4079+
} map;
4080+
} iter;
40744081
struct {
40754082
__u32 netns_ino;
40764083
__u32 attach_type;

kernel/bpf/bpf_iter.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,68 @@ static int bpf_iter_link_replace(struct bpf_link *link,
377377
return ret;
378378
}
379379

380+
static void bpf_iter_link_show_fdinfo(const struct bpf_link *link,
381+
struct seq_file *seq)
382+
{
383+
struct bpf_iter_link *iter_link =
384+
container_of(link, struct bpf_iter_link, link);
385+
bpf_iter_show_fdinfo_t show_fdinfo;
386+
387+
seq_printf(seq,
388+
"target_name:\t%s\n",
389+
iter_link->tinfo->reg_info->target);
390+
391+
show_fdinfo = iter_link->tinfo->reg_info->show_fdinfo;
392+
if (show_fdinfo)
393+
show_fdinfo(&iter_link->aux, seq);
394+
}
395+
396+
static int bpf_iter_link_fill_link_info(const struct bpf_link *link,
397+
struct bpf_link_info *info)
398+
{
399+
struct bpf_iter_link *iter_link =
400+
container_of(link, struct bpf_iter_link, link);
401+
char __user *ubuf = u64_to_user_ptr(info->iter.target_name);
402+
bpf_iter_fill_link_info_t fill_link_info;
403+
u32 ulen = info->iter.target_name_len;
404+
const char *target_name;
405+
u32 target_len;
406+
407+
if (!ulen ^ !ubuf)
408+
return -EINVAL;
409+
410+
target_name = iter_link->tinfo->reg_info->target;
411+
target_len = strlen(target_name);
412+
info->iter.target_name_len = target_len + 1;
413+
414+
if (ubuf) {
415+
if (ulen >= target_len + 1) {
416+
if (copy_to_user(ubuf, target_name, target_len + 1))
417+
return -EFAULT;
418+
} else {
419+
char zero = '\0';
420+
421+
if (copy_to_user(ubuf, target_name, ulen - 1))
422+
return -EFAULT;
423+
if (put_user(zero, ubuf + ulen - 1))
424+
return -EFAULT;
425+
return -ENOSPC;
426+
}
427+
}
428+
429+
fill_link_info = iter_link->tinfo->reg_info->fill_link_info;
430+
if (fill_link_info)
431+
return fill_link_info(&iter_link->aux, info);
432+
433+
return 0;
434+
}
435+
380436
static const struct bpf_link_ops bpf_iter_link_lops = {
381437
.release = bpf_iter_link_release,
382438
.dealloc = bpf_iter_link_dealloc,
383439
.update_prog = bpf_iter_link_replace,
440+
.show_fdinfo = bpf_iter_link_show_fdinfo,
441+
.fill_link_info = bpf_iter_link_fill_link_info,
384442
};
385443

386444
bool bpf_link_is_iter(struct bpf_link *link)

tools/include/uapi/linux/bpf.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4071,6 +4071,13 @@ struct bpf_link_info {
40714071
__u64 cgroup_id;
40724072
__u32 attach_type;
40734073
} cgroup;
4074+
struct {
4075+
__aligned_u64 target_name; /* in/out: target_name buffer ptr */
4076+
__u32 target_name_len; /* in/out: target_name buffer len */
4077+
union {
4078+
__u32 map_id;
4079+
} map;
4080+
} iter;
40744081
struct {
40754082
__u32 netns_ino;
40764083
__u32 attach_type;

0 commit comments

Comments
 (0)