bpftool: cgroup bpf operations
Subsystems (5)
v4 cover bpftool: cgroup bpf operations
This patchset adds basic cgroup bpf operations to bpftool.
Right now there is no convenient way to perform these operations. The /samples/bpf/load_sock_ops.c implements attach/detacg operations, but only for BPF_CGROUP_SOCK_OPS programs. Bps (part of bcc) implements bpf introspection, but lacks any cgroup-related specific.
I find having a tool to perform these basic operations in the kernel tree very useful, as it can be used in the corresponding bpf documentation without creating additional dependencies. And bpftool seems to be a right tool to extend with such functionality.
v4:
- ATTACH_FLAGS and ATTACH_TYPE are listed and described in docs and usage
- ATTACH_FLAG names converted to "multi" and "override"
- do_attach() recognizes ATTACH_FLAG abbreviations, e.g "mul"
- Local variables sorted ("reverse Christmas tree")
- unknown attach flags value will be never truncated
v3:
- SRC replaced with OBJ in prog load docs
- Output unknown attach type in hex
- License header in SPDX format
- Minor style fixes (e.g. variable reordering)
v2:
- Added prog load operations
- All cgroup operations are looking like bpftool cgroup <command>
- All cgroup-related stuff is moved to a separate file
- Added support for attach flags
- Added support for attaching/detaching programs by id, pinned name, etc
- Changed cgroup detach arguments order
- Added empty json output for succesful programs
- Style fixed: includes order, strncmp and macroses, error handling
- Added man pages
v1:
https://lwn.net/Articles/740366/
Roman Gushchin (4):
libbpf: add ability to guess program type based on section name
libbpf: prefer global symbols as bpf program name source
bpftool: implement prog load command
bpftool: implement cgroup bpf operations
tools/bpf/bpftool/Documentation/bpftool-cgroup.rst | 118 ++++++++ tools/bpf/bpftool/Documentation/bpftool-map.rst | 2 +- tools/bpf/bpftool/Documentation/bpftool-prog.rst | 12 +- tools/bpf/bpftool/Documentation/bpftool.rst | 8 +- tools/bpf/bpftool/cgroup.c | 307 +++++++++++++++++++++ tools/bpf/bpftool/common.c | 71 ++--- tools/bpf/bpftool/main.c | 3 +- tools/bpf/bpftool/main.h | 2 + tools/bpf/bpftool/prog.c | 29 +- tools/lib/bpf/libbpf.c | 53 ++++ 10 files changed, 566 insertions(+), 39 deletions(-) create mode 100644 tools/bpf/bpftool/Documentation/bpftool-cgroup.rst create mode 100644 tools/bpf/bpftool/cgroup.c
Signature · 1 line
2.14.3
PATCH v4 1/4 libbpf: add ability to guess program type based on section name
The bpf_prog_load() function will guess program type if it's not specified explicitly. This functionality will be used to implement loading of different programs without asking a user to specify the program type. In first order it will be used by bpftool.
--- tools/lib/bpf/libbpf.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)
tools/lib/bpf/libbpf.c +51 -0
@@ -1721,6 +1721,45 @@ BPF_PROG_TYPE_FNS(tracepoint, BPF_PROG_TYPE_TRACEPOINT);BPF_PROG_TYPE_FNS (xdp,BPF_PROG_TYPE_XDP );BPF_PROG_TYPE_FNS (perf_event,BPF_PROG_TYPE_PERF_EVENT ); +#define BPF_PROG_SEC (string, type) { string, sizeof(string), type } +static const struct { +const char *sec; +size_t len; +enum bpf_prog_type prog_type; +} section_names[] = { +BPF_PROG_SEC ("socket" ,BPF_PROG_TYPE_SOCKET_FILTER ), +BPF_PROG_SEC ("kprobe/" ,BPF_PROG_TYPE_KPROBE ), +BPF_PROG_SEC ("kretprobe/" ,BPF_PROG_TYPE_KPROBE ), +BPF_PROG_SEC ("tracepoint/" ,BPF_PROG_TYPE_TRACEPOINT ), +BPF_PROG_SEC ("xdp" ,BPF_PROG_TYPE_XDP ), +BPF_PROG_SEC ("perf_event" ,BPF_PROG_TYPE_PERF_EVENT ), +BPF_PROG_SEC ("cgroup/skb" ,BPF_PROG_TYPE_CGROUP_SKB ), +BPF_PROG_SEC ("cgroup/sock" ,BPF_PROG_TYPE_CGROUP_SOCK ), +BPF_PROG_SEC ("cgroup/dev" ,BPF_PROG_TYPE_CGROUP_DEVICE ), +BPF_PROG_SEC ("sockops" ,BPF_PROG_TYPE_SOCK_OPS ), +BPF_PROG_SEC ("sk_skb" ,BPF_PROG_TYPE_SK_SKB ), +}; +#undef BPF_PROG_SEC + +static enum bpf_prog_type bpf_program__guess_type (struct bpf_program *prog) +{ +int i; + +if (!prog->section_name) + goto err; + +for (i =0 ; i <ARRAY_SIZE (section_names); i++) +if (strncmp (prog->section_name, section_names[i].sec, + section_names[i].len) ==0 ) +return section_names[i].prog_type; + +err: +pr_warning ("failed to guess program type based on section name %s\n" , + prog->section_name); + +return BPF_PROG_TYPE_UNSPEC ; +} +int bpf_map__fd (struct bpf_map *map) {return map ? map->fd : -EINVAL ;
@@ -1832,6 +1871,18 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type,return -ENOENT ; } +/* +* If type is not specified, try to guess it based on +* section name. +*/ +if (type ==BPF_PROG_TYPE_UNSPEC ) { + type =bpf_program__guess_type (prog); +if (type ==BPF_PROG_TYPE_UNSPEC ) { +bpf_object__close (obj); +return -EINVAL ; + } + } +bpf_program__set_type (prog, type); err =bpf_object__load (obj);if (err) {
Signature · 1 line
2.14.3
PATCH v4 2/4 libbpf: prefer global symbols as bpf program name source
In reply to Roman GushchinLibbpf picks the name of the first symbol in the corresponding elf section to use as a program name. But without taking symbol's scope into account it may end's up with some local label as a program name. E.g.:
$ bpftool prog 1: type 15 name LBB0_10 tag 0390a5136ba23f5c loaded_at Dec 07/17:22 uid 0 xlated 456B not jited memlock 4096B
Fix this by preferring global symbols as program name.
For instance:
$ bpftool prog 1: type 15 name bpf_prog1 tag 0390a5136ba23f5c loaded_at Dec 07/17:26 uid 0 xlated 456B not jited memlock 4096B
--- tools/lib/bpf/libbpf.c | 2 ++ 1 file changed, 2 insertions(+)
tools/lib/bpf/libbpf.c +2 -0
@@ -387,6 +387,8 @@ bpf_object__init_prog_names(struct bpf_object *obj)continue ;if (sym.st_shndx != prog->idx)continue ; +if (GELF_ST_BIND (sym.st_info) !=STB_GLOBAL ) +continue ; name = elf_strptr(obj->efile.elf, obj->efile.strtabidx,
Signature · 1 line
2.14.3
PATCH v4 3/4 bpftool: implement prog load command
In reply to Roman GushchinAdd the prog load command to load a bpf program from a specified binary file and pin it to bpffs.
Usage description and examples are given in the corresponding man page.
Syntax:
$ bpftool prog load OBJ FILE
FILE is a non-existing file on bpffs.
--- tools/bpf/bpftool/Documentation/bpftool-prog.rst | 10 +++- tools/bpf/bpftool/Documentation/bpftool.rst | 2 +- tools/bpf/bpftool/common.c | 71 +++++++++++++----------- tools/bpf/bpftool/main.h | 1 + tools/bpf/bpftool/prog.c | 29 +++++++++- 5 files changed, 79 insertions(+), 34 deletions(-)
tools/bpf/bpftool/Documentation/bpftool-prog.rst +9 -1
@@ -15,7 +15,7 @@ SYNOPSIS *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } *COMMANDS* := - { **show** | **dump xlated** | **dump jited** | **pin** | **help** } + { **show** | **dump xlated** | **dump jited** | **pin** | **load** | **help** } MAP COMMANDS =============
@@ -24,6 +24,7 @@ MAP COMMANDS | **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes**}] | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] | **bpftool** **prog pin** *PROG* *FILE* +| **bpftool** **prog load** *OBJ* *FILE* | **bpftool** **prog help** | | *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
@@ -57,6 +58,11 @@ DESCRIPTION Note: *FILE* must be located in *bpffs* mount. + **bpftool prog load** *OBJ* *FILE* + Load bpf program from binary *OBJ* and pin as *FILE*. + + Note: *FILE* must be located in *bpffs* mount. + **bpftool prog help** Print short help message.
@@ -126,8 +132,10 @@ EXAMPLES | | **# mount -t bpf none /sys/fs/bpf/** | **# bpftool prog pin id 10 /sys/fs/bpf/prog** +| **# bpftool prog load ./my_prog.o /sys/fs/bpf/prog2** | **# ls -l /sys/fs/bpf/** | -rw------- 1 root root 0 Jul 22 01:43 prog +| -rw------- 1 root root 0 Jul 22 01:44 prog2 **# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes**
tools/bpf/bpftool/Documentation/bpftool.rst +1 -1
@@ -26,7 +26,7 @@ SYNOPSIS | **pin** | **help** } *PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin** - | **help** } + | **load** | **help** } DESCRIPTION ===========
tools/bpf/bpftool/common.c +40 -31
88 lines not on this page · raw message
tools/bpf/bpftool/main.h +1 -0
@@ -111,6 +111,7 @@ char *get_fdinfo(int fd, const char *key);int open_obj_pinned (char *path);int open_obj_pinned_any (char *path,enum bpf_obj_type exp_type);int do_pin_any (int argc,char **argv,int (*get_fd_by_id)(__u32 )); +int do_pin_fd (int fd,const char *name);int do_prog (int argc,char **arg);int do_map (int argc,char **arg);
tools/bpf/bpftool/prog.c +28 -1
@@ -45,6 +45,7 @@#include <sys/stat.h> #include <bpf.h> +#include <libbpf.h> #include "main.h" #include "disasm.h"
@@ -635,6 +636,30 @@ static int do_pin(int argc, char **argv)return err; } +static int do_load (int argc,char **argv) +{ +struct bpf_object *obj; +int prog_fd; + +if (argc !=2 ) +usage (); + +if (bpf_prog_load (argv[0 ],BPF_PROG_TYPE_UNSPEC , &obj, &prog_fd)) { +p_err ("failed to load program\n" ); +return -1 ; + } + +if (do_pin_fd (prog_fd, argv[1 ])) { +p_err ("failed to pin program\n" ); +return -1 ; + } + +if (json_output) +jsonw_null (json_wtr); + +return 0 ; +} +static int do_help (int argc,char **argv) {if (json_output) {
@@ -647,13 +672,14 @@ static int do_help(int argc, char **argv)" %s %s dump xlated PROG [{ file FILE | opcodes }]\n" " %s %s dump jited PROG [{ file FILE | opcodes }]\n" " %s %s pin PROG FILE\n" +" %s %s load OBJ FILE\n" " %s %s help\n" "\n" " " HELP_SPEC_PROGRAM "\n" " " HELP_SPEC_OPTIONS "\n" "" , bin_name, argv[-2 ], bin_name, argv[-2 ], bin_name, argv[-2 ], - bin_name, argv[-2], bin_name, argv[-2]); + bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]);return 0 ; }
@@ -663,6 +689,7 @@ static const struct cmd cmds[] = { { "help", do_help }, { "dump", do_dump }, { "pin", do_pin }, + { "load", do_load }, { 0 } };
Signature · 1 line
2.14.3
PATCH v4 4/4 bpftool: implement cgroup bpf operations
In reply to Roman GushchinThis patch adds basic cgroup bpf operations to bpftool:
cgroup list, attach and detach commands.
Usage is described in the corresponding man pages, and examples are provided.
Syntax:
$ bpftool cgroup list CGROUP $ bpftool cgroup attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS] $ bpftool cgroup detach CGROUP ATTACH_TYPE PROG
--- tools/bpf/bpftool/Documentation/bpftool-cgroup.rst | 118 ++++++++ tools/bpf/bpftool/Documentation/bpftool-map.rst | 2 +- tools/bpf/bpftool/Documentation/bpftool-prog.rst | 2 +- tools/bpf/bpftool/Documentation/bpftool.rst | 6 +- tools/bpf/bpftool/cgroup.c | 307 +++++++++++++++++++++ tools/bpf/bpftool/main.c | 3 +- tools/bpf/bpftool/main.h | 1 + 7 files changed, 434 insertions(+), 5 deletions(-) create mode 100644 tools/bpf/bpftool/Documentation/bpftool-cgroup.rst create mode 100644 tools/bpf/bpftool/cgroup.c
tools/bpf/bpftool/Documentation/bpftool-cgroup.rst new file +118 -0
@@ -0,0 +1,118 @@ +================ +bpftool-cgroup +================ +------------------------------------------------------------------------------- +tool for inspection and simple manipulation of eBPF progs +------------------------------------------------------------------------------- + +:Manual section: 8 + +SYNOPSIS +======== + + **bpftool** [*OPTIONS*] **cgroup** *COMMAND* + + *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } + + *COMMANDS* := + { **list** | **attach** | **detach** | **help** } + +MAP COMMANDS +============= + +| **bpftool** **cgroup list** *CGROUP* +| **bpftool** **cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] +| **bpftool** **cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG* +| **bpftool** **cgroup help** +| +| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } +| *ATTACH_TYPE* := { *ingress* | *egress* | *sock_create* | *sock_ops* | *device* } +| *ATTACH_FLAGS* := { *multi* | *override* } + +DESCRIPTION +=========== + **bpftool cgroup list** *CGROUP* + List all programs attached to the cgroup *CGROUP*. + + Output will start with program ID followed by attach type, + attach flags and program name. + + **bpftool cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] + Attach program *PROG* to the cgroup *CGROUP* with attach type + *ATTACH_TYPE* and optional *ATTACH_FLAGS*. + + *ATTACH_FLAGS* can be one of: **override** if a sub-cgroup installs + some bpf program, the program in this cgroup yields to sub-cgroup + program; **multi** if a sub-cgroup installs some bpf program, + that cgroup program gets run in addition to the program in this + cgroup. + + Only one program is allowed to be attached to a cgroup with + no attach flags or the **override** flag. Attaching another + program will release old program and attach the new one. + + Multiple programs are allowed to be attached to a cgroup with + **multi**. They are executed in FIFO order (those that were + attached first, run first). + + Non-default *ATTACH_FLAGS* are supported by kernel version 4.14 + and later. + + *ATTACH_TYPE* can be on of: + **ingress** ingress path of the inet socket (since 4.10); + **egress** egress path of the inet socket (since 4.10); + **sock_create** opening of an inet socket (since 4.10); + **sock_ops** various socket operations (since 4.12); + **device** device access (since 4.15). + + **bpftool cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG* + Detach *PROG* from the cgroup *CGROUP* and attach type + *ATTACH_TYPE*. + + **bpftool prog help** + Print short help message. + +OPTIONS +======= + -h, --help + Print short generic help message (similar to **bpftool help**). + + -v, --version + Print version number (similar to **bpftool version**). + + -j, --json + Generate JSON output. For commands that cannot produce JSON, this + option has no effect. + + -p, --pretty + Generate human-readable JSON output. Implies **-j**. + + -f, --bpffs + Show file names of pinned programs. + +EXAMPLES +======== +| +| **# mount -t bpf none /sys/fs/bpf/** +| **# mkdir /sys/fs/cgroup/test.slice** +| **# bpftool prog load ./device_cgroup.o /sys/fs/bpf/prog** +| **# bpftool cgroup attach /sys/fs/cgroup/test.slice/ device id 1 allow_multi** + +**# bpftool cgroup list /sys/fs/cgroup/test.slice/** + +:: + + ID AttachType AttachFlags Name + 1 device allow_multi bpf_prog1 + +| +| **# bpftool cgroup detach /sys/fs/cgroup/test.slice/ device id 1** +| **# bpftool cgroup list /sys/fs/cgroup/test.slice/** + +:: + + ID AttachType AttachFlags Name + +SEE ALSO +======== + **bpftool**\ (8), **bpftool-prog**\ (8), **bpftool-map**\ (8)
tools/bpf/bpftool/Documentation/bpftool-map.rst +1 -1
@@ -128,4 +128,4 @@ EXAMPLES SEE ALSO ======== - **bpftool**\ (8), **bpftool-prog**\ (8) + **bpftool**\ (8), **bpftool-prog**\ (8), **bpftool-cgroup**\ (8)
tools/bpf/bpftool/Documentation/bpftool-prog.rst +1 -1
@@ -155,4 +155,4 @@ EXAMPLES SEE ALSO ======== - **bpftool**\ (8), **bpftool-map**\ (8) + **bpftool**\ (8), **bpftool-map**\ (8), **bpftool-cgroup**\ (8)
tools/bpf/bpftool/Documentation/bpftool.rst +4 -2
@@ -16,7 +16,7 @@ SYNOPSIS **bpftool** **version** - *OBJECT* := { **map** | **program** } + *OBJECT* := { **map** | **program** | **cgroup** } *OPTIONS* := { { **-V** | **--version** } | { **-h** | **--help** } | { **-j** | **--json** } [{ **-p** | **--pretty** }] }
@@ -28,6 +28,8 @@ SYNOPSIS *PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin** | **load** | **help** } + *CGROUP-COMMANDS* := { **list** | **attach** | **detach** | **help** } + DESCRIPTION =========== *bpftool* allows for inspection and simple modification of BPF objects
@@ -53,4 +55,4 @@ OPTIONS SEE ALSO ======== - **bpftool-map**\ (8), **bpftool-prog**\ (8) + **bpftool-map**\ (8), **bpftool-prog**\ (8), **bpftool-cgroup**\ (8)
tools/bpf/bpftool/cgroup.c new file +307 -0
307 lines not on this page · raw message
tools/bpf/bpftool/main.c +2 -1
@@ -85,7 +85,7 @@ static int do_help(int argc, char **argv)" %s batch file FILE\n" " %s version\n" "\n" -" OBJECT := { prog | map }\n" +" OBJECT := { prog | map | cgroup }\n" " " HELP_SPEC_OPTIONS "\n" "" , bin_name, bin_name, bin_name);
@@ -173,6 +173,7 @@ static const struct cmd cmds[] = { { "batch", do_batch }, { "prog", do_prog }, { "map", do_map }, + { "cgroup", do_cgroup }, { "version", do_version }, { 0 } };
tools/bpf/bpftool/main.h +1 -0
@@ -115,6 +115,7 @@ int do_pin_fd(int fd, const char *name);int do_prog (int argc,char **arg);int do_map (int argc,char **arg); +int do_cgroup (int argc,char **arg);int prog_parse_fd (int *argc,char ***argv);
Signature · 1 line
2.14.3
Re: [PATCH v4 net-next 4/4] bpftool: implement cgroup bpf operations
Quoted 11 lines · Roman Gushchin
This patch adds basic cgroup bpf operations to bpftool:
cgroup list, attach and detach commands.Usage is described in the corresponding man pages, and examples are provided.
Syntax:
$ bpftool cgroup list CGROUP $ bpftool cgroup attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS] $ bpftool cgroup detach CGROUP ATTACH_TYPE PROG
Quoted 8 lines
Signed-off-by Roman Gushchin <[email protected]>Cc Alexei Starovoitov <[email protected]>Cc Daniel Borkmann <[email protected]>Cc Jakub Kicinski <[email protected]>Cc Martin KaFai Lau <[email protected]>Cc Quentin Monnet <[email protected]>Reviewed-by David Ahern <[email protected]>---
The updates for attach flags and man page look great. Very user friendly. Thanks for the work on it.
Re: [PATCH v4 net-next 4/4] bpftool: implement cgroup bpf operations
In reply to Roman GushchinQuoted 11 lines · Roman Gushchin
This patch adds basic cgroup bpf operations to bpftool:
cgroup list, attach and detach commands.Usage is described in the corresponding man pages, and examples are provided.
Syntax:
$ bpftool cgroup list CGROUP $ bpftool cgroup attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS] $ bpftool cgroup detach CGROUP ATTACH_TYPE PROG
Quoted 7 lines
Signed-off-by Roman Gushchin <[email protected]>Cc Alexei Starovoitov <[email protected]>Cc Daniel Borkmann <[email protected]>Cc Jakub Kicinski <[email protected]>Cc Martin KaFai Lau <[email protected]>Cc Quentin Monnet <[email protected]>Reviewed-by David Ahern <[email protected]>
Excellent, thank you!
2017-12-13 15:18 UTC+0000 ~ Roman Gushchin <[email protected]>
Quoted 11 lines
This patchset adds basic cgroup bpf operations to bpftool.
Right now there is no convenient way to perform these operations. The /samples/bpf/load_sock_ops.c implements attach/detacg operations, but only for
BPF_CGROUP_SOCK_OPSprograms. Bps (part of bcc) implements bpf introspection, but lacks any cgroup-related specific.I find having a tool to perform these basic operations in the kernel tree very useful, as it can be used in the corresponding bpf documentation without creating additional dependencies. And bpftool seems to be a right tool to extend with such functionality.
Thank you Roman for this series, and for documenting the new commands and flags!
Daniel Borkmann
maintainerQuoted 12 lines · Roman Gushchin
This patchset adds basic cgroup bpf operations to bpftool.
Right now there is no convenient way to perform these operations. The /samples/bpf/load_sock_ops.c implements attach/detacg operations, but only for
BPF_CGROUP_SOCK_OPSprograms. Bps (part of bcc) implements bpf introspection, but lacks any cgroup-related specific.I find having a tool to perform these basic operations in the kernel tree very useful, as it can be used in the corresponding bpf documentation without creating additional dependencies. And bpftool seems to be a right tool to extend with such functionality.
Quoted 6 lines
v4:
-ATTACH_FLAGSandATTACH_TYPEare listed and described in docs and usage
-ATTACH_FLAGnames converted to "multi" and "override"
-do_attach()recognizesATTACH_FLAGabbreviations, e.g "mul"
- Local variables sorted ("reverse Christmas tree")
- unknown attach flags value will be never truncated
Series applied to bpf-next, thanks everyone!