Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools/bpftool: Add bpftool support for bpf map element iterator

The optional parameter "map MAP" can be added to "bpftool iter"
command to create a bpf iterator for map elements. For example,
bpftool iter pin ./prog.o /sys/fs/bpf/p1 map id 333

For map element bpf iterator "map MAP" parameter is required.
Otherwise, bpf link creation will return an error.

Quentin Monnet kindly provided bash-completion implementation
for new "map MAP" option.

Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200723184119.590799-1-yhs@fb.com

authored by

Yonghong Song and committed by
Alexei Starovoitov
d8793aca cd31039a

+62 -7
+16 -2
tools/bpf/bpftool/Documentation/bpftool-iter.rst
··· 17 17 ITER COMMANDS 18 18 =================== 19 19 20 - | **bpftool** **iter pin** *OBJ* *PATH* 20 + | **bpftool** **iter pin** *OBJ* *PATH* [**map** *MAP*] 21 21 | **bpftool** **iter help** 22 22 | 23 23 | *OBJ* := /a/file/of/bpf_iter_target.o 24 + | *MAP* := { **id** *MAP_ID* | **pinned** *FILE* } 24 25 25 26 DESCRIPTION 26 27 =========== 27 - **bpftool iter pin** *OBJ* *PATH* 28 + **bpftool iter pin** *OBJ* *PATH* [**map** *MAP*] 28 29 A bpf iterator combines a kernel iterating of 29 30 particular kernel data (e.g., tasks, bpf_maps, etc.) 30 31 and a bpf program called for each kernel data object ··· 37 36 in *bpffs* mount. It must not contain a dot 38 37 character ('.'), which is reserved for future extensions 39 38 of *bpffs*. 39 + 40 + Map element bpf iterator requires an additional parameter 41 + *MAP* so bpf program can iterate over map elements for 42 + that map. User can have a bpf program in kernel to run 43 + with each map element, do checking, filtering, aggregation, 44 + etc. without copying data to user space. 40 45 41 46 User can then *cat PATH* to see the bpf iterator output. 42 47 ··· 70 63 71 64 Create a file-based bpf iterator from bpf_iter_netlink.o and pin it 72 65 to /sys/fs/bpf/my_netlink 66 + 67 + **# bpftool iter pin bpf_iter_hashmap.o /sys/fs/bpf/my_hashmap map id 20** 68 + 69 + :: 70 + 71 + Create a file-based bpf iterator from bpf_iter_hashmap.o and map with 72 + id 20, and pin it to /sys/fs/bpf/my_hashmap 73 73 74 74 SEE ALSO 75 75 ========
+17 -1
tools/bpf/bpftool/bash-completion/bpftool
··· 615 615 iter) 616 616 case $command in 617 617 pin) 618 - _filedir 618 + case $prev in 619 + $command) 620 + _filedir 621 + ;; 622 + id) 623 + _bpftool_get_map_ids 624 + ;; 625 + name) 626 + _bpftool_get_map_names 627 + ;; 628 + pinned) 629 + _filedir 630 + ;; 631 + *) 632 + _bpftool_one_of_list $MAP_TYPE 633 + ;; 634 + esac 619 635 return 0 620 636 ;; 621 637 *)
+29 -4
tools/bpf/bpftool/iter.c
··· 2 2 // Copyright (C) 2020 Facebook 3 3 4 4 #define _GNU_SOURCE 5 + #include <unistd.h> 5 6 #include <linux/err.h> 6 7 #include <bpf/libbpf.h> 7 8 ··· 10 9 11 10 static int do_pin(int argc, char **argv) 12 11 { 12 + DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, iter_opts); 13 13 const char *objfile, *path; 14 14 struct bpf_program *prog; 15 15 struct bpf_object *obj; 16 16 struct bpf_link *link; 17 - int err; 17 + int err = -1, map_fd = -1; 18 18 19 19 if (!REQ_ARGS(2)) 20 20 usage(); ··· 23 21 objfile = GET_ARG(); 24 22 path = GET_ARG(); 25 23 24 + /* optional arguments */ 25 + if (argc) { 26 + if (is_prefix(*argv, "map")) { 27 + NEXT_ARG(); 28 + 29 + if (!REQ_ARGS(2)) { 30 + p_err("incorrect map spec"); 31 + return -1; 32 + } 33 + 34 + map_fd = map_parse_fd(&argc, &argv); 35 + if (map_fd < 0) 36 + return -1; 37 + } 38 + } 39 + 26 40 obj = bpf_object__open(objfile); 27 41 if (IS_ERR(obj)) { 28 42 p_err("can't open objfile %s", objfile); 29 - return -1; 43 + goto close_map_fd; 30 44 } 31 45 32 46 err = bpf_object__load(obj); ··· 57 39 goto close_obj; 58 40 } 59 41 60 - link = bpf_program__attach_iter(prog, NULL); 42 + if (map_fd >= 0) 43 + iter_opts.map_fd = map_fd; 44 + 45 + link = bpf_program__attach_iter(prog, &iter_opts); 61 46 if (IS_ERR(link)) { 62 47 err = PTR_ERR(link); 63 48 p_err("attach_iter failed for program %s", ··· 83 62 bpf_link__destroy(link); 84 63 close_obj: 85 64 bpf_object__close(obj); 65 + close_map_fd: 66 + if (map_fd >= 0) 67 + close(map_fd); 86 68 return err; 87 69 } 88 70 89 71 static int do_help(int argc, char **argv) 90 72 { 91 73 fprintf(stderr, 92 - "Usage: %1$s %2$s pin OBJ PATH\n" 74 + "Usage: %1$s %2$s pin OBJ PATH [map MAP]\n" 93 75 " %1$s %2$s help\n" 76 + " " HELP_SPEC_MAP "\n" 94 77 "", 95 78 bin_name, "iter"); 96 79