summaryrefslogtreecommitdiff
path: root/tools/bpf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/bpf')
-rw-r--r--tools/bpf/bpf_jit_disasm.c2
-rw-r--r--tools/bpf/bpftool/Documentation/Makefile6
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-btf.rst111
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-cgroup.rst219
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-feature.rst115
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-gen.rst338
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-iter.rst60
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-link.rst73
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-map.rst232
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-net.rst134
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-perf.rst34
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-prog.rst436
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-struct_ops.rst81
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool.rst60
-rw-r--r--tools/bpf/bpftool/Documentation/common_options.rst26
-rw-r--r--tools/bpf/bpftool/Makefile30
-rw-r--r--tools/bpf/bpftool/bash-completion/bpftool71
-rw-r--r--tools/bpf/bpftool/btf.c395
-rw-r--r--tools/bpf/bpftool/cfg.c1
-rw-r--r--tools/bpf/bpftool/cgroup.c40
-rw-r--r--tools/bpf/bpftool/common.c98
-rw-r--r--tools/bpf/bpftool/feature.c36
-rw-r--r--tools/bpf/bpftool/gen.c99
-rw-r--r--tools/bpf/bpftool/iter.c2
-rw-r--r--tools/bpf/bpftool/jit_disasm.c40
-rw-r--r--tools/bpf/bpftool/link.c9
-rw-r--r--tools/bpf/bpftool/main.h3
-rw-r--r--tools/bpf/bpftool/net.c80
-rw-r--r--tools/bpf/bpftool/pids.c21
-rw-r--r--tools/bpf/bpftool/prog.c30
-rw-r--r--tools/bpf/bpftool/skeleton/pid_iter.bpf.c11
-rw-r--r--tools/bpf/bpftool/skeleton/profiler.bpf.c14
-rw-r--r--tools/bpf/bpftool/struct_ops.c2
-rw-r--r--tools/bpf/bpftool/xlated_dumper.c4
-rw-r--r--tools/bpf/resolve_btfids/main.c28
-rw-r--r--tools/bpf/runqslower/Makefile3
-rw-r--r--tools/bpf/runqslower/runqslower.bpf.c1
37 files changed, 1788 insertions, 1157 deletions
diff --git a/tools/bpf/bpf_jit_disasm.c b/tools/bpf/bpf_jit_disasm.c
index a90a5d110f92..1baee9e2aba9 100644
--- a/tools/bpf/bpf_jit_disasm.c
+++ b/tools/bpf/bpf_jit_disasm.c
@@ -210,7 +210,7 @@ static uint8_t *get_last_jit_image(char *haystack, size_t hlen,
return NULL;
}
if (proglen > 1000000) {
- printf("proglen of %d too big, stopping\n", proglen);
+ printf("proglen of %u too big, stopping\n", proglen);
return NULL;
}
diff --git a/tools/bpf/bpftool/Documentation/Makefile b/tools/bpf/bpftool/Documentation/Makefile
index ac8487dcff1d..4315652678b9 100644
--- a/tools/bpf/bpftool/Documentation/Makefile
+++ b/tools/bpf/bpftool/Documentation/Makefile
@@ -31,9 +31,9 @@ see_also = $(subst " ",, \
"\n" \
"SEE ALSO\n" \
"========\n" \
- "\t**bpf**\ (2),\n" \
- "\t**bpf-helpers**\\ (7)" \
- $(foreach page,$(call list_pages,$(1)),",\n\t**$(page)**\\ (8)") \
+ "**bpf**\ (2),\n" \
+ "**bpf-helpers**\\ (7)" \
+ $(foreach page,$(call list_pages,$(1)),",\n**$(page)**\\ (8)") \
"\n")
$(OUTPUT)%.8: %.rst
diff --git a/tools/bpf/bpftool/Documentation/bpftool-btf.rst b/tools/bpf/bpftool/Documentation/bpftool-btf.rst
index 342716f74ec4..d47dddc2b4ee 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-btf.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-btf.rst
@@ -14,82 +14,83 @@ tool for inspection of BTF data
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **btf** *COMMAND*
+**bpftool** [*OPTIONS*] **btf** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| | { **-B** | **--base-btf** } }
+*OPTIONS* := { |COMMON_OPTIONS| | { **-B** | **--base-btf** } }
- *COMMANDS* := { **dump** | **help** }
+*COMMANDS* := { **dump** | **help** }
BTF COMMANDS
=============
-| **bpftool** **btf** { **show** | **list** } [**id** *BTF_ID*]
-| **bpftool** **btf dump** *BTF_SRC* [**format** *FORMAT*]
-| **bpftool** **btf help**
+| **bpftool** **btf** { **show** | **list** } [**id** *BTF_ID*]
+| **bpftool** **btf dump** *BTF_SRC* [**format** *FORMAT*] [**root_id** *ROOT_ID*]
+| **bpftool** **btf help**
|
-| *BTF_SRC* := { **id** *BTF_ID* | **prog** *PROG* | **map** *MAP* [{**key** | **value** | **kv** | **all**}] | **file** *FILE* }
-| *FORMAT* := { **raw** | **c** }
-| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
-| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
+| *BTF_SRC* := { **id** *BTF_ID* | **prog** *PROG* | **map** *MAP* [{**key** | **value** | **kv** | **all**}] | **file** *FILE* }
+| *FORMAT* := { **raw** | **c** [**unsorted**] }
+| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
+| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* }
DESCRIPTION
===========
- **bpftool btf { show | list }** [**id** *BTF_ID*]
- Show information about loaded BTF objects. If a BTF ID is
- specified, show information only about given BTF object,
- otherwise list all BTF objects currently loaded on the
- system.
+bpftool btf { show | list } [id *BTF_ID*]
+ Show information about loaded BTF objects. If a BTF ID is specified, show
+ information only about given BTF object, otherwise list all BTF objects
+ currently loaded on the system.
- Since Linux 5.8 bpftool is able to discover information about
- processes that hold open file descriptors (FDs) against BTF
- objects. On such kernels bpftool will automatically emit this
- information as well.
+ Since Linux 5.8 bpftool is able to discover information about processes
+ that hold open file descriptors (FDs) against BTF objects. On such kernels
+ bpftool will automatically emit this information as well.
- **bpftool btf dump** *BTF_SRC*
- Dump BTF entries from a given *BTF_SRC*.
+bpftool btf dump *BTF_SRC* [format *FORMAT*] [root_id *ROOT_ID*]
+ Dump BTF entries from a given *BTF_SRC*.
- When **id** is specified, BTF object with that ID will be
- loaded and all its BTF types emitted.
+ When **id** is specified, BTF object with that ID will be loaded and all
+ its BTF types emitted.
- When **map** is provided, it's expected that map has
- associated BTF object with BTF types describing key and
- value. It's possible to select whether to dump only BTF
- type(s) associated with key (**key**), value (**value**),
- both key and value (**kv**), or all BTF types present in
- associated BTF object (**all**). If not specified, **kv**
- is assumed.
+ When **map** is provided, it's expected that map has associated BTF object
+ with BTF types describing key and value. It's possible to select whether to
+ dump only BTF type(s) associated with key (**key**), value (**value**),
+ both key and value (**kv**), or all BTF types present in associated BTF
+ object (**all**). If not specified, **kv** is assumed.
- When **prog** is provided, it's expected that program has
- associated BTF object with BTF types.
+ When **prog** is provided, it's expected that program has associated BTF
+ object with BTF types.
- When specifying *FILE*, an ELF file is expected, containing
- .BTF section with well-defined BTF binary format data,
- typically produced by clang or pahole.
+ When specifying *FILE*, an ELF file is expected, containing .BTF section
+ with well-defined BTF binary format data, typically produced by clang or
+ pahole.
- **format** option can be used to override default (raw)
- output format. Raw (**raw**) or C-syntax (**c**) output
- formats are supported.
+ **format** option can be used to override default (raw) output format. Raw
+ (**raw**) or C-syntax (**c**) output formats are supported. With C-style
+ formatting, the output is sorted by default. Use the **unsorted** option
+ to avoid sorting the output.
- **bpftool btf help**
- Print short help message.
+ **root_id** option can be used to filter a dump to a single type and all
+ its dependent types. It cannot be used with any other types of filtering
+ (such as the "key", "value", or "kv" arguments when dumping BTF for a map).
+ It can be passed multiple times to dump multiple types.
+
+bpftool btf help
+ Print short help message.
OPTIONS
=======
- .. include:: common_options.rst
-
- -B, --base-btf *FILE*
- Pass a base BTF object. Base BTF objects are typically used
- with BTF objects for kernel modules. To avoid duplicating
- all kernel symbols required by modules, BTF objects for
- modules are "split", they are built incrementally on top of
- the kernel (vmlinux) BTF object. So the base BTF reference
- should usually point to the kernel BTF.
-
- When the main BTF object to process (for example, the
- module BTF to dump) is passed as a *FILE*, bpftool attempts
- to autodetect the path for the base object, and passing
- this option is optional. When the main BTF object is passed
- through other handles, this option becomes necessary.
+.. include:: common_options.rst
+
+-B, --base-btf *FILE*
+ Pass a base BTF object. Base BTF objects are typically used with BTF
+ objects for kernel modules. To avoid duplicating all kernel symbols
+ required by modules, BTF objects for modules are "split", they are
+ built incrementally on top of the kernel (vmlinux) BTF object. So the
+ base BTF reference should usually point to the kernel BTF.
+
+ When the main BTF object to process (for example, the module BTF to
+ dump) is passed as a *FILE*, bpftool attempts to autodetect the path
+ for the base object, and passing this option is optional. When the main
+ BTF object is passed through other handles, this option becomes
+ necessary.
EXAMPLES
========
diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
index 2ce900f66d6e..e8185596a759 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
@@ -14,134 +14,125 @@ tool for inspection and simple manipulation of eBPF progs
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **cgroup** *COMMAND*
+**bpftool** [*OPTIONS*] **cgroup** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| | { **-f** | **--bpffs** } }
+*OPTIONS* := { |COMMON_OPTIONS| | { **-f** | **--bpffs** } }
- *COMMANDS* :=
- { **show** | **list** | **tree** | **attach** | **detach** | **help** }
+*COMMANDS* :=
+{ **show** | **list** | **tree** | **attach** | **detach** | **help** }
CGROUP COMMANDS
===============
-| **bpftool** **cgroup** { **show** | **list** } *CGROUP* [**effective**]
-| **bpftool** **cgroup tree** [*CGROUP_ROOT*] [**effective**]
-| **bpftool** **cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*]
-| **bpftool** **cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG*
-| **bpftool** **cgroup help**
+| **bpftool** **cgroup** { **show** | **list** } *CGROUP* [**effective**]
+| **bpftool** **cgroup tree** [*CGROUP_ROOT*] [**effective**]
+| **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* := { **cgroup_inet_ingress** | **cgroup_inet_egress** |
-| **cgroup_inet_sock_create** | **cgroup_sock_ops** |
-| **cgroup_device** | **cgroup_inet4_bind** | **cgroup_inet6_bind** |
-| **cgroup_inet4_post_bind** | **cgroup_inet6_post_bind** |
-| **cgroup_inet4_connect** | **cgroup_inet6_connect** |
-| **cgroup_unix_connect** | **cgroup_inet4_getpeername** |
-| **cgroup_inet6_getpeername** | **cgroup_unix_getpeername** |
-| **cgroup_inet4_getsockname** | **cgroup_inet6_getsockname** |
-| **cgroup_unix_getsockname** | **cgroup_udp4_sendmsg** |
-| **cgroup_udp6_sendmsg** | **cgroup_unix_sendmsg** |
-| **cgroup_udp4_recvmsg** | **cgroup_udp6_recvmsg** |
-| **cgroup_unix_recvmsg** | **cgroup_sysctl** |
-| **cgroup_getsockopt** | **cgroup_setsockopt** |
-| **cgroup_inet_sock_release** }
-| *ATTACH_FLAGS* := { **multi** | **override** }
+| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* }
+| *ATTACH_TYPE* := { **cgroup_inet_ingress** | **cgroup_inet_egress** |
+| **cgroup_inet_sock_create** | **cgroup_sock_ops** |
+| **cgroup_device** | **cgroup_inet4_bind** | **cgroup_inet6_bind** |
+| **cgroup_inet4_post_bind** | **cgroup_inet6_post_bind** |
+| **cgroup_inet4_connect** | **cgroup_inet6_connect** |
+| **cgroup_unix_connect** | **cgroup_inet4_getpeername** |
+| **cgroup_inet6_getpeername** | **cgroup_unix_getpeername** |
+| **cgroup_inet4_getsockname** | **cgroup_inet6_getsockname** |
+| **cgroup_unix_getsockname** | **cgroup_udp4_sendmsg** |
+| **cgroup_udp6_sendmsg** | **cgroup_unix_sendmsg** |
+| **cgroup_udp4_recvmsg** | **cgroup_udp6_recvmsg** |
+| **cgroup_unix_recvmsg** | **cgroup_sysctl** |
+| **cgroup_getsockopt** | **cgroup_setsockopt** |
+| **cgroup_inet_sock_release** }
+| *ATTACH_FLAGS* := { **multi** | **override** }
DESCRIPTION
===========
- **bpftool cgroup { show | list }** *CGROUP* [**effective**]
- List all programs attached to the cgroup *CGROUP*.
-
- Output will start with program ID followed by attach type,
- attach flags and program name.
-
- If **effective** is specified retrieve effective programs that
- will execute for events within a cgroup. This includes
- inherited along with attached ones.
-
- **bpftool cgroup tree** [*CGROUP_ROOT*] [**effective**]
- Iterate over all cgroups in *CGROUP_ROOT* and list all
- attached programs. If *CGROUP_ROOT* is not specified,
- bpftool uses cgroup v2 mountpoint.
-
- The output is similar to the output of cgroup show/list
- commands: it starts with absolute cgroup path, followed by
- program ID, attach type, attach flags and program name.
-
- If **effective** is specified retrieve effective programs that
- will execute for events within a cgroup. This includes
- inherited along with attached ones.
-
- **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);
- **bind4** call to bind(2) for an inet4 socket (since 4.17);
- **bind6** call to bind(2) for an inet6 socket (since 4.17);
- **post_bind4** return from bind(2) for an inet4 socket (since 4.17);
- **post_bind6** return from bind(2) for an inet6 socket (since 4.17);
- **connect4** call to connect(2) for an inet4 socket (since 4.17);
- **connect6** call to connect(2) for an inet6 socket (since 4.17);
- **connect_unix** call to connect(2) for a unix socket (since 6.7);
- **sendmsg4** call to sendto(2), sendmsg(2), sendmmsg(2) for an
- unconnected udp4 socket (since 4.18);
- **sendmsg6** call to sendto(2), sendmsg(2), sendmmsg(2) for an
- unconnected udp6 socket (since 4.18);
- **sendmsg_unix** call to sendto(2), sendmsg(2), sendmmsg(2) for
- an unconnected unix socket (since 6.7);
- **recvmsg4** call to recvfrom(2), recvmsg(2), recvmmsg(2) for
- an unconnected udp4 socket (since 5.2);
- **recvmsg6** call to recvfrom(2), recvmsg(2), recvmmsg(2) for
- an unconnected udp6 socket (since 5.2);
- **recvmsg_unix** call to recvfrom(2), recvmsg(2), recvmmsg(2) for
- an unconnected unix socket (since 6.7);
- **sysctl** sysctl access (since 5.2);
- **getsockopt** call to getsockopt (since 5.3);
- **setsockopt** call to setsockopt (since 5.3);
- **getpeername4** call to getpeername(2) for an inet4 socket (since 5.8);
- **getpeername6** call to getpeername(2) for an inet6 socket (since 5.8);
- **getpeername_unix** call to getpeername(2) for a unix socket (since 6.7);
- **getsockname4** call to getsockname(2) for an inet4 socket (since 5.8);
- **getsockname6** call to getsockname(2) for an inet6 socket (since 5.8).
- **getsockname_unix** call to getsockname(2) for a unix socket (since 6.7);
- **sock_release** closing an userspace inet socket (since 5.9).
-
- **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.
+bpftool cgroup { show | list } *CGROUP* [effective]
+ List all programs attached to the cgroup *CGROUP*.
+
+ Output will start with program ID followed by attach type, attach flags and
+ program name.
+
+ If **effective** is specified retrieve effective programs that will execute
+ for events within a cgroup. This includes inherited along with attached
+ ones.
+
+bpftool cgroup tree [*CGROUP_ROOT*] [effective]
+ Iterate over all cgroups in *CGROUP_ROOT* and list all attached programs.
+ If *CGROUP_ROOT* is not specified, bpftool uses cgroup v2 mountpoint.
+
+ The output is similar to the output of cgroup show/list commands: it starts
+ with absolute cgroup path, followed by program ID, attach type, attach
+ flags and program name.
+
+ If **effective** is specified retrieve effective programs that will execute
+ for events within a cgroup. This includes inherited along with attached
+ ones.
+
+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 one 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)
+ - **bind4** call to bind(2) for an inet4 socket (since 4.17)
+ - **bind6** call to bind(2) for an inet6 socket (since 4.17)
+ - **post_bind4** return from bind(2) for an inet4 socket (since 4.17)
+ - **post_bind6** return from bind(2) for an inet6 socket (since 4.17)
+ - **connect4** call to connect(2) for an inet4 socket (since 4.17)
+ - **connect6** call to connect(2) for an inet6 socket (since 4.17)
+ - **connect_unix** call to connect(2) for a unix socket (since 6.7)
+ - **sendmsg4** call to sendto(2), sendmsg(2), sendmmsg(2) for an unconnected udp4 socket (since 4.18)
+ - **sendmsg6** call to sendto(2), sendmsg(2), sendmmsg(2) for an unconnected udp6 socket (since 4.18)
+ - **sendmsg_unix** call to sendto(2), sendmsg(2), sendmmsg(2) for an unconnected unix socket (since 6.7)
+ - **recvmsg4** call to recvfrom(2), recvmsg(2), recvmmsg(2) for an unconnected udp4 socket (since 5.2)
+ - **recvmsg6** call to recvfrom(2), recvmsg(2), recvmmsg(2) for an unconnected udp6 socket (since 5.2)
+ - **recvmsg_unix** call to recvfrom(2), recvmsg(2), recvmmsg(2) for an unconnected unix socket (since 6.7)
+ - **sysctl** sysctl access (since 5.2)
+ - **getsockopt** call to getsockopt (since 5.3)
+ - **setsockopt** call to setsockopt (since 5.3)
+ - **getpeername4** call to getpeername(2) for an inet4 socket (since 5.8)
+ - **getpeername6** call to getpeername(2) for an inet6 socket (since 5.8)
+ - **getpeername_unix** call to getpeername(2) for a unix socket (since 6.7)
+ - **getsockname4** call to getsockname(2) for an inet4 socket (since 5.8)
+ - **getsockname6** call to getsockname(2) for an inet6 socket (since 5.8)
+ - **getsockname_unix** call to getsockname(2) for a unix socket (since 6.7)
+ - **sock_release** closing a userspace inet socket (since 5.9)
+
+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
=======
- .. include:: common_options.rst
+.. include:: common_options.rst
- -f, --bpffs
- Show file names of pinned programs.
+-f, --bpffs
+ Show file names of pinned programs.
EXAMPLES
========
diff --git a/tools/bpf/bpftool/Documentation/bpftool-feature.rst b/tools/bpf/bpftool/Documentation/bpftool-feature.rst
index e44039f89be7..c7f837898bc7 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-feature.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-feature.rst
@@ -14,77 +14,70 @@ tool for inspection of eBPF-related parameters for Linux kernel or net device
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **feature** *COMMAND*
+**bpftool** [*OPTIONS*] **feature** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| }
+*OPTIONS* := { |COMMON_OPTIONS| }
- *COMMANDS* := { **probe** | **help** }
+*COMMANDS* := { **probe** | **help** }
FEATURE COMMANDS
================
-| **bpftool** **feature probe** [*COMPONENT*] [**full**] [**unprivileged**] [**macros** [**prefix** *PREFIX*]]
-| **bpftool** **feature list_builtins** *GROUP*
-| **bpftool** **feature help**
+| **bpftool** **feature probe** [*COMPONENT*] [**full**] [**unprivileged**] [**macros** [**prefix** *PREFIX*]]
+| **bpftool** **feature list_builtins** *GROUP*
+| **bpftool** **feature help**
|
-| *COMPONENT* := { **kernel** | **dev** *NAME* }
-| *GROUP* := { **prog_types** | **map_types** | **attach_types** | **link_types** | **helpers** }
+| *COMPONENT* := { **kernel** | **dev** *NAME* }
+| *GROUP* := { **prog_types** | **map_types** | **attach_types** | **link_types** | **helpers** }
DESCRIPTION
===========
- **bpftool feature probe** [**kernel**] [**full**] [**macros** [**prefix** *PREFIX*]]
- Probe the running kernel and dump a number of eBPF-related
- parameters, such as availability of the **bpf**\ () system call,
- JIT status, eBPF program types availability, eBPF helper
- functions availability, and more.
-
- By default, bpftool **does not run probes** for
- **bpf_probe_write_user**\ () and **bpf_trace_printk**\()
- helpers which print warnings to kernel logs. To enable them
- and run all probes, the **full** keyword should be used.
-
- If the **macros** keyword (but not the **-j** option) is
- passed, a subset of the output is dumped as a list of
- **#define** macros that are ready to be included in a C
- header file, for example. If, additionally, **prefix** is
- used to define a *PREFIX*, the provided string will be used
- as a prefix to the names of the macros: this can be used to
- avoid conflicts on macro names when including the output of
- this command as a header file.
-
- Keyword **kernel** can be omitted. If no probe target is
- specified, probing the kernel is the default behaviour.
-
- When the **unprivileged** keyword is used, bpftool will dump
- only the features available to a user who does not have the
- **CAP_SYS_ADMIN** capability set. The features available in
- that case usually represent a small subset of the parameters
- supported by the system. Unprivileged users MUST use the
- **unprivileged** keyword: This is to avoid misdetection if
- bpftool is inadvertently run as non-root, for example. This
- keyword is unavailable if bpftool was compiled without
- libcap.
-
- **bpftool feature probe dev** *NAME* [**full**] [**macros** [**prefix** *PREFIX*]]
- Probe network device for supported eBPF features and dump
- results to the console.
-
- The keywords **full**, **macros** and **prefix** have the
- same role as when probing the kernel.
-
- **bpftool feature list_builtins** *GROUP*
- List items known to bpftool. These can be BPF program types
- (**prog_types**), BPF map types (**map_types**), attach types
- (**attach_types**), link types (**link_types**), or BPF helper
- functions (**helpers**). The command does not probe the system, but
- simply lists the elements that bpftool knows from compilation time,
- as provided from libbpf (for all object types) or from the BPF UAPI
- header (list of helpers). This can be used in scripts to iterate over
- BPF types or helpers.
-
- **bpftool feature help**
- Print short help message.
+bpftool feature probe [kernel] [full] [macros [prefix *PREFIX*]]
+ Probe the running kernel and dump a number of eBPF-related parameters, such
+ as availability of the **bpf**\ () system call, JIT status, eBPF program
+ types availability, eBPF helper functions availability, and more.
+
+ By default, bpftool **does not run probes** for **bpf_probe_write_user**\
+ () and **bpf_trace_printk**\() helpers which print warnings to kernel logs.
+ To enable them and run all probes, the **full** keyword should be used.
+
+ If the **macros** keyword (but not the **-j** option) is passed, a subset
+ of the output is dumped as a list of **#define** macros that are ready to
+ be included in a C header file, for example. If, additionally, **prefix**
+ is used to define a *PREFIX*, the provided string will be used as a prefix
+ to the names of the macros: this can be used to avoid conflicts on macro
+ names when including the output of this command as a header file.
+
+ Keyword **kernel** can be omitted. If no probe target is specified, probing
+ the kernel is the default behaviour.
+
+ When the **unprivileged** keyword is used, bpftool will dump only the
+ features available to a user who does not have the **CAP_SYS_ADMIN**
+ capability set. The features available in that case usually represent a
+ small subset of the parameters supported by the system. Unprivileged users
+ MUST use the **unprivileged** keyword: This is to avoid misdetection if
+ bpftool is inadvertently run as non-root, for example. This keyword is
+ unavailable if bpftool was compiled without libcap.
+
+bpftool feature probe dev *NAME* [full] [macros [prefix *PREFIX*]]
+ Probe network device for supported eBPF features and dump results to the
+ console.
+
+ The keywords **full**, **macros** and **prefix** have the same role as when
+ probing the kernel.
+
+bpftool feature list_builtins *GROUP*
+ List items known to bpftool. These can be BPF program types
+ (**prog_types**), BPF map types (**map_types**), attach types
+ (**attach_types**), link types (**link_types**), or BPF helper functions
+ (**helpers**). The command does not probe the system, but simply lists the
+ elements that bpftool knows from compilation time, as provided from libbpf
+ (for all object types) or from the BPF UAPI header (list of helpers). This
+ can be used in scripts to iterate over BPF types or helpers.
+
+bpftool feature help
+ Print short help message.
OPTIONS
=======
- .. include:: common_options.rst
+.. include:: common_options.rst
diff --git a/tools/bpf/bpftool/Documentation/bpftool-gen.rst b/tools/bpf/bpftool/Documentation/bpftool-gen.rst
index 5e60825818dd..ca860fd97d8d 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-gen.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-gen.rst
@@ -14,199 +14,177 @@ tool for BPF code-generation
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **gen** *COMMAND*
+**bpftool** [*OPTIONS*] **gen** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } }
+*OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } }
- *COMMAND* := { **object** | **skeleton** | **help** }
+*COMMAND* := { **object** | **skeleton** | **help** }
GEN COMMANDS
=============
-| **bpftool** **gen object** *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...]
-| **bpftool** **gen skeleton** *FILE* [**name** *OBJECT_NAME*]
-| **bpftool** **gen subskeleton** *FILE* [**name** *OBJECT_NAME*]
-| **bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...]
-| **bpftool** **gen help**
+| **bpftool** **gen object** *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...]
+| **bpftool** **gen skeleton** *FILE* [**name** *OBJECT_NAME*]
+| **bpftool** **gen subskeleton** *FILE* [**name** *OBJECT_NAME*]
+| **bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...]
+| **bpftool** **gen help**
DESCRIPTION
===========
- **bpftool gen object** *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...]
- Statically link (combine) together one or more *INPUT_FILE*'s
- into a single resulting *OUTPUT_FILE*. All the files involved
- are BPF ELF object files.
-
- The rules of BPF static linking are mostly the same as for
- user-space object files, but in addition to combining data
- and instruction sections, .BTF and .BTF.ext (if present in
- any of the input files) data are combined together. .BTF
- data is deduplicated, so all the common types across
- *INPUT_FILE*'s will only be represented once in the resulting
- BTF information.
-
- BPF static linking allows to partition BPF source code into
- individually compiled files that are then linked into
- a single resulting BPF object file, which can be used to
- generated BPF skeleton (with **gen skeleton** command) or
- passed directly into **libbpf** (using **bpf_object__open()**
- family of APIs).
-
- **bpftool gen skeleton** *FILE*
- Generate BPF skeleton C header file for a given *FILE*.
-
- BPF skeleton is an alternative interface to existing libbpf
- APIs for working with BPF objects. Skeleton code is intended
- to significantly shorten and simplify code to load and work
- with BPF programs from userspace side. Generated code is
- tailored to specific input BPF object *FILE*, reflecting its
- structure by listing out available maps, program, variables,
- etc. Skeleton eliminates the need to lookup mentioned
- components by name. Instead, if skeleton instantiation
- succeeds, they are populated in skeleton structure as valid
- libbpf types (e.g., **struct bpf_map** pointer) and can be
- passed to existing generic libbpf APIs.
-
- In addition to simple and reliable access to maps and
- programs, skeleton provides a storage for BPF links (**struct
- bpf_link**) for each BPF program within BPF object. When
- requested, supported BPF programs will be automatically
- attached and resulting BPF links stored for further use by
- user in pre-allocated fields in skeleton struct. For BPF
- programs that can't be automatically attached by libbpf,
- user can attach them manually, but store resulting BPF link
- in per-program link field. All such set up links will be
- automatically destroyed on BPF skeleton destruction. This
- eliminates the need for users to manage links manually and
- rely on libbpf support to detach programs and free up
- resources.
-
- Another facility provided by BPF skeleton is an interface to
- global variables of all supported kinds: mutable, read-only,
- as well as extern ones. This interface allows to pre-setup
- initial values of variables before BPF object is loaded and
- verified by kernel. For non-read-only variables, the same
- interface can be used to fetch values of global variables on
- userspace side, even if they are modified by BPF code.
-
- During skeleton generation, contents of source BPF object
- *FILE* is embedded within generated code and is thus not
- necessary to keep around. This ensures skeleton and BPF
- object file are matching 1-to-1 and always stay in sync.
- Generated code is dual-licensed under LGPL-2.1 and
- BSD-2-Clause licenses.
-
- It is a design goal and guarantee that skeleton interfaces
- are interoperable with generic libbpf APIs. User should
- always be able to use skeleton API to create and load BPF
- object, and later use libbpf APIs to keep working with
- specific maps, programs, etc.
-
- As part of skeleton, few custom functions are generated.
- Each of them is prefixed with object name. Object name can
- either be derived from object file name, i.e., if BPF object
- file name is **example.o**, BPF object name will be
- **example**. Object name can be also specified explicitly
- through **name** *OBJECT_NAME* parameter. The following
- custom functions are provided (assuming **example** as
- the object name):
-
- - **example__open** and **example__open_opts**.
- These functions are used to instantiate skeleton. It
- corresponds to libbpf's **bpf_object__open**\ () API.
- **_opts** variants accepts extra **bpf_object_open_opts**
- options.
-
- - **example__load**.
- This function creates maps, loads and verifies BPF
- programs, initializes global data maps. It corresponds to
- libppf's **bpf_object__load**\ () API.
-
- - **example__open_and_load** combines **example__open** and
- **example__load** invocations in one commonly used
- operation.
-
- - **example__attach** and **example__detach**
- This pair of functions allow to attach and detach,
- correspondingly, already loaded BPF object. Only BPF
- programs of types supported by libbpf for auto-attachment
- will be auto-attached and their corresponding BPF links
- instantiated. For other BPF programs, user can manually
- create a BPF link and assign it to corresponding fields in
- skeleton struct. **example__detach** will detach both
- links created automatically, as well as those populated by
- user manually.
-
- - **example__destroy**
- Detach and unload BPF programs, free up all the resources
- used by skeleton and BPF object.
-
- If BPF object has global variables, corresponding structs
- with memory layout corresponding to global data data section
- layout will be created. Currently supported ones are: *.data*,
- *.bss*, *.rodata*, and *.kconfig* structs/data sections.
- These data sections/structs can be used to set up initial
- values of variables, if set before **example__load**.
- Afterwards, if target kernel supports memory-mapped BPF
- arrays, same structs can be used to fetch and update
- (non-read-only) data from userspace, with same simplicity
- as for BPF side.
-
- **bpftool gen subskeleton** *FILE*
- Generate BPF subskeleton C header file for a given *FILE*.
-
- Subskeletons are similar to skeletons, except they do not own
- the corresponding maps, programs, or global variables. They
- require that the object file used to generate them is already
- loaded into a *bpf_object* by some other means.
-
- This functionality is useful when a library is included into a
- larger BPF program. A subskeleton for the library would have
- access to all objects and globals defined in it, without
- having to know about the larger program.
-
- Consequently, there are only two functions defined
- for subskeletons:
-
- - **example__open(bpf_object\*)**
- Instantiates a subskeleton from an already opened (but not
- necessarily loaded) **bpf_object**.
-
- - **example__destroy()**
- Frees the storage for the subskeleton but *does not* unload
- any BPF programs or maps.
-
- **bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...]
- Generate a minimum BTF file as *OUTPUT*, derived from a given
- *INPUT* BTF file, containing all needed BTF types so one, or
- more, given eBPF objects CO-RE relocations may be satisfied.
-
- When kernels aren't compiled with CONFIG_DEBUG_INFO_BTF,
- libbpf, when loading an eBPF object, has to rely on external
- BTF files to be able to calculate CO-RE relocations.
-
- Usually, an external BTF file is built from existing kernel
- DWARF data using pahole. It contains all the types used by
- its respective kernel image and, because of that, is big.
-
- The min_core_btf feature builds smaller BTF files, customized
- to one or multiple eBPF objects, so they can be distributed
- together with an eBPF CO-RE based application, turning the
- application portable to different kernel versions.
-
- Check examples bellow for more information how to use it.
-
- **bpftool gen help**
- Print short help message.
+bpftool gen object *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...]
+ Statically link (combine) together one or more *INPUT_FILE*'s into a single
+ resulting *OUTPUT_FILE*. All the files involved are BPF ELF object files.
+
+ The rules of BPF static linking are mostly the same as for user-space
+ object files, but in addition to combining data and instruction sections,
+ .BTF and .BTF.ext (if present in any of the input files) data are combined
+ together. .BTF data is deduplicated, so all the common types across
+ *INPUT_FILE*'s will only be represented once in the resulting BTF
+ information.
+
+ BPF static linking allows to partition BPF source code into individually
+ compiled files that are then linked into a single resulting BPF object
+ file, which can be used to generated BPF skeleton (with **gen skeleton**
+ command) or passed directly into **libbpf** (using **bpf_object__open()**
+ family of APIs).
+
+bpftool gen skeleton *FILE*
+ Generate BPF skeleton C header file for a given *FILE*.
+
+ BPF skeleton is an alternative interface to existing libbpf APIs for
+ working with BPF objects. Skeleton code is intended to significantly
+ shorten and simplify code to load and work with BPF programs from userspace
+ side. Generated code is tailored to specific input BPF object *FILE*,
+ reflecting its structure by listing out available maps, program, variables,
+ etc. Skeleton eliminates the need to lookup mentioned components by name.
+ Instead, if skeleton instantiation succeeds, they are populated in skeleton
+ structure as valid libbpf types (e.g., **struct bpf_map** pointer) and can
+ be passed to existing generic libbpf APIs.
+
+ In addition to simple and reliable access to maps and programs, skeleton
+ provides a storage for BPF links (**struct bpf_link**) for each BPF program
+ within BPF object. When requested, supported BPF programs will be
+ automatically attached and resulting BPF links stored for further use by
+ user in pre-allocated fields in skeleton struct. For BPF programs that
+ can't be automatically attached by libbpf, user can attach them manually,
+ but store resulting BPF link in per-program link field. All such set up
+ links will be automatically destroyed on BPF skeleton destruction. This
+ eliminates the need for users to manage links manually and rely on libbpf
+ support to detach programs and free up resources.
+
+ Another facility provided by BPF skeleton is an interface to global
+ variables of all supported kinds: mutable, read-only, as well as extern
+ ones. This interface allows to pre-setup initial values of variables before
+ BPF object is loaded and verified by kernel. For non-read-only variables,
+ the same interface can be used to fetch values of global variables on
+ userspace side, even if they are modified by BPF code.
+
+ During skeleton generation, contents of source BPF object *FILE* is
+ embedded within generated code and is thus not necessary to keep around.
+ This ensures skeleton and BPF object file are matching 1-to-1 and always
+ stay in sync. Generated code is dual-licensed under LGPL-2.1 and
+ BSD-2-Clause licenses.
+
+ It is a design goal and guarantee that skeleton interfaces are
+ interoperable with generic libbpf APIs. User should always be able to use
+ skeleton API to create and load BPF object, and later use libbpf APIs to
+ keep working with specific maps, programs, etc.
+
+ As part of skeleton, few custom functions are generated. Each of them is
+ prefixed with object name. Object name can either be derived from object
+ file name, i.e., if BPF object file name is **example.o**, BPF object name
+ will be **example**. Object name can be also specified explicitly through
+ **name** *OBJECT_NAME* parameter. The following custom functions are
+ provided (assuming **example** as the object name):
+
+ - **example__open** and **example__open_opts**.
+ These functions are used to instantiate skeleton. It corresponds to
+ libbpf's **bpf_object__open**\ () API. **_opts** variants accepts extra
+ **bpf_object_open_opts** options.
+
+ - **example__load**.
+ This function creates maps, loads and verifies BPF programs, initializes
+ global data maps. It corresponds to libbpf's **bpf_object__load**\ ()
+ API.
+
+ - **example__open_and_load** combines **example__open** and
+ **example__load** invocations in one commonly used operation.
+
+ - **example__attach** and **example__detach**.
+ This pair of functions allow to attach and detach, correspondingly,
+ already loaded BPF object. Only BPF programs of types supported by libbpf
+ for auto-attachment will be auto-attached and their corresponding BPF
+ links instantiated. For other BPF programs, user can manually create a
+ BPF link and assign it to corresponding fields in skeleton struct.
+ **example__detach** will detach both links created automatically, as well
+ as those populated by user manually.
+
+ - **example__destroy**.
+ Detach and unload BPF programs, free up all the resources used by
+ skeleton and BPF object.
+
+ If BPF object has global variables, corresponding structs with memory
+ layout corresponding to global data data section layout will be created.
+ Currently supported ones are: *.data*, *.bss*, *.rodata*, and *.kconfig*
+ structs/data sections. These data sections/structs can be used to set up
+ initial values of variables, if set before **example__load**. Afterwards,
+ if target kernel supports memory-mapped BPF arrays, same structs can be
+ used to fetch and update (non-read-only) data from userspace, with same
+ simplicity as for BPF side.
+
+bpftool gen subskeleton *FILE*
+ Generate BPF subskeleton C header file for a given *FILE*.
+
+ Subskeletons are similar to skeletons, except they do not own the
+ corresponding maps, programs, or global variables. They require that the
+ object file used to generate them is already loaded into a *bpf_object* by
+ some other means.
+
+ This functionality is useful when a library is included into a larger BPF
+ program. A subskeleton for the library would have access to all objects and
+ globals defined in it, without having to know about the larger program.
+
+ Consequently, there are only two functions defined for subskeletons:
+
+ - **example__open(bpf_object\*)**.
+ Instantiates a subskeleton from an already opened (but not necessarily
+ loaded) **bpf_object**.
+
+ - **example__destroy()**.
+ Frees the storage for the subskeleton but *does not* unload any BPF
+ programs or maps.
+
+bpftool gen min_core_btf *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...]
+ Generate a minimum BTF file as *OUTPUT*, derived from a given *INPUT* BTF
+ file, containing all needed BTF types so one, or more, given eBPF objects
+ CO-RE relocations may be satisfied.
+
+ When kernels aren't compiled with CONFIG_DEBUG_INFO_BTF, libbpf, when
+ loading an eBPF object, has to rely on external BTF files to be able to
+ calculate CO-RE relocations.
+
+ Usually, an external BTF file is built from existing kernel DWARF data
+ using pahole. It contains all the types used by its respective kernel image
+ and, because of that, is big.
+
+ The min_core_btf feature builds smaller BTF files, customized to one or
+ multiple eBPF objects, so they can be distributed together with an eBPF
+ CO-RE based application, turning the application portable to different
+ kernel versions.
+
+ Check examples below for more information on how to use it.
+
+bpftool gen help
+ Print short help message.
OPTIONS
=======
- .. include:: common_options.rst
+.. include:: common_options.rst
- -L, --use-loader
- For skeletons, generate a "light" skeleton (also known as "loader"
- skeleton). A light skeleton contains a loader eBPF program. It does
- not use the majority of the libbpf infrastructure, and does not need
- libelf.
+-L, --use-loader
+ For skeletons, generate a "light" skeleton (also known as "loader"
+ skeleton). A light skeleton contains a loader eBPF program. It does not use
+ the majority of the libbpf infrastructure, and does not need libelf.
EXAMPLES
========
diff --git a/tools/bpf/bpftool/Documentation/bpftool-iter.rst b/tools/bpf/bpftool/Documentation/bpftool-iter.rst
index 84839d488621..2e5d81c906dc 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-iter.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-iter.rst
@@ -14,50 +14,46 @@ tool to create BPF iterators
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **iter** *COMMAND*
+**bpftool** [*OPTIONS*] **iter** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| }
+*OPTIONS* := { |COMMON_OPTIONS| }
- *COMMANDS* := { **pin** | **help** }
+*COMMANDS* := { **pin** | **help** }
ITER COMMANDS
-===================
+=============
-| **bpftool** **iter pin** *OBJ* *PATH* [**map** *MAP*]
-| **bpftool** **iter help**
+| **bpftool** **iter pin** *OBJ* *PATH* [**map** *MAP*]
+| **bpftool** **iter help**
|
-| *OBJ* := /a/file/of/bpf_iter_target.o
-| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
+| *OBJ* := /a/file/of/bpf_iter_target.o
+| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
DESCRIPTION
===========
- **bpftool iter pin** *OBJ* *PATH* [**map** *MAP*]
- A bpf iterator combines a kernel iterating of
- particular kernel data (e.g., tasks, bpf_maps, etc.)
- and a bpf program called for each kernel data object
- (e.g., one task, one bpf_map, etc.). User space can
- *read* kernel iterator output through *read()* syscall.
-
- The *pin* command creates a bpf iterator from *OBJ*,
- and pin it to *PATH*. The *PATH* should be located
- in *bpffs* mount. It must not contain a dot
- character ('.'), which is reserved for future extensions
- of *bpffs*.
-
- Map element bpf iterator requires an additional parameter
- *MAP* so bpf program can iterate over map elements for
- that map. User can have a bpf program in kernel to run
- with each map element, do checking, filtering, aggregation,
- etc. without copying data to user space.
-
- User can then *cat PATH* to see the bpf iterator output.
-
- **bpftool iter help**
- Print short help message.
+bpftool iter pin *OBJ* *PATH* [map *MAP*]
+ A bpf iterator combines a kernel iterating of particular kernel data (e.g.,
+ tasks, bpf_maps, etc.) and a bpf program called for each kernel data object
+ (e.g., one task, one bpf_map, etc.). User space can *read* kernel iterator
+ output through *read()* syscall.
+
+ The *pin* command creates a bpf iterator from *OBJ*, and pin it to *PATH*.
+ The *PATH* should be located in *bpffs* mount. It must not contain a dot
+ character ('.'), which is reserved for future extensions of *bpffs*.
+
+ Map element bpf iterator requires an additional parameter *MAP* so bpf
+ program can iterate over map elements for that map. User can have a bpf
+ program in kernel to run with each map element, do checking, filtering,
+ aggregation, etc. without copying data to user space.
+
+ User can then *cat PATH* to see the bpf iterator output.
+
+bpftool iter help
+ Print short help message.
OPTIONS
=======
- .. include:: common_options.rst
+.. include:: common_options.rst
EXAMPLES
========
diff --git a/tools/bpf/bpftool/Documentation/bpftool-link.rst b/tools/bpf/bpftool/Documentation/bpftool-link.rst
index 52a4eee4af54..6f09d4405ed8 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-link.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-link.rst
@@ -14,67 +14,62 @@ tool for inspection and simple manipulation of eBPF links
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **link** *COMMAND*
+**bpftool** [*OPTIONS*] **link** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| | { **-f** | **--bpffs** } | { **-n** | **--nomount** } }
+*OPTIONS* := { |COMMON_OPTIONS| | { **-f** | **--bpffs** } | { **-n** | **--nomount** } }
- *COMMANDS* := { **show** | **list** | **pin** | **help** }
+*COMMANDS* := { **show** | **list** | **pin** | **help** }
LINK COMMANDS
=============
-| **bpftool** **link { show | list }** [*LINK*]
-| **bpftool** **link pin** *LINK* *FILE*
-| **bpftool** **link detach** *LINK*
-| **bpftool** **link help**
+| **bpftool** **link { show | list }** [*LINK*]
+| **bpftool** **link pin** *LINK* *FILE*
+| **bpftool** **link detach** *LINK*
+| **bpftool** **link help**
|
-| *LINK* := { **id** *LINK_ID* | **pinned** *FILE* }
+| *LINK* := { **id** *LINK_ID* | **pinned** *FILE* }
DESCRIPTION
===========
- **bpftool link { show | list }** [*LINK*]
- Show information about active links. If *LINK* is
- specified show information only about given link,
- otherwise list all links currently active on the system.
+bpftool link { show | list } [*LINK*]
+ Show information about active links. If *LINK* is specified show
+ information only about given link, otherwise list all links currently
+ active on the system.
- Output will start with link ID followed by link type and
- zero or more named attributes, some of which depend on type
- of link.
+ Output will start with link ID followed by link type and zero or more named
+ attributes, some of which depend on type of link.
- Since Linux 5.8 bpftool is able to discover information about
- processes that hold open file descriptors (FDs) against BPF
- links. On such kernels bpftool will automatically emit this
- information as well.
+ Since Linux 5.8 bpftool is able to discover information about processes
+ that hold open file descriptors (FDs) against BPF links. On such kernels
+ bpftool will automatically emit this information as well.
- **bpftool link pin** *LINK* *FILE*
- Pin link *LINK* as *FILE*.
+bpftool link pin *LINK* *FILE*
+ Pin link *LINK* as *FILE*.
- Note: *FILE* must be located in *bpffs* mount. It must not
- contain a dot character ('.'), which is reserved for future
- extensions of *bpffs*.
+ Note: *FILE* must be located in *bpffs* mount. It must not contain a dot
+ character ('.'), which is reserved for future extensions of *bpffs*.
- **bpftool link detach** *LINK*
- Force-detach link *LINK*. BPF link and its underlying BPF
- program will stay valid, but they will be detached from the
- respective BPF hook and BPF link will transition into
- a defunct state until last open file descriptor for that
- link is closed.
+bpftool link detach *LINK*
+ Force-detach link *LINK*. BPF link and its underlying BPF program will stay
+ valid, but they will be detached from the respective BPF hook and BPF link
+ will transition into a defunct state until last open file descriptor for
+ that link is closed.
- **bpftool link help**
- Print short help message.
+bpftool link help
+ Print short help message.
OPTIONS
=======
- .. include:: common_options.rst
+ .. include:: common_options.rst
- -f, --bpffs
- When showing BPF links, show file names of pinned
- links.
+ -f, --bpffs
+ When showing BPF links, show file names of pinned links.
- -n, --nomount
- Do not automatically attempt to mount any virtual file system
- (such as tracefs or BPF virtual file system) when necessary.
+ -n, --nomount
+ Do not automatically attempt to mount any virtual file system (such as
+ tracefs or BPF virtual file system) when necessary.
EXAMPLES
========
diff --git a/tools/bpf/bpftool/Documentation/bpftool-map.rst b/tools/bpf/bpftool/Documentation/bpftool-map.rst
index 9d6a314dfd7a..252e4c538edb 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-map.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-map.rst
@@ -14,166 +14,160 @@ tool for inspection and simple manipulation of eBPF maps
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **map** *COMMAND*
+**bpftool** [*OPTIONS*] **map** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| | { **-f** | **--bpffs** } | { **-n** | **--nomount** } }
+*OPTIONS* := { |COMMON_OPTIONS| | { **-f** | **--bpffs** } | { **-n** | **--nomount** } }
- *COMMANDS* :=
- { **show** | **list** | **create** | **dump** | **update** | **lookup** | **getnext** |
- **delete** | **pin** | **help** }
+*COMMANDS* :=
+{ **show** | **list** | **create** | **dump** | **update** | **lookup** | **getnext** |
+**delete** | **pin** | **help** }
MAP COMMANDS
=============
-| **bpftool** **map** { **show** | **list** } [*MAP*]
-| **bpftool** **map create** *FILE* **type** *TYPE* **key** *KEY_SIZE* **value** *VALUE_SIZE* \
-| **entries** *MAX_ENTRIES* **name** *NAME* [**flags** *FLAGS*] [**inner_map** *MAP*] \
-| [**offload_dev** *NAME*]
-| **bpftool** **map dump** *MAP*
-| **bpftool** **map update** *MAP* [**key** *DATA*] [**value** *VALUE*] [*UPDATE_FLAGS*]
-| **bpftool** **map lookup** *MAP* [**key** *DATA*]
-| **bpftool** **map getnext** *MAP* [**key** *DATA*]
-| **bpftool** **map delete** *MAP* **key** *DATA*
-| **bpftool** **map pin** *MAP* *FILE*
-| **bpftool** **map event_pipe** *MAP* [**cpu** *N* **index** *M*]
-| **bpftool** **map peek** *MAP*
-| **bpftool** **map push** *MAP* **value** *VALUE*
-| **bpftool** **map pop** *MAP*
-| **bpftool** **map enqueue** *MAP* **value** *VALUE*
-| **bpftool** **map dequeue** *MAP*
-| **bpftool** **map freeze** *MAP*
-| **bpftool** **map help**
+| **bpftool** **map** { **show** | **list** } [*MAP*]
+| **bpftool** **map create** *FILE* **type** *TYPE* **key** *KEY_SIZE* **value** *VALUE_SIZE* \
+| **entries** *MAX_ENTRIES* **name** *NAME* [**flags** *FLAGS*] [**inner_map** *MAP*] \
+| [**offload_dev** *NAME*]
+| **bpftool** **map dump** *MAP*
+| **bpftool** **map update** *MAP* [**key** *DATA*] [**value** *VALUE*] [*UPDATE_FLAGS*]
+| **bpftool** **map lookup** *MAP* [**key** *DATA*]
+| **bpftool** **map getnext** *MAP* [**key** *DATA*]
+| **bpftool** **map delete** *MAP* **key** *DATA*
+| **bpftool** **map pin** *MAP* *FILE*
+| **bpftool** **map event_pipe** *MAP* [**cpu** *N* **index** *M*]
+| **bpftool** **map peek** *MAP*
+| **bpftool** **map push** *MAP* **value** *VALUE*
+| **bpftool** **map pop** *MAP*
+| **bpftool** **map enqueue** *MAP* **value** *VALUE*
+| **bpftool** **map dequeue** *MAP*
+| **bpftool** **map freeze** *MAP*
+| **bpftool** **map help**
|
-| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* | **name** *MAP_NAME* }
-| *DATA* := { [**hex**] *BYTES* }
-| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* }
-| *VALUE* := { *DATA* | *MAP* | *PROG* }
-| *UPDATE_FLAGS* := { **any** | **exist** | **noexist** }
-| *TYPE* := { **hash** | **array** | **prog_array** | **perf_event_array** | **percpu_hash**
-| | **percpu_array** | **stack_trace** | **cgroup_array** | **lru_hash**
-| | **lru_percpu_hash** | **lpm_trie** | **array_of_maps** | **hash_of_maps**
-| | **devmap** | **devmap_hash** | **sockmap** | **cpumap** | **xskmap** | **sockhash**
-| | **cgroup_storage** | **reuseport_sockarray** | **percpu_cgroup_storage**
-| | **queue** | **stack** | **sk_storage** | **struct_ops** | **ringbuf** | **inode_storage**
-| | **task_storage** | **bloom_filter** | **user_ringbuf** | **cgrp_storage** | **arena** }
+| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* | **name** *MAP_NAME* }
+| *DATA* := { [**hex**] *BYTES* }
+| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* }
+| *VALUE* := { *DATA* | *MAP* | *PROG* }
+| *UPDATE_FLAGS* := { **any** | **exist** | **noexist** }
+| *TYPE* := { **hash** | **array** | **prog_array** | **perf_event_array** | **percpu_hash**
+| | **percpu_array** | **stack_trace** | **cgroup_array** | **lru_hash**
+| | **lru_percpu_hash** | **lpm_trie** | **array_of_maps** | **hash_of_maps**
+| | **devmap** | **devmap_hash** | **sockmap** | **cpumap** | **xskmap** | **sockhash**
+| | **cgroup_storage** | **reuseport_sockarray** | **percpu_cgroup_storage**
+| | **queue** | **stack** | **sk_storage** | **struct_ops** | **ringbuf** | **inode_storage**
+| | **task_storage** | **bloom_filter** | **user_ringbuf** | **cgrp_storage** | **arena** }
DESCRIPTION
===========
- **bpftool map { show | list }** [*MAP*]
- Show information about loaded maps. If *MAP* is specified
- show information only about given maps, otherwise list all
- maps currently loaded on the system. In case of **name**,
- *MAP* may match several maps which will all be shown.
+bpftool map { show | list } [*MAP*]
+ Show information about loaded maps. If *MAP* is specified show information
+ only about given maps, otherwise list all maps currently loaded on the
+ system. In case of **name**, *MAP* may match several maps which will all
+ be shown.
- Output will start with map ID followed by map type and
- zero or more named attributes (depending on kernel version).
+ Output will start with map ID followed by map type and zero or more named
+ attributes (depending on kernel version).
- Since Linux 5.8 bpftool is able to discover information about
- processes that hold open file descriptors (FDs) against BPF
- maps. On such kernels bpftool will automatically emit this
- information as well.
+ Since Linux 5.8 bpftool is able to discover information about processes
+ that hold open file descriptors (FDs) against BPF maps. On such kernels
+ bpftool will automatically emit this information as well.
- **bpftool map create** *FILE* **type** *TYPE* **key** *KEY_SIZE* **value** *VALUE_SIZE* **entries** *MAX_ENTRIES* **name** *NAME* [**flags** *FLAGS*] [**inner_map** *MAP*] [**offload_dev** *NAME*]
- Create a new map with given parameters and pin it to *bpffs*
- as *FILE*.
+bpftool map create *FILE* type *TYPE* key *KEY_SIZE* value *VALUE_SIZE* entries *MAX_ENTRIES* name *NAME* [flags *FLAGS*] [inner_map *MAP*] [offload_dev *NAME*]
+ Create a new map with given parameters and pin it to *bpffs* as *FILE*.
- *FLAGS* should be an integer which is the combination of
- desired flags, e.g. 1024 for **BPF_F_MMAPABLE** (see bpf.h
- UAPI header for existing flags).
+ *FLAGS* should be an integer which is the combination of desired flags,
+ e.g. 1024 for **BPF_F_MMAPABLE** (see bpf.h UAPI header for existing
+ flags).
- To create maps of type array-of-maps or hash-of-maps, the
- **inner_map** keyword must be used to pass an inner map. The
- kernel needs it to collect metadata related to the inner maps
- that the new map will work with.
+ To create maps of type array-of-maps or hash-of-maps, the **inner_map**
+ keyword must be used to pass an inner map. The kernel needs it to collect
+ metadata related to the inner maps that the new map will work with.
- Keyword **offload_dev** expects a network interface name,
- and is used to request hardware offload for the map.
+ Keyword **offload_dev** expects a network interface name, and is used to
+ request hardware offload for the map.
- **bpftool map dump** *MAP*
- Dump all entries in a given *MAP*. In case of **name**,
- *MAP* may match several maps which will all be dumped.
+bpftool map dump *MAP*
+ Dump all entries in a given *MAP*. In case of **name**, *MAP* may match
+ several maps which will all be dumped.
- **bpftool map update** *MAP* [**key** *DATA*] [**value** *VALUE*] [*UPDATE_FLAGS*]
- Update map entry for a given *KEY*.
+bpftool map update *MAP* [key *DATA*] [value *VALUE*] [*UPDATE_FLAGS*]
+ Update map entry for a given *KEY*.
- *UPDATE_FLAGS* can be one of: **any** update existing entry
- or add if doesn't exit; **exist** update only if entry already
- exists; **noexist** update only if entry doesn't exist.
+ *UPDATE_FLAGS* can be one of: **any** update existing entry or add if
+ doesn't exit; **exist** update only if entry already exists; **noexist**
+ update only if entry doesn't exist.
- If the **hex** keyword is provided in front of the bytes
- sequence, the bytes are parsed as hexadecimal values, even if
- no "0x" prefix is added. If the keyword is not provided, then
- the bytes are parsed as decimal values, unless a "0x" prefix
- (for hexadecimal) or a "0" prefix (for octal) is provided.
+ If the **hex** keyword is provided in front of the bytes sequence, the
+ bytes are parsed as hexadecimal values, even if no "0x" prefix is added. If
+ the keyword is not provided, then the bytes are parsed as decimal values,
+ unless a "0x" prefix (for hexadecimal) or a "0" prefix (for octal) is
+ provided.
- **bpftool map lookup** *MAP* [**key** *DATA*]
- Lookup **key** in the map.
+bpftool map lookup *MAP* [key *DATA*]
+ Lookup **key** in the map.
- **bpftool map getnext** *MAP* [**key** *DATA*]
- Get next key. If *key* is not specified, get first key.
+bpftool map getnext *MAP* [key *DATA*]
+ Get next key. If *key* is not specified, get first key.
- **bpftool map delete** *MAP* **key** *DATA*
- Remove entry from the map.
+bpftool map delete *MAP* key *DATA*
+ Remove entry from the map.
- **bpftool map pin** *MAP* *FILE*
- Pin map *MAP* as *FILE*.
+bpftool map pin *MAP* *FILE*
+ Pin map *MAP* as *FILE*.
- Note: *FILE* must be located in *bpffs* mount. It must not
- contain a dot character ('.'), which is reserved for future
- extensions of *bpffs*.
+ Note: *FILE* must be located in *bpffs* mount. It must not contain a dot
+ character ('.'), which is reserved for future extensions of *bpffs*.
- **bpftool** **map event_pipe** *MAP* [**cpu** *N* **index** *M*]
- Read events from a **BPF_MAP_TYPE_PERF_EVENT_ARRAY** map.
+bpftool map event_pipe *MAP* [cpu *N* index *M*]
+ Read events from a **BPF_MAP_TYPE_PERF_EVENT_ARRAY** map.
- Install perf rings into a perf event array map and dump
- output of any **bpf_perf_event_output**\ () call in the kernel.
- By default read the number of CPUs on the system and
- install perf ring for each CPU in the corresponding index
- in the array.
+ Install perf rings into a perf event array map and dump output of any
+ **bpf_perf_event_output**\ () call in the kernel. By default read the
+ number of CPUs on the system and install perf ring for each CPU in the
+ corresponding index in the array.
- If **cpu** and **index** are specified, install perf ring
- for given **cpu** at **index** in the array (single ring).
+ If **cpu** and **index** are specified, install perf ring for given **cpu**
+ at **index** in the array (single ring).
- Note that installing a perf ring into an array will silently
- replace any existing ring. Any other application will stop
- receiving events if it installed its rings earlier.
+ Note that installing a perf ring into an array will silently replace any
+ existing ring. Any other application will stop receiving events if it
+ installed its rings earlier.
- **bpftool map peek** *MAP*
- Peek next value in the queue or stack.
+bpftool map peek *MAP*
+ Peek next value in the queue or stack.
- **bpftool map push** *MAP* **value** *VALUE*
- Push *VALUE* onto the stack.
+bpftool map push *MAP* value *VALUE*
+ Push *VALUE* onto the stack.
- **bpftool map pop** *MAP*
- Pop and print value from the stack.
+bpftool map pop *MAP*
+ Pop and print value from the stack.
- **bpftool map enqueue** *MAP* **value** *VALUE*
- Enqueue *VALUE* into the queue.
+bpftool map enqueue *MAP* value *VALUE*
+ Enqueue *VALUE* into the queue.
- **bpftool map dequeue** *MAP*
- Dequeue and print value from the queue.
+bpftool map dequeue *MAP*
+ Dequeue and print value from the queue.
- **bpftool map freeze** *MAP*
- Freeze the map as read-only from user space. Entries from a
- frozen map can not longer be updated or deleted with the
- **bpf**\ () system call. This operation is not reversible,
- and the map remains immutable from user space until its
- destruction. However, read and write permissions for BPF
- programs to the map remain unchanged.
+bpftool map freeze *MAP*
+ Freeze the map as read-only from user space. Entries from a frozen map can
+ not longer be updated or deleted with the **bpf**\ () system call. This
+ operation is not reversible, and the map remains immutable from user space
+ until its destruction. However, read and write permissions for BPF programs
+ to the map remain unchanged.
- **bpftool map help**
- Print short help message.
+bpftool map help
+ Print short help message.
OPTIONS
=======
- .. include:: common_options.rst
+.. include:: common_options.rst
- -f, --bpffs
- Show file names of pinned maps.
+-f, --bpffs
+ Show file names of pinned maps.
- -n, --nomount
- Do not automatically attempt to mount any virtual file system
- (such as tracefs or BPF virtual file system) when necessary.
+-n, --nomount
+ Do not automatically attempt to mount any virtual file system (such as
+ tracefs or BPF virtual file system) when necessary.
EXAMPLES
========
diff --git a/tools/bpf/bpftool/Documentation/bpftool-net.rst b/tools/bpf/bpftool/Documentation/bpftool-net.rst
index dd3f9469765b..a9ed8992800f 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-net.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-net.rst
@@ -14,76 +14,76 @@ tool for inspection of networking related bpf prog attachments
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **net** *COMMAND*
+**bpftool** [*OPTIONS*] **net** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| }
+*OPTIONS* := { |COMMON_OPTIONS| }
- *COMMANDS* :=
- { **show** | **list** | **attach** | **detach** | **help** }
+*COMMANDS* := { **show** | **list** | **attach** | **detach** | **help** }
NET COMMANDS
============
-| **bpftool** **net** { **show** | **list** } [ **dev** *NAME* ]
-| **bpftool** **net attach** *ATTACH_TYPE* *PROG* **dev** *NAME* [ **overwrite** ]
-| **bpftool** **net detach** *ATTACH_TYPE* **dev** *NAME*
-| **bpftool** **net help**
+| **bpftool** **net** { **show** | **list** } [ **dev** *NAME* ]
+| **bpftool** **net attach** *ATTACH_TYPE* *PROG* **dev** *NAME* [ **overwrite** ]
+| **bpftool** **net detach** *ATTACH_TYPE* **dev** *NAME*
+| **bpftool** **net help**
|
-| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
-| *ATTACH_TYPE* := { **xdp** | **xdpgeneric** | **xdpdrv** | **xdpoffload** }
+| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* }
+| *ATTACH_TYPE* := { **xdp** | **xdpgeneric** | **xdpdrv** | **xdpoffload** | **tcx_ingress** | **tcx_egress** }
DESCRIPTION
===========
- **bpftool net { show | list }** [ **dev** *NAME* ]
- List bpf program attachments in the kernel networking subsystem.
-
- Currently, device driver xdp attachments, tcx, netkit and old-style tc
- classifier/action attachments, flow_dissector as well as netfilter
- attachments are implemented, i.e., for
- program types **BPF_PROG_TYPE_XDP**, **BPF_PROG_TYPE_SCHED_CLS**,
- **BPF_PROG_TYPE_SCHED_ACT**, **BPF_PROG_TYPE_FLOW_DISSECTOR**,
- **BPF_PROG_TYPE_NETFILTER**.
-
- For programs attached to a particular cgroup, e.g.,
- **BPF_PROG_TYPE_CGROUP_SKB**, **BPF_PROG_TYPE_CGROUP_SOCK**,
- **BPF_PROG_TYPE_SOCK_OPS** and **BPF_PROG_TYPE_CGROUP_SOCK_ADDR**,
- users can use **bpftool cgroup** to dump cgroup attachments.
- For sk_{filter, skb, msg, reuseport} and lwt/seg6
- bpf programs, users should consult other tools, e.g., iproute2.
-
- The current output will start with all xdp program attachments, followed by
- all tcx, netkit, then tc class/qdisc bpf program attachments, then flow_dissector
- and finally netfilter programs. Both xdp programs and tcx/netkit/tc programs are
- ordered based on ifindex number. If multiple bpf programs attached
- to the same networking device through **tc**, the order will be first
- all bpf programs attached to tcx, netkit, then tc classes, then all bpf programs
- attached to non clsact qdiscs, and finally all bpf programs attached
- to root and clsact qdisc.
-
- **bpftool** **net attach** *ATTACH_TYPE* *PROG* **dev** *NAME* [ **overwrite** ]
- Attach bpf program *PROG* to network interface *NAME* with
- type specified by *ATTACH_TYPE*. Previously attached bpf program
- can be replaced by the command used with **overwrite** option.
- Currently, only XDP-related modes are supported for *ATTACH_TYPE*.
-
- *ATTACH_TYPE* can be of:
- **xdp** - try native XDP and fallback to generic XDP if NIC driver does not support it;
- **xdpgeneric** - Generic XDP. runs at generic XDP hook when packet already enters receive path as skb;
- **xdpdrv** - Native XDP. runs earliest point in driver's receive path;
- **xdpoffload** - Offload XDP. runs directly on NIC on each packet reception;
-
- **bpftool** **net detach** *ATTACH_TYPE* **dev** *NAME*
- Detach bpf program attached to network interface *NAME* with
- type specified by *ATTACH_TYPE*. To detach bpf program, same
- *ATTACH_TYPE* previously used for attach must be specified.
- Currently, only XDP-related modes are supported for *ATTACH_TYPE*.
-
- **bpftool net help**
- Print short help message.
+bpftool net { show | list } [ dev *NAME* ]
+ List bpf program attachments in the kernel networking subsystem.
+
+ Currently, device driver xdp attachments, tcx, netkit and old-style tc
+ classifier/action attachments, flow_dissector as well as netfilter
+ attachments are implemented, i.e., for program types **BPF_PROG_TYPE_XDP**,
+ **BPF_PROG_TYPE_SCHED_CLS**, **BPF_PROG_TYPE_SCHED_ACT**,
+ **BPF_PROG_TYPE_FLOW_DISSECTOR**, **BPF_PROG_TYPE_NETFILTER**.
+
+ For programs attached to a particular cgroup, e.g.,
+ **BPF_PROG_TYPE_CGROUP_SKB**, **BPF_PROG_TYPE_CGROUP_SOCK**,
+ **BPF_PROG_TYPE_SOCK_OPS** and **BPF_PROG_TYPE_CGROUP_SOCK_ADDR**, users
+ can use **bpftool cgroup** to dump cgroup attachments. For sk_{filter, skb,
+ msg, reuseport} and lwt/seg6 bpf programs, users should consult other
+ tools, e.g., iproute2.
+
+ The current output will start with all xdp program attachments, followed by
+ all tcx, netkit, then tc class/qdisc bpf program attachments, then
+ flow_dissector and finally netfilter programs. Both xdp programs and
+ tcx/netkit/tc programs are ordered based on ifindex number. If multiple bpf
+ programs attached to the same networking device through **tc**, the order
+ will be first all bpf programs attached to tcx, netkit, then tc classes,
+ then all bpf programs attached to non clsact qdiscs, and finally all bpf
+ programs attached to root and clsact qdisc.
+
+bpftool net attach *ATTACH_TYPE* *PROG* dev *NAME* [ overwrite ]
+ Attach bpf program *PROG* to network interface *NAME* with type specified
+ by *ATTACH_TYPE*. Previously attached bpf program can be replaced by the
+ command used with **overwrite** option. Currently, only XDP-related modes
+ are supported for *ATTACH_TYPE*.
+
+ *ATTACH_TYPE* can be of:
+ **xdp** - try native XDP and fallback to generic XDP if NIC driver does not support it;
+ **xdpgeneric** - Generic XDP. runs at generic XDP hook when packet already enters receive path as skb;
+ **xdpdrv** - Native XDP. runs earliest point in driver's receive path;
+ **xdpoffload** - Offload XDP. runs directly on NIC on each packet reception;
+ **tcx_ingress** - Ingress TCX. runs on ingress net traffic;
+ **tcx_egress** - Egress TCX. runs on egress net traffic;
+
+bpftool net detach *ATTACH_TYPE* dev *NAME*
+ Detach bpf program attached to network interface *NAME* with type specified
+ by *ATTACH_TYPE*. To detach bpf program, same *ATTACH_TYPE* previously used
+ for attach must be specified. Currently, only XDP-related modes are
+ supported for *ATTACH_TYPE*.
+
+bpftool net help
+ Print short help message.
OPTIONS
=======
- .. include:: common_options.rst
+.. include:: common_options.rst
EXAMPLES
========
@@ -180,3 +180,23 @@ EXAMPLES
::
xdp:
+
+|
+| **# bpftool net attach tcx_ingress name tc_prog dev lo**
+| **# bpftool net**
+|
+
+::
+
+ tc:
+ lo(1) tcx/ingress tc_prog prog_id 29
+
+|
+| **# bpftool net attach tcx_ingress name tc_prog dev lo**
+| **# bpftool net detach tcx_ingress dev lo**
+| **# bpftool net**
+|
+
+::
+
+ tc:
diff --git a/tools/bpf/bpftool/Documentation/bpftool-perf.rst b/tools/bpf/bpftool/Documentation/bpftool-perf.rst
index 5fea633a82f1..8c1ae55be596 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-perf.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-perf.rst
@@ -14,37 +14,37 @@ tool for inspection of perf related bpf prog attachments
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **perf** *COMMAND*
+**bpftool** [*OPTIONS*] **perf** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| }
+*OPTIONS* := { |COMMON_OPTIONS| }
- *COMMANDS* :=
- { **show** | **list** | **help** }
+*COMMANDS* :=
+{ **show** | **list** | **help** }
PERF COMMANDS
=============
-| **bpftool** **perf** { **show** | **list** }
-| **bpftool** **perf help**
+| **bpftool** **perf** { **show** | **list** }
+| **bpftool** **perf help**
DESCRIPTION
===========
- **bpftool perf { show | list }**
- List all raw_tracepoint, tracepoint, kprobe attachment in the system.
+bpftool perf { show | list }
+ List all raw_tracepoint, tracepoint, kprobe attachment in the system.
- Output will start with process id and file descriptor in that process,
- followed by bpf program id, attachment information, and attachment point.
- The attachment point for raw_tracepoint/tracepoint is the trace probe name.
- The attachment point for k[ret]probe is either symbol name and offset,
- or a kernel virtual address.
- The attachment point for u[ret]probe is the file name and the file offset.
+ Output will start with process id and file descriptor in that process,
+ followed by bpf program id, attachment information, and attachment point.
+ The attachment point for raw_tracepoint/tracepoint is the trace probe name.
+ The attachment point for k[ret]probe is either symbol name and offset, or a
+ kernel virtual address. The attachment point for u[ret]probe is the file
+ name and the file offset.
- **bpftool perf help**
- Print short help message.
+bpftool perf help
+ Print short help message.
OPTIONS
=======
- .. include:: common_options.rst
+.. include:: common_options.rst
EXAMPLES
========
diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
index 58e6a5b10ef7..d6304e01afe0 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
@@ -14,250 +14,226 @@ tool for inspection and simple manipulation of eBPF progs
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **prog** *COMMAND*
+**bpftool** [*OPTIONS*] **prog** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| |
- { **-f** | **--bpffs** } | { **-m** | **--mapcompat** } | { **-n** | **--nomount** } |
- { **-L** | **--use-loader** } }
+*OPTIONS* := { |COMMON_OPTIONS| |
+{ **-f** | **--bpffs** } | { **-m** | **--mapcompat** } | { **-n** | **--nomount** } |
+{ **-L** | **--use-loader** } }
- *COMMANDS* :=
- { **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load** |
- **loadall** | **help** }
+*COMMANDS* :=
+{ **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load** |
+**loadall** | **help** }
PROG COMMANDS
=============
-| **bpftool** **prog** { **show** | **list** } [*PROG*]
-| **bpftool** **prog dump xlated** *PROG* [{ **file** *FILE* | [**opcodes**] [**linum**] [**visual**] }]
-| **bpftool** **prog dump jited** *PROG* [{ **file** *FILE* | [**opcodes**] [**linum**] }]
-| **bpftool** **prog pin** *PROG* *FILE*
-| **bpftool** **prog** { **load** | **loadall** } *OBJ* *PATH* [**type** *TYPE*] [**map** { **idx** *IDX* | **name** *NAME* } *MAP*] [{ **offload_dev** | **xdpmeta_dev** } *NAME*] [**pinmaps** *MAP_DIR*] [**autoattach**]
-| **bpftool** **prog attach** *PROG* *ATTACH_TYPE* [*MAP*]
-| **bpftool** **prog detach** *PROG* *ATTACH_TYPE* [*MAP*]
-| **bpftool** **prog tracelog**
-| **bpftool** **prog run** *PROG* **data_in** *FILE* [**data_out** *FILE* [**data_size_out** *L*]] [**ctx_in** *FILE* [**ctx_out** *FILE* [**ctx_size_out** *M*]]] [**repeat** *N*]
-| **bpftool** **prog profile** *PROG* [**duration** *DURATION*] *METRICs*
-| **bpftool** **prog help**
+| **bpftool** **prog** { **show** | **list** } [*PROG*]
+| **bpftool** **prog dump xlated** *PROG* [{ **file** *FILE* | [**opcodes**] [**linum**] [**visual**] }]
+| **bpftool** **prog dump jited** *PROG* [{ **file** *FILE* | [**opcodes**] [**linum**] }]
+| **bpftool** **prog pin** *PROG* *FILE*
+| **bpftool** **prog** { **load** | **loadall** } *OBJ* *PATH* [**type** *TYPE*] [**map** { **idx** *IDX* | **name** *NAME* } *MAP*] [{ **offload_dev** | **xdpmeta_dev** } *NAME*] [**pinmaps** *MAP_DIR*] [**autoattach**]
+| **bpftool** **prog attach** *PROG* *ATTACH_TYPE* [*MAP*]
+| **bpftool** **prog detach** *PROG* *ATTACH_TYPE* [*MAP*]
+| **bpftool** **prog tracelog**
+| **bpftool** **prog run** *PROG* **data_in** *FILE* [**data_out** *FILE* [**data_size_out** *L*]] [**ctx_in** *FILE* [**ctx_out** *FILE* [**ctx_size_out** *M*]]] [**repeat** *N*]
+| **bpftool** **prog profile** *PROG* [**duration** *DURATION*] *METRICs*
+| **bpftool** **prog help**
|
-| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
-| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* }
-| *TYPE* := {
-| **socket** | **kprobe** | **kretprobe** | **classifier** | **action** |
-| **tracepoint** | **raw_tracepoint** | **xdp** | **perf_event** | **cgroup/skb** |
-| **cgroup/sock** | **cgroup/dev** | **lwt_in** | **lwt_out** | **lwt_xmit** |
-| **lwt_seg6local** | **sockops** | **sk_skb** | **sk_msg** | **lirc_mode2** |
-| **cgroup/bind4** | **cgroup/bind6** | **cgroup/post_bind4** | **cgroup/post_bind6** |
-| **cgroup/connect4** | **cgroup/connect6** | **cgroup/connect_unix** |
-| **cgroup/getpeername4** | **cgroup/getpeername6** | **cgroup/getpeername_unix** |
-| **cgroup/getsockname4** | **cgroup/getsockname6** | **cgroup/getsockname_unix** |
-| **cgroup/sendmsg4** | **cgroup/sendmsg6** | **cgroup/sendmsg_unix** |
-| **cgroup/recvmsg4** | **cgroup/recvmsg6** | **cgroup/recvmsg_unix** | **cgroup/sysctl** |
-| **cgroup/getsockopt** | **cgroup/setsockopt** | **cgroup/sock_release** |
-| **struct_ops** | **fentry** | **fexit** | **freplace** | **sk_lookup**
-| }
-| *ATTACH_TYPE* := {
-| **sk_msg_verdict** | **sk_skb_verdict** | **sk_skb_stream_verdict** |
-| **sk_skb_stream_parser** | **flow_dissector**
-| }
-| *METRICs* := {
-| **cycles** | **instructions** | **l1d_loads** | **llc_misses** |
-| **itlb_misses** | **dtlb_misses**
-| }
+| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* | **name** *MAP_NAME* }
+| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* }
+| *TYPE* := {
+| **socket** | **kprobe** | **kretprobe** | **classifier** | **action** |
+| **tracepoint** | **raw_tracepoint** | **xdp** | **perf_event** | **cgroup/skb** |
+| **cgroup/sock** | **cgroup/dev** | **lwt_in** | **lwt_out** | **lwt_xmit** |
+| **lwt_seg6local** | **sockops** | **sk_skb** | **sk_msg** | **lirc_mode2** |
+| **cgroup/bind4** | **cgroup/bind6** | **cgroup/post_bind4** | **cgroup/post_bind6** |
+| **cgroup/connect4** | **cgroup/connect6** | **cgroup/connect_unix** |
+| **cgroup/getpeername4** | **cgroup/getpeername6** | **cgroup/getpeername_unix** |
+| **cgroup/getsockname4** | **cgroup/getsockname6** | **cgroup/getsockname_unix** |
+| **cgroup/sendmsg4** | **cgroup/sendmsg6** | **cgroup/sendmsg_unix** |
+| **cgroup/recvmsg4** | **cgroup/recvmsg6** | **cgroup/recvmsg_unix** | **cgroup/sysctl** |
+| **cgroup/getsockopt** | **cgroup/setsockopt** | **cgroup/sock_release** |
+| **struct_ops** | **fentry** | **fexit** | **freplace** | **sk_lookup**
+| }
+| *ATTACH_TYPE* := {
+| **sk_msg_verdict** | **sk_skb_verdict** | **sk_skb_stream_verdict** |
+| **sk_skb_stream_parser** | **flow_dissector**
+| }
+| *METRICs* := {
+| **cycles** | **instructions** | **l1d_loads** | **llc_misses** |
+| **itlb_misses** | **dtlb_misses**
+| }
DESCRIPTION
===========
- **bpftool prog { show | list }** [*PROG*]
- Show information about loaded programs. If *PROG* is
- specified show information only about given programs,
- otherwise list all programs currently loaded on the system.
- In case of **tag** or **name**, *PROG* may match several
- programs which will all be shown.
-
- Output will start with program ID followed by program type and
- zero or more named attributes (depending on kernel version).
-
- Since Linux 5.1 the kernel can collect statistics on BPF
- programs (such as the total time spent running the program,
- and the number of times it was run). If available, bpftool
- shows such statistics. However, the kernel does not collect
- them by defaults, as it slightly impacts performance on each
- program run. Activation or deactivation of the feature is
- performed via the **kernel.bpf_stats_enabled** sysctl knob.
-
- Since Linux 5.8 bpftool is able to discover information about
- processes that hold open file descriptors (FDs) against BPF
- programs. On such kernels bpftool will automatically emit this
- information as well.
-
- **bpftool prog dump xlated** *PROG* [{ **file** *FILE* | [**opcodes**] [**linum**] [**visual**] }]
- Dump eBPF instructions of the programs from the kernel. By
- default, eBPF will be disassembled and printed to standard
- output in human-readable format. In this case, **opcodes**
- controls if raw opcodes should be printed as well.
-
- In case of **tag** or **name**, *PROG* may match several
- programs which will all be dumped. However, if **file** or
- **visual** is specified, *PROG* must match a single program.
-
- If **file** is specified, the binary image will instead be
- written to *FILE*.
-
- If **visual** is specified, control flow graph (CFG) will be
- built instead, and eBPF instructions will be presented with
- CFG in DOT format, on standard output.
-
- If the programs have line_info available, the source line will
- be displayed. If **linum** is specified, the filename, line
- number and line column will also be displayed.
-
- **bpftool prog dump jited** *PROG* [{ **file** *FILE* | [**opcodes**] [**linum**] }]
- Dump jited image (host machine code) of the program.
-
- If *FILE* is specified image will be written to a file,
- otherwise it will be disassembled and printed to stdout.
- *PROG* must match a single program when **file** is specified.
-
- **opcodes** controls if raw opcodes will be printed.
-
- If the prog has line_info available, the source line will
- be displayed. If **linum** is specified, the filename, line
- number and line column will also be displayed.
-
- **bpftool prog pin** *PROG* *FILE*
- Pin program *PROG* as *FILE*.
-
- Note: *FILE* must be located in *bpffs* mount. It must not
- contain a dot character ('.'), which is reserved for future
- extensions of *bpffs*.
-
- **bpftool prog { load | loadall }** *OBJ* *PATH* [**type** *TYPE*] [**map** { **idx** *IDX* | **name** *NAME* } *MAP*] [{ **offload_dev** | **xdpmeta_dev** } *NAME*] [**pinmaps** *MAP_DIR*] [**autoattach**]
- Load bpf program(s) from binary *OBJ* and pin as *PATH*.
- **bpftool prog load** pins only the first program from the
- *OBJ* as *PATH*. **bpftool prog loadall** pins all programs
- from the *OBJ* under *PATH* directory.
- **type** is optional, if not specified program type will be
- inferred from section names.
- By default bpftool will create new maps as declared in the ELF
- object being loaded. **map** parameter allows for the reuse
- of existing maps. It can be specified multiple times, each
- time for a different map. *IDX* refers to index of the map
- to be replaced in the ELF file counting from 0, while *NAME*
- allows to replace a map by name. *MAP* specifies the map to
- use, referring to it by **id** or through a **pinned** file.
- If **offload_dev** *NAME* is specified program will be loaded
- onto given networking device (offload).
- If **xdpmeta_dev** *NAME* is specified program will become
- device-bound without offloading, this facilitates access
- to XDP metadata.
- Optional **pinmaps** argument can be provided to pin all
- maps under *MAP_DIR* directory.
-
- If **autoattach** is specified program will be attached
- before pin. In that case, only the link (representing the
- program attached to its hook) is pinned, not the program as
- such, so the path won't show in **bpftool prog show -f**,
- only show in **bpftool link show -f**. Also, this only works
- when bpftool (libbpf) is able to infer all necessary
- information from the object file, in particular, it's not
- supported for all program types. If a program does not
- support autoattach, bpftool falls back to regular pinning
- for that program instead.
-
- Note: *PATH* must be located in *bpffs* mount. It must not
- contain a dot character ('.'), which is reserved for future
- extensions of *bpffs*.
-
- **bpftool prog attach** *PROG* *ATTACH_TYPE* [*MAP*]
- Attach bpf program *PROG* (with type specified by
- *ATTACH_TYPE*). Most *ATTACH_TYPEs* require a *MAP*
- parameter, with the exception of *flow_dissector* which is
- attached to current networking name space.
-
- **bpftool prog detach** *PROG* *ATTACH_TYPE* [*MAP*]
- Detach bpf program *PROG* (with type specified by
- *ATTACH_TYPE*). Most *ATTACH_TYPEs* require a *MAP*
- parameter, with the exception of *flow_dissector* which is
- detached from the current networking name space.
-
- **bpftool prog tracelog**
- Dump the trace pipe of the system to the console (stdout).
- Hit <Ctrl+C> to stop printing. BPF programs can write to this
- trace pipe at runtime with the **bpf_trace_printk**\ () helper.
- This should be used only for debugging purposes. For
- streaming data from BPF programs to user space, one can use
- perf events (see also **bpftool-map**\ (8)).
-
- **bpftool prog run** *PROG* **data_in** *FILE* [**data_out** *FILE* [**data_size_out** *L*]] [**ctx_in** *FILE* [**ctx_out** *FILE* [**ctx_size_out** *M*]]] [**repeat** *N*]
- Run BPF program *PROG* in the kernel testing infrastructure
- for BPF, meaning that the program works on the data and
- context provided by the user, and not on actual packets or
- monitored functions etc. Return value and duration for the
- test run are printed out to the console.
-
- Input data is read from the *FILE* passed with **data_in**.
- If this *FILE* is "**-**", input data is read from standard
- input. Input context, if any, is read from *FILE* passed with
- **ctx_in**. Again, "**-**" can be used to read from standard
- input, but only if standard input is not already in use for
- input data. If a *FILE* is passed with **data_out**, output
- data is written to that file. Similarly, output context is
- written to the *FILE* passed with **ctx_out**. For both
- output flows, "**-**" can be used to print to the standard
- output (as plain text, or JSON if relevant option was
- passed). If output keywords are omitted, output data and
- context are discarded. Keywords **data_size_out** and
- **ctx_size_out** are used to pass the size (in bytes) for the
- output buffers to the kernel, although the default of 32 kB
- should be more than enough for most cases.
-
- Keyword **repeat** is used to indicate the number of
- consecutive runs to perform. Note that output data and
- context printed to files correspond to the last of those
- runs. The duration printed out at the end of the runs is an
- average over all runs performed by the command.
-
- Not all program types support test run. Among those which do,
- not all of them can take the **ctx_in**/**ctx_out**
- arguments. bpftool does not perform checks on program types.
-
- **bpftool prog profile** *PROG* [**duration** *DURATION*] *METRICs*
- Profile *METRICs* for bpf program *PROG* for *DURATION*
- seconds or until user hits <Ctrl+C>. *DURATION* is optional.
- If *DURATION* is not specified, the profiling will run up to
- **UINT_MAX** seconds.
-
- **bpftool prog help**
- Print short help message.
+bpftool prog { show | list } [*PROG*]
+ Show information about loaded programs. If *PROG* is specified show
+ information only about given programs, otherwise list all programs
+ currently loaded on the system. In case of **tag** or **name**, *PROG* may
+ match several programs which will all be shown.
+
+ Output will start with program ID followed by program type and zero or more
+ named attributes (depending on kernel version).
+
+ Since Linux 5.1 the kernel can collect statistics on BPF programs (such as
+ the total time spent running the program, and the number of times it was
+ run). If available, bpftool shows such statistics. However, the kernel does
+ not collect them by defaults, as it slightly impacts performance on each
+ program run. Activation or deactivation of the feature is performed via the
+ **kernel.bpf_stats_enabled** sysctl knob.
+
+ Since Linux 5.8 bpftool is able to discover information about processes
+ that hold open file descriptors (FDs) against BPF programs. On such kernels
+ bpftool will automatically emit this information as well.
+
+bpftool prog dump xlated *PROG* [{ file *FILE* | [opcodes] [linum] [visual] }]
+ Dump eBPF instructions of the programs from the kernel. By default, eBPF
+ will be disassembled and printed to standard output in human-readable
+ format. In this case, **opcodes** controls if raw opcodes should be printed
+ as well.
+
+ In case of **tag** or **name**, *PROG* may match several programs which
+ will all be dumped. However, if **file** or **visual** is specified,
+ *PROG* must match a single program.
+
+ If **file** is specified, the binary image will instead be written to
+ *FILE*.
+
+ If **visual** is specified, control flow graph (CFG) will be built instead,
+ and eBPF instructions will be presented with CFG in DOT format, on standard
+ output.
+
+ If the programs have line_info available, the source line will be
+ displayed. If **linum** is specified, the filename, line number and line
+ column will also be displayed.
+
+bpftool prog dump jited *PROG* [{ file *FILE* | [opcodes] [linum] }]
+ Dump jited image (host machine code) of the program.
+
+ If *FILE* is specified image will be written to a file, otherwise it will
+ be disassembled and printed to stdout. *PROG* must match a single program
+ when **file** is specified.
+
+ **opcodes** controls if raw opcodes will be printed.
+
+ If the prog has line_info available, the source line will be displayed. If
+ **linum** is specified, the filename, line number and line column will also
+ be displayed.
+
+bpftool prog pin *PROG* *FILE*
+ Pin program *PROG* as *FILE*.
+
+ Note: *FILE* must be located in *bpffs* mount. It must not contain a dot
+ character ('.'), which is reserved for future extensions of *bpffs*.
+
+bpftool prog { load | loadall } *OBJ* *PATH* [type *TYPE*] [map { idx *IDX* | name *NAME* } *MAP*] [{ offload_dev | xdpmeta_dev } *NAME*] [pinmaps *MAP_DIR*] [autoattach]
+ Load bpf program(s) from binary *OBJ* and pin as *PATH*. **bpftool prog
+ load** pins only the first program from the *OBJ* as *PATH*. **bpftool prog
+ loadall** pins all programs from the *OBJ* under *PATH* directory. **type**
+ is optional, if not specified program type will be inferred from section
+ names. By default bpftool will create new maps as declared in the ELF
+ object being loaded. **map** parameter allows for the reuse of existing
+ maps. It can be specified multiple times, each time for a different map.
+ *IDX* refers to index of the map to be replaced in the ELF file counting
+ from 0, while *NAME* allows to replace a map by name. *MAP* specifies the
+ map to use, referring to it by **id** or through a **pinned** file. If
+ **offload_dev** *NAME* is specified program will be loaded onto given
+ networking device (offload). If **xdpmeta_dev** *NAME* is specified program
+ will become device-bound without offloading, this facilitates access to XDP
+ metadata. Optional **pinmaps** argument can be provided to pin all maps
+ under *MAP_DIR* directory.
+
+ If **autoattach** is specified program will be attached before pin. In that
+ case, only the link (representing the program attached to its hook) is
+ pinned, not the program as such, so the path won't show in **bpftool prog
+ show -f**, only show in **bpftool link show -f**. Also, this only works
+ when bpftool (libbpf) is able to infer all necessary information from the
+ object file, in particular, it's not supported for all program types. If a
+ program does not support autoattach, bpftool falls back to regular pinning
+ for that program instead.
+
+ Note: *PATH* must be located in *bpffs* mount. It must not contain a dot
+ character ('.'), which is reserved for future extensions of *bpffs*.
+
+bpftool prog attach *PROG* *ATTACH_TYPE* [*MAP*]
+ Attach bpf program *PROG* (with type specified by *ATTACH_TYPE*). Most
+ *ATTACH_TYPEs* require a *MAP* parameter, with the exception of
+ *flow_dissector* which is attached to current networking name space.
+
+bpftool prog detach *PROG* *ATTACH_TYPE* [*MAP*]
+ Detach bpf program *PROG* (with type specified by *ATTACH_TYPE*). Most
+ *ATTACH_TYPEs* require a *MAP* parameter, with the exception of
+ *flow_dissector* which is detached from the current networking name space.
+
+bpftool prog tracelog
+ Dump the trace pipe of the system to the console (stdout). Hit <Ctrl+C> to
+ stop printing. BPF programs can write to this trace pipe at runtime with
+ the **bpf_trace_printk**\ () helper. This should be used only for debugging
+ purposes. For streaming data from BPF programs to user space, one can use
+ perf events (see also **bpftool-map**\ (8)).
+
+bpftool prog run *PROG* data_in *FILE* [data_out *FILE* [data_size_out *L*]] [ctx_in *FILE* [ctx_out *FILE* [ctx_size_out *M*]]] [repeat *N*]
+ Run BPF program *PROG* in the kernel testing infrastructure for BPF,
+ meaning that the program works on the data and context provided by the
+ user, and not on actual packets or monitored functions etc. Return value
+ and duration for the test run are printed out to the console.
+
+ Input data is read from the *FILE* passed with **data_in**. If this *FILE*
+ is "**-**", input data is read from standard input. Input context, if any,
+ is read from *FILE* passed with **ctx_in**. Again, "**-**" can be used to
+ read from standard input, but only if standard input is not already in use
+ for input data. If a *FILE* is passed with **data_out**, output data is
+ written to that file. Similarly, output context is written to the *FILE*
+ passed with **ctx_out**. For both output flows, "**-**" can be used to
+ print to the standard output (as plain text, or JSON if relevant option was
+ passed). If output keywords are omitted, output data and context are
+ discarded. Keywords **data_size_out** and **ctx_size_out** are used to pass
+ the size (in bytes) for the output buffers to the kernel, although the
+ default of 32 kB should be more than enough for most cases.
+
+ Keyword **repeat** is used to indicate the number of consecutive runs to
+ perform. Note that output data and context printed to files correspond to
+ the last of those runs. The duration printed out at the end of the runs is
+ an average over all runs performed by the command.
+
+ Not all program types support test run. Among those which do, not all of
+ them can take the **ctx_in**/**ctx_out** arguments. bpftool does not
+ perform checks on program types.
+
+bpftool prog profile *PROG* [duration *DURATION*] *METRICs*
+ Profile *METRICs* for bpf program *PROG* for *DURATION* seconds or until
+ user hits <Ctrl+C>. *DURATION* is optional. If *DURATION* is not specified,
+ the profiling will run up to **UINT_MAX** seconds.
+
+bpftool prog help
+ Print short help message.
OPTIONS
=======
- .. include:: common_options.rst
-
- -f, --bpffs
- When showing BPF programs, show file names of pinned
- programs.
-
- -m, --mapcompat
- Allow loading maps with unknown map definitions.
-
- -n, --nomount
- Do not automatically attempt to mount any virtual file system
- (such as tracefs or BPF virtual file system) when necessary.
-
- -L, --use-loader
- Load program as a "loader" program. This is useful to debug
- the generation of such programs. When this option is in
- use, bpftool attempts to load the programs from the object
- file into the kernel, but does not pin them (therefore, the
- *PATH* must not be provided).
-
- When combined with the **-d**\ \|\ **--debug** option,
- additional debug messages are generated, and the execution
- of the loader program will use the **bpf_trace_printk**\ ()
- helper to log each step of loading BTF, creating the maps,
- and loading the programs (see **bpftool prog tracelog** as
- a way to dump those messages).
+.. include:: common_options.rst
+
+-f, --bpffs
+ When showing BPF programs, show file names of pinned programs.
+
+-m, --mapcompat
+ Allow loading maps with unknown map definitions.
+
+-n, --nomount
+ Do not automatically attempt to mount any virtual file system (such as
+ tracefs or BPF virtual file system) when necessary.
+
+-L, --use-loader
+ Load program as a "loader" program. This is useful to debug the generation
+ of such programs. When this option is in use, bpftool attempts to load the
+ programs from the object file into the kernel, but does not pin them
+ (therefore, the *PATH* must not be provided).
+
+ When combined with the **-d**\ \|\ **--debug** option, additional debug
+ messages are generated, and the execution of the loader program will use
+ the **bpf_trace_printk**\ () helper to log each step of loading BTF,
+ creating the maps, and loading the programs (see **bpftool prog tracelog**
+ as a way to dump those messages).
EXAMPLES
========
diff --git a/tools/bpf/bpftool/Documentation/bpftool-struct_ops.rst b/tools/bpf/bpftool/Documentation/bpftool-struct_ops.rst
index 8022b5321dbe..e871b9539ac7 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-struct_ops.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-struct_ops.rst
@@ -14,61 +14,60 @@ tool to register/unregister/introspect BPF struct_ops
SYNOPSIS
========
- **bpftool** [*OPTIONS*] **struct_ops** *COMMAND*
+**bpftool** [*OPTIONS*] **struct_ops** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| }
+*OPTIONS* := { |COMMON_OPTIONS| }
- *COMMANDS* :=
- { **show** | **list** | **dump** | **register** | **unregister** | **help** }
+*COMMANDS* :=
+{ **show** | **list** | **dump** | **register** | **unregister** | **help** }
STRUCT_OPS COMMANDS
===================
-| **bpftool** **struct_ops { show | list }** [*STRUCT_OPS_MAP*]
-| **bpftool** **struct_ops dump** [*STRUCT_OPS_MAP*]
-| **bpftool** **struct_ops register** *OBJ* [*LINK_DIR*]
-| **bpftool** **struct_ops unregister** *STRUCT_OPS_MAP*
-| **bpftool** **struct_ops help**
+| **bpftool** **struct_ops { show | list }** [*STRUCT_OPS_MAP*]
+| **bpftool** **struct_ops dump** [*STRUCT_OPS_MAP*]
+| **bpftool** **struct_ops register** *OBJ* [*LINK_DIR*]
+| **bpftool** **struct_ops unregister** *STRUCT_OPS_MAP*
+| **bpftool** **struct_ops help**
|
-| *STRUCT_OPS_MAP* := { **id** *STRUCT_OPS_MAP_ID* | **name** *STRUCT_OPS_MAP_NAME* }
-| *OBJ* := /a/file/of/bpf_struct_ops.o
+| *STRUCT_OPS_MAP* := { **id** *STRUCT_OPS_MAP_ID* | **name** *STRUCT_OPS_MAP_NAME* }
+| *OBJ* := /a/file/of/bpf_struct_ops.o
DESCRIPTION
===========
- **bpftool struct_ops { show | list }** [*STRUCT_OPS_MAP*]
- Show brief information about the struct_ops in the system.
- If *STRUCT_OPS_MAP* is specified, it shows information only
- for the given struct_ops. Otherwise, it lists all struct_ops
- currently existing in the system.
-
- Output will start with struct_ops map ID, followed by its map
- name and its struct_ops's kernel type.
-
- **bpftool struct_ops dump** [*STRUCT_OPS_MAP*]
- Dump details information about the struct_ops in the system.
- If *STRUCT_OPS_MAP* is specified, it dumps information only
- for the given struct_ops. Otherwise, it dumps all struct_ops
- currently existing in the system.
-
- **bpftool struct_ops register** *OBJ* [*LINK_DIR*]
- Register bpf struct_ops from *OBJ*. All struct_ops under
- the ELF section ".struct_ops" and ".struct_ops.link" will
- be registered to its kernel subsystem. For each
- struct_ops in the ".struct_ops.link" section, a link
- will be created. You can give *LINK_DIR* to provide a
- directory path where these links will be pinned with the
- same name as their corresponding map name.
-
- **bpftool struct_ops unregister** *STRUCT_OPS_MAP*
- Unregister the *STRUCT_OPS_MAP* from the kernel subsystem.
-
- **bpftool struct_ops help**
- Print short help message.
+bpftool struct_ops { show | list } [*STRUCT_OPS_MAP*]
+ Show brief information about the struct_ops in the system. If
+ *STRUCT_OPS_MAP* is specified, it shows information only for the given
+ struct_ops. Otherwise, it lists all struct_ops currently existing in the
+ system.
+
+ Output will start with struct_ops map ID, followed by its map name and its
+ struct_ops's kernel type.
+
+bpftool struct_ops dump [*STRUCT_OPS_MAP*]
+ Dump details information about the struct_ops in the system. If
+ *STRUCT_OPS_MAP* is specified, it dumps information only for the given
+ struct_ops. Otherwise, it dumps all struct_ops currently existing in the
+ system.
+
+bpftool struct_ops register *OBJ* [*LINK_DIR*]
+ Register bpf struct_ops from *OBJ*. All struct_ops under the ELF section
+ ".struct_ops" and ".struct_ops.link" will be registered to its kernel
+ subsystem. For each struct_ops in the ".struct_ops.link" section, a link
+ will be created. You can give *LINK_DIR* to provide a directory path where
+ these links will be pinned with the same name as their corresponding map
+ name.
+
+bpftool struct_ops unregister *STRUCT_OPS_MAP*
+ Unregister the *STRUCT_OPS_MAP* from the kernel subsystem.
+
+bpftool struct_ops help
+ Print short help message.
OPTIONS
=======
- .. include:: common_options.rst
+.. include:: common_options.rst
EXAMPLES
========
diff --git a/tools/bpf/bpftool/Documentation/bpftool.rst b/tools/bpf/bpftool/Documentation/bpftool.rst
index 09e4f2ff5658..f38ae5c40439 100644
--- a/tools/bpf/bpftool/Documentation/bpftool.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool.rst
@@ -14,57 +14,57 @@ tool for inspection and simple manipulation of eBPF programs and maps
SYNOPSIS
========
- **bpftool** [*OPTIONS*] *OBJECT* { *COMMAND* | **help** }
+**bpftool** [*OPTIONS*] *OBJECT* { *COMMAND* | **help** }
- **bpftool** **batch file** *FILE*
+**bpftool** **batch file** *FILE*
- **bpftool** **version**
+**bpftool** **version**
- *OBJECT* := { **map** | **prog** | **link** | **cgroup** | **perf** | **net** | **feature** |
- **btf** | **gen** | **struct_ops** | **iter** }
+*OBJECT* := { **map** | **prog** | **link** | **cgroup** | **perf** | **net** | **feature** |
+**btf** | **gen** | **struct_ops** | **iter** }
- *OPTIONS* := { { **-V** | **--version** } | |COMMON_OPTIONS| }
+*OPTIONS* := { { **-V** | **--version** } | |COMMON_OPTIONS| }
- *MAP-COMMANDS* :=
- { **show** | **list** | **create** | **dump** | **update** | **lookup** | **getnext** |
- **delete** | **pin** | **event_pipe** | **help** }
+*MAP-COMMANDS* :=
+{ **show** | **list** | **create** | **dump** | **update** | **lookup** | **getnext** |
+**delete** | **pin** | **event_pipe** | **help** }
- *PROG-COMMANDS* := { **show** | **list** | **dump jited** | **dump xlated** | **pin** |
- **load** | **attach** | **detach** | **help** }
+*PROG-COMMANDS* := { **show** | **list** | **dump jited** | **dump xlated** | **pin** |
+**load** | **attach** | **detach** | **help** }
- *LINK-COMMANDS* := { **show** | **list** | **pin** | **detach** | **help** }
+*LINK-COMMANDS* := { **show** | **list** | **pin** | **detach** | **help** }
- *CGROUP-COMMANDS* := { **show** | **list** | **attach** | **detach** | **help** }
+*CGROUP-COMMANDS* := { **show** | **list** | **attach** | **detach** | **help** }
- *PERF-COMMANDS* := { **show** | **list** | **help** }
+*PERF-COMMANDS* := { **show** | **list** | **help** }
- *NET-COMMANDS* := { **show** | **list** | **help** }
+*NET-COMMANDS* := { **show** | **list** | **help** }
- *FEATURE-COMMANDS* := { **probe** | **help** }
+*FEATURE-COMMANDS* := { **probe** | **help** }
- *BTF-COMMANDS* := { **show** | **list** | **dump** | **help** }
+*BTF-COMMANDS* := { **show** | **list** | **dump** | **help** }
- *GEN-COMMANDS* := { **object** | **skeleton** | **min_core_btf** | **help** }
+*GEN-COMMANDS* := { **object** | **skeleton** | **min_core_btf** | **help** }
- *STRUCT-OPS-COMMANDS* := { **show** | **list** | **dump** | **register** | **unregister** | **help** }
+*STRUCT-OPS-COMMANDS* := { **show** | **list** | **dump** | **register** | **unregister** | **help** }
- *ITER-COMMANDS* := { **pin** | **help** }
+*ITER-COMMANDS* := { **pin** | **help** }
DESCRIPTION
===========
- *bpftool* allows for inspection and simple modification of BPF objects
- on the system.
+*bpftool* allows for inspection and simple modification of BPF objects on the
+system.
- Note that format of the output of all tools is not guaranteed to be
- stable and should not be depended upon.
+Note that format of the output of all tools is not guaranteed to be stable and
+should not be depended upon.
OPTIONS
=======
- .. include:: common_options.rst
+.. include:: common_options.rst
- -m, --mapcompat
- Allow loading maps with unknown map definitions.
+-m, --mapcompat
+ Allow loading maps with unknown map definitions.
- -n, --nomount
- Do not automatically attempt to mount any virtual file system
- (such as tracefs or BPF virtual file system) when necessary.
+-n, --nomount
+ Do not automatically attempt to mount any virtual file system (such as
+ tracefs or BPF virtual file system) when necessary.
diff --git a/tools/bpf/bpftool/Documentation/common_options.rst b/tools/bpf/bpftool/Documentation/common_options.rst
index 30df7a707f02..9234b9dab768 100644
--- a/tools/bpf/bpftool/Documentation/common_options.rst
+++ b/tools/bpf/bpftool/Documentation/common_options.rst
@@ -1,25 +1,23 @@
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-h, --help
- Print short help message (similar to **bpftool help**).
+ Print short help message (similar to **bpftool help**).
-V, --version
- Print bpftool's version number (similar to **bpftool version**), the
- number of the libbpf version in use, and optional features that were
- included when bpftool was compiled. Optional features include linking
- against LLVM or libbfd to provide the disassembler for JIT-ted
- programs (**bpftool prog dump jited**) and usage of BPF skeletons
- (some features like **bpftool prog profile** or showing pids
- associated to BPF objects may rely on it).
+ Print bpftool's version number (similar to **bpftool version**), the number
+ of the libbpf version in use, and optional features that were included when
+ bpftool was compiled. Optional features include linking against LLVM or
+ libbfd to provide the disassembler for JIT-ted programs (**bpftool prog
+ dump jited**) and usage of BPF skeletons (some features like **bpftool prog
+ profile** or showing pids associated to BPF objects may rely on it).
-j, --json
- Generate JSON output. For commands that cannot produce JSON, this
- option has no effect.
+ Generate JSON output. For commands that cannot produce JSON, this option
+ has no effect.
-p, --pretty
- Generate human-readable JSON output. Implies **-j**.
+ Generate human-readable JSON output. Implies **-j**.
-d, --debug
- Print all logs available, even debug-level information. This includes
- logs from libbpf as well as from the verifier, when attempting to
- load programs.
+ Print all logs available, even debug-level information. This includes logs
+ from libbpf as well as from the verifier, when attempting to load programs.
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index e9154ace80ff..dd9f3ec84201 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -89,6 +89,10 @@ ifneq ($(EXTRA_LDFLAGS),)
LDFLAGS += $(EXTRA_LDFLAGS)
endif
+HOST_CFLAGS := $(subst -I$(LIBBPF_INCLUDE),-I$(LIBBPF_BOOTSTRAP_INCLUDE),\
+ $(subst $(CLANG_CROSS_FLAGS),,$(CFLAGS)))
+HOST_LDFLAGS := $(LDFLAGS)
+
INSTALL ?= install
RM ?= rm -f
@@ -102,6 +106,7 @@ FEATURE_TESTS += libbfd-liberty
FEATURE_TESTS += libbfd-liberty-z
FEATURE_TESTS += disassembler-four-args
FEATURE_TESTS += disassembler-init-styled
+FEATURE_TESTS += libelf-zstd
FEATURE_DISPLAY := clang-bpf-co-re
FEATURE_DISPLAY += llvm
@@ -128,6 +133,12 @@ endif
LIBS = $(LIBBPF) -lelf -lz
LIBS_BOOTSTRAP = $(LIBBPF_BOOTSTRAP) -lelf -lz
+
+ifeq ($(feature-libelf-zstd),1)
+LIBS += -lzstd
+LIBS_BOOTSTRAP += -lzstd
+endif
+
ifeq ($(feature-libcap), 1)
CFLAGS += -DUSE_LIBCAP
LIBS += -lcap
@@ -143,7 +154,11 @@ ifeq ($(feature-llvm),1)
# If LLVM is available, use it for JIT disassembly
CFLAGS += -DHAVE_LLVM_SUPPORT
LLVM_CONFIG_LIB_COMPONENTS := mcdisassembler all-targets
- CFLAGS += $(shell $(LLVM_CONFIG) --cflags --libs $(LLVM_CONFIG_LIB_COMPONENTS))
+ # llvm-config always adds -D_GNU_SOURCE, however, it may already be in CFLAGS
+ # (e.g. when bpftool build is called from selftests build as selftests
+ # Makefile includes lib.mk which sets -D_GNU_SOURCE) which would cause
+ # compilation error due to redefinition. Let's filter it out here.
+ CFLAGS += $(filter-out -D_GNU_SOURCE,$(shell $(LLVM_CONFIG) --cflags))
LIBS += $(shell $(LLVM_CONFIG) --libs $(LLVM_CONFIG_LIB_COMPONENTS))
ifeq ($(shell $(LLVM_CONFIG) --shared-mode),static)
LIBS += $(shell $(LLVM_CONFIG) --system-libs $(LLVM_CONFIG_LIB_COMPONENTS))
@@ -178,12 +193,9 @@ ifeq ($(filter -DHAVE_LLVM_SUPPORT -DHAVE_LIBBFD_SUPPORT,$(CFLAGS)),)
SRCS := $(filter-out jit_disasm.c,$(SRCS))
endif
-HOST_CFLAGS = $(subst -I$(LIBBPF_INCLUDE),-I$(LIBBPF_BOOTSTRAP_INCLUDE),\
- $(subst $(CLANG_CROSS_FLAGS),,$(CFLAGS)))
-
BPFTOOL_BOOTSTRAP := $(BOOTSTRAP_OUTPUT)bpftool
-BOOTSTRAP_OBJS = $(addprefix $(BOOTSTRAP_OUTPUT),main.o common.o json_writer.o gen.o btf.o xlated_dumper.o btf_dumper.o disasm.o)
+BOOTSTRAP_OBJS = $(addprefix $(BOOTSTRAP_OUTPUT),main.o common.o json_writer.o gen.o btf.o)
$(BOOTSTRAP_OBJS): $(LIBBPF_BOOTSTRAP)
OBJS = $(patsubst %.c,$(OUTPUT)%.o,$(SRCS)) $(OUTPUT)disasm.o
@@ -203,10 +215,11 @@ ifeq ($(feature-clang-bpf-co-re),1)
BUILD_BPF_SKELS := 1
-$(OUTPUT)vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL_BOOTSTRAP)
ifeq ($(VMLINUX_H),)
+$(OUTPUT)vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL_BOOTSTRAP)
$(QUIET_GEN)$(BPFTOOL_BOOTSTRAP) btf dump file $< format c > $@
else
+$(OUTPUT)vmlinux.h: $(VMLINUX_H)
$(Q)cp "$(VMLINUX_H)" $@
endif
@@ -231,14 +244,11 @@ endif
CFLAGS += $(if $(BUILD_BPF_SKELS),,-DBPFTOOL_WITHOUT_SKELETONS)
-$(BOOTSTRAP_OUTPUT)disasm.o: $(srctree)/kernel/bpf/disasm.c
- $(QUIET_CC)$(HOSTCC) $(HOST_CFLAGS) -c -MMD $< -o $@
-
$(OUTPUT)disasm.o: $(srctree)/kernel/bpf/disasm.c
$(QUIET_CC)$(CC) $(CFLAGS) -c -MMD $< -o $@
$(BPFTOOL_BOOTSTRAP): $(BOOTSTRAP_OBJS) $(LIBBPF_BOOTSTRAP)
- $(QUIET_LINK)$(HOSTCC) $(HOST_CFLAGS) $(LDFLAGS) $(BOOTSTRAP_OBJS) $(LIBS_BOOTSTRAP) -o $@
+ $(QUIET_LINK)$(HOSTCC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(BOOTSTRAP_OBJS) $(LIBS_BOOTSTRAP) -o $@
$(OUTPUT)bpftool: $(OBJS) $(LIBBPF)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool
index 6e4f7ce6bc01..1ce409a6cbd9 100644
--- a/tools/bpf/bpftool/bash-completion/bpftool
+++ b/tools/bpf/bpftool/bash-completion/bpftool
@@ -106,19 +106,19 @@ _bpftool_get_link_ids()
_bpftool_get_obj_map_names()
{
- local obj
+ local obj maps
obj=$1
- maps=$(objdump -j maps -t $obj 2>/dev/null | \
- command awk '/g . maps/ {print $NF}')
+ maps=$(objdump -j .maps -t $obj 2>/dev/null | \
+ command awk '/g . .maps/ {print $NF}')
COMPREPLY+=( $( compgen -W "$maps" -- "$cur" ) )
}
_bpftool_get_obj_map_idxs()
{
- local obj
+ local obj nmaps
obj=$1
@@ -136,7 +136,7 @@ _sysfs_get_netdevs()
# Retrieve type of the map that we are operating on.
_bpftool_map_guess_map_type()
{
- local keyword ref
+ local keyword idx ref=""
for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
case "${words[$((idx-2))]}" in
lookup|update)
@@ -255,8 +255,9 @@ _bpftool_map_update_get_name()
_bpftool()
{
- local cur prev words objword json=0
- _init_completion || return
+ local cur prev words cword comp_args
+ local json=0
+ _init_completion -- "$@" || return
# Deal with options
if [[ ${words[cword]} == -* ]]; then
@@ -293,7 +294,7 @@ _bpftool()
esac
# Remove all options so completions don't have to deal with them.
- local i
+ local i pprev
for (( i=1; i < ${#words[@]}; )); do
if [[ ${words[i]::1} == - ]] &&
[[ ${words[i]} != "-B" ]] && [[ ${words[i]} != "--base-btf" ]]; then
@@ -307,7 +308,7 @@ _bpftool()
prev=${words[cword - 1]}
pprev=${words[cword - 2]}
- local object=${words[1]} command=${words[2]}
+ local object=${words[1]}
if [[ -z $object || $cword -eq 1 ]]; then
case $cur in
@@ -324,8 +325,12 @@ _bpftool()
esac
fi
+ local command=${words[2]}
[[ $command == help ]] && return 0
+ local MAP_TYPE='id pinned name'
+ local PROG_TYPE='id pinned tag name'
+
# Completion depends on object and command in use
case $object in
prog)
@@ -346,8 +351,6 @@ _bpftool()
;;
esac
- local PROG_TYPE='id pinned tag name'
- local MAP_TYPE='id pinned name'
local METRIC_TYPE='cycles instructions l1d_loads llc_misses \
itlb_misses dtlb_misses'
case $command in
@@ -457,7 +460,7 @@ _bpftool()
obj=${words[3]}
if [[ ${words[-4]} == "map" ]]; then
- COMPREPLY=( $( compgen -W "id pinned" -- "$cur" ) )
+ COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
return 0
fi
if [[ ${words[-3]} == "map" ]]; then
@@ -541,20 +544,9 @@ _bpftool()
COMPREPLY=( $( compgen -W "$METRIC_TYPE duration" -- "$cur" ) )
return 0
;;
- 6)
- case $prev in
- duration)
- return 0
- ;;
- *)
- COMPREPLY=( $( compgen -W "$METRIC_TYPE" -- "$cur" ) )
- return 0
- ;;
- esac
- return 0
- ;;
*)
- COMPREPLY=( $( compgen -W "$METRIC_TYPE" -- "$cur" ) )
+ [[ $prev == duration ]] && return 0
+ _bpftool_once_attr "$METRIC_TYPE"
return 0
;;
esac
@@ -612,7 +604,7 @@ _bpftool()
return 0
;;
register)
- _filedir
+ [[ $prev == $command ]] && _filedir
return 0
;;
*)
@@ -638,9 +630,12 @@ _bpftool()
pinned)
_filedir
;;
- *)
+ map)
_bpftool_one_of_list $MAP_TYPE
;;
+ *)
+ _bpftool_once_attr 'map'
+ ;;
esac
return 0
;;
@@ -652,7 +647,6 @@ _bpftool()
esac
;;
map)
- local MAP_TYPE='id pinned name'
case $command in
show|list|dump|peek|pop|dequeue|freeze)
case $prev in
@@ -793,13 +787,11 @@ _bpftool()
# map, depending on the type of the map to update.
case "$(_bpftool_map_guess_map_type)" in
array_of_maps|hash_of_maps)
- local MAP_TYPE='id pinned name'
COMPREPLY+=( $( compgen -W "$MAP_TYPE" \
-- "$cur" ) )
return 0
;;
prog_array)
- local PROG_TYPE='id pinned tag name'
COMPREPLY+=( $( compgen -W "$PROG_TYPE" \
-- "$cur" ) )
return 0
@@ -821,7 +813,7 @@ _bpftool()
esac
_bpftool_once_attr 'key'
- local UPDATE_FLAGS='any exist noexist'
+ local UPDATE_FLAGS='any exist noexist' idx
for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
if [[ ${words[idx]} == 'value' ]]; then
# 'value' is present, but is not the last
@@ -893,7 +885,6 @@ _bpftool()
esac
;;
btf)
- local PROG_TYPE='id pinned tag name'
local MAP_TYPE='id pinned name'
case $command in
dump)
@@ -939,16 +930,24 @@ _bpftool()
format)
COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) )
;;
+ root_id)
+ return 0;
+ ;;
+ c)
+ COMPREPLY=( $( compgen -W "unsorted root_id" -- "$cur" ) )
+ ;;
*)
# emit extra options
case ${words[3]} in
id|file)
+ COMPREPLY=( $( compgen -W "root_id" -- "$cur" ) )
_bpftool_once_attr 'format'
;;
map|prog)
if [[ ${words[3]} == "map" ]] && [[ $cword == 6 ]]; then
COMPREPLY+=( $( compgen -W "key value kv all" -- "$cur" ) )
fi
+ COMPREPLY=( $( compgen -W "root_id" -- "$cur" ) )
_bpftool_once_attr 'format'
;;
*)
@@ -1033,7 +1032,6 @@ _bpftool()
local BPFTOOL_CGROUP_ATTACH_TYPES="$(bpftool feature list_builtins attach_types 2>/dev/null | \
grep '^cgroup_')"
local ATTACH_FLAGS='multi override'
- local PROG_TYPE='id pinned tag name'
# Check for $prev = $command first
if [ $prev = $command ]; then
_filedir
@@ -1086,8 +1084,7 @@ _bpftool()
esac
;;
net)
- local PROG_TYPE='id pinned tag name'
- local ATTACH_TYPES='xdp xdpgeneric xdpdrv xdpoffload'
+ local ATTACH_TYPES='xdp xdpgeneric xdpdrv xdpoffload tcx_ingress tcx_egress'
case $command in
show|list)
[[ $prev != "$command" ]] && return 0
@@ -1193,14 +1190,14 @@ _bpftool()
pin|detach)
if [[ $prev == "$command" ]]; then
COMPREPLY=( $( compgen -W "$LINK_TYPE" -- "$cur" ) )
- else
+ elif [[ $pprev == "$command" ]]; then
_filedir
fi
return 0
;;
*)
[[ $prev == $object ]] && \
- COMPREPLY=( $( compgen -W 'help pin show list' -- "$cur" ) )
+ COMPREPLY=( $( compgen -W 'help pin detach show list' -- "$cur" ) )
;;
esac
;;
diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index 91fcb75babe3..2636655ac180 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -1,11 +1,15 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (C) 2019 Facebook */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
#include <errno.h>
#include <fcntl.h>
#include <linux/err.h>
#include <stdbool.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/btf.h>
@@ -20,6 +24,11 @@
#include "json_writer.h"
#include "main.h"
+#define KFUNC_DECL_TAG "bpf_kfunc"
+#define FASTCALL_DECL_TAG "bpf_fastcall"
+
+#define MAX_ROOT_IDS 16
+
static const char * const btf_kind_str[NR_BTF_KINDS] = {
[BTF_KIND_UNKN] = "UNKNOWN",
[BTF_KIND_INT] = "INT",
@@ -43,6 +52,14 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = {
[BTF_KIND_ENUM64] = "ENUM64",
};
+struct sort_datum {
+ int index;
+ int type_rank;
+ const char *sort_name;
+ const char *own_name;
+ __u64 disambig_hash;
+};
+
static const char *btf_int_enc_str(__u8 encoding)
{
switch (encoding) {
@@ -274,7 +291,7 @@ static int dump_btf_type(const struct btf *btf, __u32 id,
} else {
if (btf_kflag(t))
printf("\n\t'%s' val=%lldLL", name,
- (unsigned long long)val);
+ (long long)val);
else
printf("\n\t'%s' val=%lluULL", name,
(unsigned long long)val);
@@ -454,15 +471,307 @@ static int dump_btf_raw(const struct btf *btf,
return 0;
}
+struct ptr_array {
+ __u32 cnt;
+ __u32 cap;
+ const void **elems;
+};
+
+static int ptr_array_push(const void *ptr, struct ptr_array *arr)
+{
+ __u32 new_cap;
+ void *tmp;
+
+ if (arr->cnt == arr->cap) {
+ new_cap = (arr->cap ?: 16) * 2;
+ tmp = realloc(arr->elems, sizeof(*arr->elems) * new_cap);
+ if (!tmp)
+ return -ENOMEM;
+ arr->elems = tmp;
+ arr->cap = new_cap;
+ }
+ arr->elems[arr->cnt++] = ptr;
+ return 0;
+}
+
+static void ptr_array_free(struct ptr_array *arr)
+{
+ free(arr->elems);
+}
+
+static int cmp_kfuncs(const void *pa, const void *pb, void *ctx)
+{
+ struct btf *btf = ctx;
+ const struct btf_type *a = *(void **)pa;
+ const struct btf_type *b = *(void **)pb;
+
+ return strcmp(btf__str_by_offset(btf, a->name_off),
+ btf__str_by_offset(btf, b->name_off));
+}
+
+static int dump_btf_kfuncs(struct btf_dump *d, const struct btf *btf)
+{
+ LIBBPF_OPTS(btf_dump_emit_type_decl_opts, opts);
+ __u32 cnt = btf__type_cnt(btf), i, j;
+ struct ptr_array fastcalls = {};
+ struct ptr_array kfuncs = {};
+ int err = 0;
+
+ printf("\n/* BPF kfuncs */\n");
+ printf("#ifndef BPF_NO_KFUNC_PROTOTYPES\n");
+
+ for (i = 1; i < cnt; i++) {
+ const struct btf_type *t = btf__type_by_id(btf, i);
+ const struct btf_type *ft;
+ const char *name;
+
+ if (!btf_is_decl_tag(t))
+ continue;
+
+ if (btf_decl_tag(t)->component_idx != -1)
+ continue;
+
+ ft = btf__type_by_id(btf, t->type);
+ if (!btf_is_func(ft))
+ continue;
+
+ name = btf__name_by_offset(btf, t->name_off);
+ if (strncmp(name, KFUNC_DECL_TAG, sizeof(KFUNC_DECL_TAG)) == 0) {
+ err = ptr_array_push(ft, &kfuncs);
+ if (err)
+ goto out;
+ }
+
+ if (strncmp(name, FASTCALL_DECL_TAG, sizeof(FASTCALL_DECL_TAG)) == 0) {
+ err = ptr_array_push(ft, &fastcalls);
+ if (err)
+ goto out;
+ }
+ }
+
+ /* Sort kfuncs by name for improved vmlinux.h stability */
+ qsort_r(kfuncs.elems, kfuncs.cnt, sizeof(*kfuncs.elems), cmp_kfuncs, (void *)btf);
+ for (i = 0; i < kfuncs.cnt; i++) {
+ const struct btf_type *t = kfuncs.elems[i];
+
+ printf("extern ");
+
+ /* Assume small amount of fastcall kfuncs */
+ for (j = 0; j < fastcalls.cnt; j++) {
+ if (fastcalls.elems[j] == t) {
+ printf("__bpf_fastcall ");
+ break;
+ }
+ }
+
+ opts.field_name = btf__name_by_offset(btf, t->name_off);
+ err = btf_dump__emit_type_decl(d, t->type, &opts);
+ if (err)
+ goto out;
+
+ printf(" __weak __ksym;\n");
+ }
+
+ printf("#endif\n\n");
+
+out:
+ ptr_array_free(&fastcalls);
+ ptr_array_free(&kfuncs);
+ return err;
+}
+
static void __printf(2, 0) btf_dump_printf(void *ctx,
const char *fmt, va_list args)
{
vfprintf(stdout, fmt, args);
}
+static int btf_type_rank(const struct btf *btf, __u32 index, bool has_name)
+{
+ const struct btf_type *t = btf__type_by_id(btf, index);
+ const int kind = btf_kind(t);
+ const int max_rank = 10;
+
+ if (t->name_off)
+ has_name = true;
+
+ switch (kind) {
+ case BTF_KIND_ENUM:
+ case BTF_KIND_ENUM64:
+ return has_name ? 1 : 0;
+ case BTF_KIND_INT:
+ case BTF_KIND_FLOAT:
+ return 2;
+ case BTF_KIND_STRUCT:
+ case BTF_KIND_UNION:
+ return has_name ? 3 : max_rank;
+ case BTF_KIND_FUNC_PROTO:
+ return has_name ? 4 : max_rank;
+ case BTF_KIND_ARRAY:
+ if (has_name)
+ return btf_type_rank(btf, btf_array(t)->type, has_name);
+ return max_rank;
+ case BTF_KIND_TYPE_TAG:
+ case BTF_KIND_CONST:
+ case BTF_KIND_PTR:
+ case BTF_KIND_VOLATILE:
+ case BTF_KIND_RESTRICT:
+ case BTF_KIND_TYPEDEF:
+ case BTF_KIND_DECL_TAG:
+ if (has_name)
+ return btf_type_rank(btf, t->type, has_name);
+ return max_rank;
+ default:
+ return max_rank;
+ }
+}
+
+static const char *btf_type_sort_name(const struct btf *btf, __u32 index, bool from_ref)
+{
+ const struct btf_type *t = btf__type_by_id(btf, index);
+
+ switch (btf_kind(t)) {
+ case BTF_KIND_ENUM:
+ case BTF_KIND_ENUM64: {
+ int name_off = t->name_off;
+
+ if (!from_ref && !name_off && btf_vlen(t))
+ name_off = btf_kind(t) == BTF_KIND_ENUM64 ?
+ btf_enum64(t)->name_off :
+ btf_enum(t)->name_off;
+
+ return btf__name_by_offset(btf, name_off);
+ }
+ case BTF_KIND_ARRAY:
+ return btf_type_sort_name(btf, btf_array(t)->type, true);
+ case BTF_KIND_TYPE_TAG:
+ case BTF_KIND_CONST:
+ case BTF_KIND_PTR:
+ case BTF_KIND_VOLATILE:
+ case BTF_KIND_RESTRICT:
+ case BTF_KIND_TYPEDEF:
+ case BTF_KIND_DECL_TAG:
+ return btf_type_sort_name(btf, t->type, true);
+ default:
+ return btf__name_by_offset(btf, t->name_off);
+ }
+ return NULL;
+}
+
+static __u64 hasher(__u64 hash, __u64 val)
+{
+ return hash * 31 + val;
+}
+
+static __u64 btf_name_hasher(__u64 hash, const struct btf *btf, __u32 name_off)
+{
+ if (!name_off)
+ return hash;
+
+ return hasher(hash, str_hash(btf__name_by_offset(btf, name_off)));
+}
+
+static __u64 btf_type_disambig_hash(const struct btf *btf, __u32 id, bool include_members)
+{
+ const struct btf_type *t = btf__type_by_id(btf, id);
+ int i;
+ size_t hash = 0;
+
+ hash = btf_name_hasher(hash, btf, t->name_off);
+
+ switch (btf_kind(t)) {
+ case BTF_KIND_ENUM:
+ case BTF_KIND_ENUM64:
+ for (i = 0; i < btf_vlen(t); i++) {
+ __u32 name_off = btf_is_enum(t) ?
+ btf_enum(t)[i].name_off :
+ btf_enum64(t)[i].name_off;
+
+ hash = btf_name_hasher(hash, btf, name_off);
+ }
+ break;
+ case BTF_KIND_STRUCT:
+ case BTF_KIND_UNION:
+ if (!include_members)
+ break;
+ for (i = 0; i < btf_vlen(t); i++) {
+ const struct btf_member *m = btf_members(t) + i;
+
+ hash = btf_name_hasher(hash, btf, m->name_off);
+ /* resolve field type's name and hash it as well */
+ hash = hasher(hash, btf_type_disambig_hash(btf, m->type, false));
+ }
+ break;
+ case BTF_KIND_TYPE_TAG:
+ case BTF_KIND_CONST:
+ case BTF_KIND_PTR:
+ case BTF_KIND_VOLATILE:
+ case BTF_KIND_RESTRICT:
+ case BTF_KIND_TYPEDEF:
+ case BTF_KIND_DECL_TAG:
+ hash = hasher(hash, btf_type_disambig_hash(btf, t->type, include_members));
+ break;
+ case BTF_KIND_ARRAY: {
+ struct btf_array *arr = btf_array(t);
+
+ hash = hasher(hash, arr->nelems);
+ hash = hasher(hash, btf_type_disambig_hash(btf, arr->type, include_members));
+ break;
+ }
+ default:
+ break;
+ }
+ return hash;
+}
+
+static int btf_type_compare(const void *left, const void *right)
+{
+ const struct sort_datum *d1 = (const struct sort_datum *)left;
+ const struct sort_datum *d2 = (const struct sort_datum *)right;
+ int r;
+
+ r = d1->type_rank - d2->type_rank;
+ r = r ?: strcmp(d1->sort_name, d2->sort_name);
+ r = r ?: strcmp(d1->own_name, d2->own_name);
+ if (r)
+ return r;
+
+ if (d1->disambig_hash != d2->disambig_hash)
+ return d1->disambig_hash < d2->disambig_hash ? -1 : 1;
+
+ return d1->index - d2->index;
+}
+
+static struct sort_datum *sort_btf_c(const struct btf *btf)
+{
+ struct sort_datum *datums;
+ int n;
+
+ n = btf__type_cnt(btf);
+ datums = malloc(sizeof(struct sort_datum) * n);
+ if (!datums)
+ return NULL;
+
+ for (int i = 0; i < n; ++i) {
+ struct sort_datum *d = datums + i;
+ const struct btf_type *t = btf__type_by_id(btf, i);
+
+ d->index = i;
+ d->type_rank = btf_type_rank(btf, i, false);
+ d->sort_name = btf_type_sort_name(btf, i, false);
+ d->own_name = btf__name_by_offset(btf, t->name_off);
+ d->disambig_hash = btf_type_disambig_hash(btf, i, true);
+ }
+
+ qsort(datums, n, sizeof(struct sort_datum), btf_type_compare);
+
+ return datums;
+}
+
static int dump_btf_c(const struct btf *btf,
- __u32 *root_type_ids, int root_type_cnt)
+ __u32 *root_type_ids, int root_type_cnt, bool sort_dump)
{
+ struct sort_datum *datums = NULL;
struct btf_dump *d;
int err = 0, i;
@@ -476,6 +785,19 @@ static int dump_btf_c(const struct btf *btf,
printf("#ifndef BPF_NO_PRESERVE_ACCESS_INDEX\n");
printf("#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)\n");
printf("#endif\n\n");
+ printf("#ifndef __ksym\n");
+ printf("#define __ksym __attribute__((section(\".ksyms\")))\n");
+ printf("#endif\n\n");
+ printf("#ifndef __weak\n");
+ printf("#define __weak __attribute__((weak))\n");
+ printf("#endif\n\n");
+ printf("#ifndef __bpf_fastcall\n");
+ printf("#if __has_attribute(bpf_fastcall)\n");
+ printf("#define __bpf_fastcall __attribute__((bpf_fastcall))\n");
+ printf("#else\n");
+ printf("#define __bpf_fastcall\n");
+ printf("#endif\n");
+ printf("#endif\n\n");
if (root_type_cnt) {
for (i = 0; i < root_type_cnt; i++) {
@@ -486,11 +808,19 @@ static int dump_btf_c(const struct btf *btf,
} else {
int cnt = btf__type_cnt(btf);
+ if (sort_dump)
+ datums = sort_btf_c(btf);
for (i = 1; i < cnt; i++) {
- err = btf_dump__dump_type(d, i);
+ int idx = datums ? datums[i].index : i;
+
+ err = btf_dump__dump_type(d, idx);
if (err)
goto done;
}
+
+ err = dump_btf_kfuncs(d, btf);
+ if (err)
+ goto done;
}
printf("#ifndef BPF_NO_PRESERVE_ACCESS_INDEX\n");
@@ -500,6 +830,7 @@ static int dump_btf_c(const struct btf *btf,
printf("#endif /* __VMLINUX_H__ */\n");
done:
+ free(datums);
btf_dump__free(d);
return err;
}
@@ -549,14 +880,16 @@ static bool btf_is_kernel_module(__u32 btf_id)
static int do_dump(int argc, char **argv)
{
+ bool dump_c = false, sort_dump_c = true;
struct btf *btf = NULL, *base = NULL;
- __u32 root_type_ids[2];
+ __u32 root_type_ids[MAX_ROOT_IDS];
+ bool have_id_filtering;
int root_type_cnt = 0;
- bool dump_c = false;
__u32 btf_id = -1;
const char *src;
int fd = -1;
int err = 0;
+ int i;
if (!REQ_ARGS(2)) {
usage();
@@ -644,6 +977,8 @@ static int do_dump(int argc, char **argv)
goto done;
}
+ have_id_filtering = !!root_type_cnt;
+
while (argc) {
if (is_prefix(*argv, "format")) {
NEXT_ARG();
@@ -663,6 +998,39 @@ static int do_dump(int argc, char **argv)
goto done;
}
NEXT_ARG();
+ } else if (is_prefix(*argv, "root_id")) {
+ __u32 root_id;
+ char *end;
+
+ if (have_id_filtering) {
+ p_err("cannot use root_id with other type filtering");
+ err = -EINVAL;
+ goto done;
+ } else if (root_type_cnt == MAX_ROOT_IDS) {
+ p_err("only %d root_id are supported", MAX_ROOT_IDS);
+ err = -E2BIG;
+ goto done;
+ }
+
+ NEXT_ARG();
+ root_id = strtoul(*argv, &end, 0);
+ if (*end) {
+ err = -1;
+ p_err("can't parse %s as root ID", *argv);
+ goto done;
+ }
+ for (i = 0; i < root_type_cnt; i++) {
+ if (root_type_ids[i] == root_id) {
+ err = -EINVAL;
+ p_err("duplicate root_id %d supplied", root_id);
+ goto done;
+ }
+ }
+ root_type_ids[root_type_cnt++] = root_id;
+ NEXT_ARG();
+ } else if (is_prefix(*argv, "unsorted")) {
+ sort_dump_c = false;
+ NEXT_ARG();
} else {
p_err("unrecognized option: '%s'", *argv);
err = -EINVAL;
@@ -685,13 +1053,24 @@ static int do_dump(int argc, char **argv)
}
}
+ /* Invalid root IDs causes half emitted boilerplate and then unclean
+ * exit. It's an ugly user experience, so handle common error here.
+ */
+ for (i = 0; i < root_type_cnt; i++) {
+ if (root_type_ids[i] >= btf__type_cnt(btf)) {
+ err = -EINVAL;
+ p_err("invalid root ID: %u", root_type_ids[i]);
+ goto done;
+ }
+ }
+
if (dump_c) {
if (json_output) {
p_err("JSON output for C-syntax dump is not supported");
err = -ENOTSUP;
goto done;
}
- err = dump_btf_c(btf, root_type_ids, root_type_cnt);
+ err = dump_btf_c(btf, root_type_ids, root_type_cnt, sort_dump_c);
} else {
err = dump_btf_raw(btf, root_type_ids, root_type_cnt);
}
@@ -1059,11 +1438,11 @@ static int do_help(int argc, char **argv)
fprintf(stderr,
"Usage: %1$s %2$s { show | list } [id BTF_ID]\n"
- " %1$s %2$s dump BTF_SRC [format FORMAT]\n"
+ " %1$s %2$s dump BTF_SRC [format FORMAT] [root_id ROOT_ID]\n"
" %1$s %2$s help\n"
"\n"
" BTF_SRC := { id BTF_ID | prog PROG | map MAP [{key | value | kv | all}] | file FILE }\n"
- " FORMAT := { raw | c }\n"
+ " FORMAT := { raw | c [unsorted] }\n"
" " HELP_SPEC_MAP "\n"
" " HELP_SPEC_PROGRAM "\n"
" " HELP_SPEC_OPTIONS " |\n"
diff --git a/tools/bpf/bpftool/cfg.c b/tools/bpf/bpftool/cfg.c
index eec437cca2ea..e3785f9a697d 100644
--- a/tools/bpf/bpftool/cfg.c
+++ b/tools/bpf/bpftool/cfg.c
@@ -302,6 +302,7 @@ static bool func_add_bb_edges(struct func_node *func)
insn = bb->tail;
if (!is_jmp_insn(insn->code) ||
+ BPF_OP(insn->code) == BPF_CALL ||
BPF_OP(insn->code) == BPF_EXIT) {
e->dst = bb_next(bb);
e->flags |= EDGE_FLAG_FALLTHROUGH;
diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c
index af6898c0f388..9af426d43299 100644
--- a/tools/bpf/bpftool/cgroup.c
+++ b/tools/bpf/bpftool/cgroup.c
@@ -19,6 +19,38 @@
#include "main.h"
+static const int cgroup_attach_types[] = {
+ BPF_CGROUP_INET_INGRESS,
+ BPF_CGROUP_INET_EGRESS,
+ BPF_CGROUP_INET_SOCK_CREATE,
+ BPF_CGROUP_INET_SOCK_RELEASE,
+ BPF_CGROUP_INET4_BIND,
+ BPF_CGROUP_INET6_BIND,
+ BPF_CGROUP_INET4_POST_BIND,
+ BPF_CGROUP_INET6_POST_BIND,
+ BPF_CGROUP_INET4_CONNECT,
+ BPF_CGROUP_INET6_CONNECT,
+ BPF_CGROUP_UNIX_CONNECT,
+ BPF_CGROUP_INET4_GETPEERNAME,
+ BPF_CGROUP_INET6_GETPEERNAME,
+ BPF_CGROUP_UNIX_GETPEERNAME,
+ BPF_CGROUP_INET4_GETSOCKNAME,
+ BPF_CGROUP_INET6_GETSOCKNAME,
+ BPF_CGROUP_UNIX_GETSOCKNAME,
+ BPF_CGROUP_UDP4_SENDMSG,
+ BPF_CGROUP_UDP6_SENDMSG,
+ BPF_CGROUP_UNIX_SENDMSG,
+ BPF_CGROUP_UDP4_RECVMSG,
+ BPF_CGROUP_UDP6_RECVMSG,
+ BPF_CGROUP_UNIX_RECVMSG,
+ BPF_CGROUP_SOCK_OPS,
+ BPF_CGROUP_DEVICE,
+ BPF_CGROUP_SYSCTL,
+ BPF_CGROUP_GETSOCKOPT,
+ BPF_CGROUP_SETSOCKOPT,
+ BPF_LSM_CGROUP
+};
+
#define HELP_SPEC_ATTACH_FLAGS \
"ATTACH_FLAGS := { multi | override }"
@@ -183,13 +215,13 @@ static int count_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type)
static int cgroup_has_attached_progs(int cgroup_fd)
{
- enum bpf_attach_type type;
+ unsigned int i = 0;
bool no_prog = true;
- for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
- int count = count_attached_bpf_progs(cgroup_fd, type);
+ for (i = 0; i < ARRAY_SIZE(cgroup_attach_types); i++) {
+ int count = count_attached_bpf_progs(cgroup_fd, cgroup_attach_types[i]);
- if (count < 0 && errno != EINVAL)
+ if (count < 0)
return -1;
if (count > 0) {
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
index cc6e6aae2447..9b75639434b8 100644
--- a/tools/bpf/bpftool/common.c
+++ b/tools/bpf/bpftool/common.c
@@ -244,29 +244,101 @@ int open_obj_pinned_any(const char *path, enum bpf_obj_type exp_type)
return fd;
}
-int mount_bpffs_for_pin(const char *name, bool is_dir)
+int create_and_mount_bpffs_dir(const char *dir_name)
{
char err_str[ERR_MAX_LEN];
- char *file;
- char *dir;
+ bool dir_exists;
int err = 0;
- if (is_dir && is_bpffs(name))
+ if (is_bpffs(dir_name))
return err;
- file = malloc(strlen(name) + 1);
- if (!file) {
+ dir_exists = access(dir_name, F_OK) == 0;
+
+ if (!dir_exists) {
+ char *temp_name;
+ char *parent_name;
+
+ temp_name = strdup(dir_name);
+ if (!temp_name) {
+ p_err("mem alloc failed");
+ return -1;
+ }
+
+ parent_name = dirname(temp_name);
+
+ if (is_bpffs(parent_name)) {
+ /* nothing to do if already mounted */
+ free(temp_name);
+ return err;
+ }
+
+ if (access(parent_name, F_OK) == -1) {
+ p_err("can't create dir '%s' to pin BPF object: parent dir '%s' doesn't exist",
+ dir_name, parent_name);
+ free(temp_name);
+ return -1;
+ }
+
+ free(temp_name);
+ }
+
+ if (block_mount) {
+ p_err("no BPF file system found, not mounting it due to --nomount option");
+ return -1;
+ }
+
+ if (!dir_exists) {
+ err = mkdir(dir_name, S_IRWXU);
+ if (err) {
+ p_err("failed to create dir '%s': %s", dir_name, strerror(errno));
+ return err;
+ }
+ }
+
+ err = mnt_fs(dir_name, "bpf", err_str, ERR_MAX_LEN);
+ if (err) {
+ err_str[ERR_MAX_LEN - 1] = '\0';
+ p_err("can't mount BPF file system on given dir '%s': %s",
+ dir_name, err_str);
+
+ if (!dir_exists)
+ rmdir(dir_name);
+ }
+
+ return err;
+}
+
+int mount_bpffs_for_file(const char *file_name)
+{
+ char err_str[ERR_MAX_LEN];
+ char *temp_name;
+ char *dir;
+ int err = 0;
+
+ if (access(file_name, F_OK) != -1) {
+ p_err("can't pin BPF object: path '%s' already exists", file_name);
+ return -1;
+ }
+
+ temp_name = strdup(file_name);
+ if (!temp_name) {
p_err("mem alloc failed");
return -1;
}
- strcpy(file, name);
- dir = dirname(file);
+ dir = dirname(temp_name);
if (is_bpffs(dir))
/* nothing to do if already mounted */
goto out_free;
+ if (access(dir, F_OK) == -1) {
+ p_err("can't pin BPF object: dir '%s' doesn't exist", dir);
+ err = -1;
+ goto out_free;
+ }
+
if (block_mount) {
p_err("no BPF file system found, not mounting it due to --nomount option");
err = -1;
@@ -276,12 +348,12 @@ int mount_bpffs_for_pin(const char *name, bool is_dir)
err = mnt_fs(dir, "bpf", err_str, ERR_MAX_LEN);
if (err) {
err_str[ERR_MAX_LEN - 1] = '\0';
- p_err("can't mount BPF file system to pin the object (%s): %s",
- name, err_str);
+ p_err("can't mount BPF file system to pin the object '%s': %s",
+ file_name, err_str);
}
out_free:
- free(file);
+ free(temp_name);
return err;
}
@@ -289,7 +361,7 @@ int do_pin_fd(int fd, const char *name)
{
int err;
- err = mount_bpffs_for_pin(name, false);
+ err = mount_bpffs_for_file(name);
if (err)
return err;
@@ -338,7 +410,7 @@ void get_prog_full_name(const struct bpf_prog_info *prog_info, int prog_fd,
{
const char *prog_name = prog_info->name;
const struct btf_type *func_type;
- const struct bpf_func_info finfo = {};
+ struct bpf_func_info finfo = {};
struct bpf_prog_info info = {};
__u32 info_len = sizeof(info);
struct btf *prog_btf = NULL;
diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c
index 708733b0ea06..24fecdf8e430 100644
--- a/tools/bpf/bpftool/feature.c
+++ b/tools/bpf/bpftool/feature.c
@@ -196,7 +196,7 @@ static void probe_unprivileged_disabled(void)
{
long res;
- /* No support for C-style ouptut */
+ /* No support for C-style output */
res = read_procfs("/proc/sys/kernel/unprivileged_bpf_disabled");
if (json_output) {
@@ -225,7 +225,7 @@ static void probe_jit_enable(void)
{
long res;
- /* No support for C-style ouptut */
+ /* No support for C-style output */
res = read_procfs("/proc/sys/net/core/bpf_jit_enable");
if (json_output) {
@@ -255,7 +255,7 @@ static void probe_jit_harden(void)
{
long res;
- /* No support for C-style ouptut */
+ /* No support for C-style output */
res = read_procfs("/proc/sys/net/core/bpf_jit_harden");
if (json_output) {
@@ -285,7 +285,7 @@ static void probe_jit_kallsyms(void)
{
long res;
- /* No support for C-style ouptut */
+ /* No support for C-style output */
res = read_procfs("/proc/sys/net/core/bpf_jit_kallsyms");
if (json_output) {
@@ -311,7 +311,7 @@ static void probe_jit_limit(void)
{
long res;
- /* No support for C-style ouptut */
+ /* No support for C-style output */
res = read_procfs("/proc/sys/net/core/bpf_jit_limit");
if (json_output) {
@@ -664,7 +664,8 @@ probe_helper_ifindex(enum bpf_func_id id, enum bpf_prog_type prog_type,
probe_prog_load_ifindex(prog_type, insns, ARRAY_SIZE(insns), buf,
sizeof(buf), ifindex);
- res = !grep(buf, "invalid func ") && !grep(buf, "unknown func ");
+ res = !grep(buf, "invalid func ") && !grep(buf, "unknown func ") &&
+ !grep(buf, "program of this type cannot use helper ");
switch (get_vendor_id(ifindex)) {
case 0x19ee: /* Netronome specific */
@@ -884,6 +885,28 @@ probe_v3_isa_extension(const char *define_prefix, __u32 ifindex)
"V3_ISA_EXTENSION");
}
+/*
+ * Probe for the v4 instruction set extension introduced in commit 1f9a1ea821ff
+ * ("bpf: Support new sign-extension load insns").
+ */
+static void
+probe_v4_isa_extension(const char *define_prefix, __u32 ifindex)
+{
+ struct bpf_insn insns[5] = {
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_JMP32_IMM(BPF_JEQ, BPF_REG_0, 1, 1),
+ BPF_JMP32_A(1),
+ BPF_MOV64_IMM(BPF_REG_0, 1),
+ BPF_EXIT_INSN()
+ };
+
+ probe_misc_feature(insns, ARRAY_SIZE(insns),
+ define_prefix, ifindex,
+ "have_v4_isa_extension",
+ "ISA extension v4",
+ "V4_ISA_EXTENSION");
+}
+
static void
section_system_config(enum probe_component target, const char *define_prefix)
{
@@ -1028,6 +1051,7 @@ static void section_misc(const char *define_prefix, __u32 ifindex)
probe_bounded_loops(define_prefix, ifindex);
probe_v2_isa_extension(define_prefix, ifindex);
probe_v3_isa_extension(define_prefix, ifindex);
+ probe_v4_isa_extension(define_prefix, ifindex);
print_end_section();
}
diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c
index 540c0f2c4fda..5a4d3240689e 100644
--- a/tools/bpf/bpftool/gen.c
+++ b/tools/bpf/bpftool/gen.c
@@ -386,7 +386,7 @@ static int codegen_subskel_datasecs(struct bpf_object *obj, const char *obj_name
*/
needs_typeof = btf_is_array(var) || btf_is_ptr_to_func_proto(btf, var);
if (needs_typeof)
- printf("typeof(");
+ printf("__typeof__(");
err = btf_dump__emit_type_decl(d, var_type_id, &opts);
if (err)
@@ -848,28 +848,45 @@ out:
}
static void
-codegen_maps_skeleton(struct bpf_object *obj, size_t map_cnt, bool mmaped)
+codegen_maps_skeleton(struct bpf_object *obj, size_t map_cnt, bool mmaped, bool populate_links)
{
struct bpf_map *map;
char ident[256];
- size_t i;
+ size_t i, map_sz;
if (!map_cnt)
return;
+ /* for backward compatibility with old libbpf versions that don't
+ * handle new BPF skeleton with new struct bpf_map_skeleton definition
+ * that includes link field, avoid specifying new increased size,
+ * unless we absolutely have to (i.e., if there are struct_ops maps
+ * present)
+ */
+ map_sz = offsetof(struct bpf_map_skeleton, link);
+ if (populate_links) {
+ bpf_object__for_each_map(map, obj) {
+ if (bpf_map__type(map) == BPF_MAP_TYPE_STRUCT_OPS) {
+ map_sz = sizeof(struct bpf_map_skeleton);
+ break;
+ }
+ }
+ }
+
codegen("\
\n\
- \n\
+ \n\
/* maps */ \n\
s->map_cnt = %zu; \n\
- s->map_skel_sz = sizeof(*s->maps); \n\
- s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt, s->map_skel_sz);\n\
+ s->map_skel_sz = %zu; \n\
+ s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt,\n\
+ sizeof(*s->maps) > %zu ? sizeof(*s->maps) : %zu);\n\
if (!s->maps) { \n\
err = -ENOMEM; \n\
goto err; \n\
} \n\
",
- map_cnt
+ map_cnt, map_sz, map_sz, map_sz
);
i = 0;
bpf_object__for_each_map(map, obj) {
@@ -878,15 +895,22 @@ codegen_maps_skeleton(struct bpf_object *obj, size_t map_cnt, bool mmaped)
codegen("\
\n\
- \n\
- s->maps[%zu].name = \"%s\"; \n\
- s->maps[%zu].map = &obj->maps.%s; \n\
+ \n\
+ map = (struct bpf_map_skeleton *)((char *)s->maps + %zu * s->map_skel_sz);\n\
+ map->name = \"%s\"; \n\
+ map->map = &obj->maps.%s; \n\
",
- i, bpf_map__name(map), i, ident);
+ i, bpf_map__name(map), ident);
/* memory-mapped internal maps */
if (mmaped && is_mmapable_map(map, ident, sizeof(ident))) {
- printf("\ts->maps[%zu].mmaped = (void **)&obj->%s;\n",
- i, ident);
+ printf("\tmap->mmaped = (void **)&obj->%s;\n", ident);
+ }
+
+ if (populate_links && bpf_map__type(map) == BPF_MAP_TYPE_STRUCT_OPS) {
+ codegen("\
+ \n\
+ map->link = &obj->links.%s; \n\
+ ", ident);
}
i++;
}
@@ -1131,7 +1155,8 @@ static void gen_st_ops_shadow_init(struct btf *btf, struct bpf_object *obj)
continue;
codegen("\
\n\
- obj->struct_ops.%1$s = bpf_map__initial_value(obj->maps.%1$s, NULL);\n\
+ obj->struct_ops.%1$s = (__typeof__(obj->struct_ops.%1$s))\n\
+ bpf_map__initial_value(obj->maps.%1$s, NULL);\n\
\n\
", ident);
}
@@ -1140,7 +1165,7 @@ static void gen_st_ops_shadow_init(struct btf *btf, struct bpf_object *obj)
static int do_skeleton(int argc, char **argv)
{
char header_guard[MAX_OBJ_NAME_LEN + sizeof("__SKEL_H__")];
- size_t map_cnt = 0, prog_cnt = 0, file_sz, mmap_sz;
+ size_t map_cnt = 0, prog_cnt = 0, attach_map_cnt = 0, file_sz, mmap_sz;
DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts);
char obj_name[MAX_OBJ_NAME_LEN] = "", *obj_data;
struct bpf_object *obj = NULL;
@@ -1224,6 +1249,10 @@ static int do_skeleton(int argc, char **argv)
bpf_map__name(map));
continue;
}
+
+ if (bpf_map__type(map) == BPF_MAP_TYPE_STRUCT_OPS)
+ attach_map_cnt++;
+
map_cnt++;
}
bpf_object__for_each_program(prog, obj) {
@@ -1259,6 +1288,8 @@ static int do_skeleton(int argc, char **argv)
#include <stdlib.h> \n\
#include <bpf/libbpf.h> \n\
\n\
+ #define BPF_SKEL_SUPPORTS_MAP_AUTO_ATTACH 1 \n\
+ \n\
struct %1$s { \n\
struct bpf_object_skeleton *skeleton; \n\
struct bpf_object *obj; \n\
@@ -1296,6 +1327,9 @@ static int do_skeleton(int argc, char **argv)
bpf_program__name(prog));
}
printf("\t} progs;\n");
+ }
+
+ if (prog_cnt + attach_map_cnt) {
printf("\tstruct {\n");
bpf_object__for_each_program(prog, obj) {
if (use_loader)
@@ -1305,6 +1339,19 @@ static int do_skeleton(int argc, char **argv)
printf("\t\tstruct bpf_link *%s;\n",
bpf_program__name(prog));
}
+
+ bpf_object__for_each_map(map, obj) {
+ if (!get_map_ident(map, ident, sizeof(ident)))
+ continue;
+ if (bpf_map__type(map) != BPF_MAP_TYPE_STRUCT_OPS)
+ continue;
+
+ if (use_loader)
+ printf("t\tint %s_fd;\n", ident);
+ else
+ printf("\t\tstruct bpf_link *%s;\n", ident);
+ }
+
printf("\t} links;\n");
}
@@ -1432,6 +1479,7 @@ static int do_skeleton(int argc, char **argv)
%1$s__create_skeleton(struct %1$s *obj) \n\
{ \n\
struct bpf_object_skeleton *s; \n\
+ struct bpf_map_skeleton *map __attribute__((unused));\n\
int err; \n\
\n\
s = (struct bpf_object_skeleton *)calloc(1, sizeof(*s));\n\
@@ -1447,7 +1495,7 @@ static int do_skeleton(int argc, char **argv)
obj_name
);
- codegen_maps_skeleton(obj, map_cnt, true /*mmaped*/);
+ codegen_maps_skeleton(obj, map_cnt, true /*mmaped*/, true /*links*/);
codegen_progs_skeleton(obj, prog_cnt, true /*populate_links*/);
codegen("\
@@ -1722,6 +1770,7 @@ static int do_subskeleton(int argc, char **argv)
{ \n\
struct %1$s *obj; \n\
struct bpf_object_subskeleton *s; \n\
+ struct bpf_map_skeleton *map __attribute__((unused));\n\
int err; \n\
\n\
obj = (struct %1$s *)calloc(1, sizeof(*obj)); \n\
@@ -1785,7 +1834,7 @@ static int do_subskeleton(int argc, char **argv)
}
}
- codegen_maps_skeleton(obj, map_cnt, false /*mmaped*/);
+ codegen_maps_skeleton(obj, map_cnt, false /*mmaped*/, false /*links*/);
codegen_progs_skeleton(obj, prog_cnt, false /*links*/);
codegen("\
@@ -2378,15 +2427,6 @@ out:
return err;
}
-static int btfgen_remap_id(__u32 *type_id, void *ctx)
-{
- unsigned int *ids = ctx;
-
- *type_id = ids[*type_id];
-
- return 0;
-}
-
/* Generate BTF from relocation information previously recorded */
static struct btf *btfgen_get_btf(struct btfgen_info *info)
{
@@ -2466,10 +2506,15 @@ static struct btf *btfgen_get_btf(struct btfgen_info *info)
/* second pass: fix up type ids */
for (i = 1; i < btf__type_cnt(btf_new); i++) {
struct btf_type *btf_type = (struct btf_type *) btf__type_by_id(btf_new, i);
+ struct btf_field_iter it;
+ __u32 *type_id;
- err = btf_type_visit_type_ids(btf_type, btfgen_remap_id, ids);
+ err = btf_field_iter_init(&it, btf_type, BTF_FIELD_ITER_IDS);
if (err)
goto err_out;
+
+ while ((type_id = btf_field_iter_next(&it)))
+ *type_id = ids[*type_id];
}
free(ids);
diff --git a/tools/bpf/bpftool/iter.c b/tools/bpf/bpftool/iter.c
index 6b0e5202ca7a..5c39c2ed36a2 100644
--- a/tools/bpf/bpftool/iter.c
+++ b/tools/bpf/bpftool/iter.c
@@ -76,7 +76,7 @@ static int do_pin(int argc, char **argv)
goto close_obj;
}
- err = mount_bpffs_for_pin(path, false);
+ err = mount_bpffs_for_file(path);
if (err)
goto close_link;
diff --git a/tools/bpf/bpftool/jit_disasm.c b/tools/bpf/bpftool/jit_disasm.c
index 7b8d9ec89ebd..c032d2c6ab6d 100644
--- a/tools/bpf/bpftool/jit_disasm.c
+++ b/tools/bpf/bpftool/jit_disasm.c
@@ -80,7 +80,8 @@ symbol_lookup_callback(__maybe_unused void *disasm_info,
static int
init_context(disasm_ctx_t *ctx, const char *arch,
__maybe_unused const char *disassembler_options,
- __maybe_unused unsigned char *image, __maybe_unused ssize_t len)
+ __maybe_unused unsigned char *image, __maybe_unused ssize_t len,
+ __maybe_unused __u64 func_ksym)
{
char *triple;
@@ -109,12 +110,13 @@ static void destroy_context(disasm_ctx_t *ctx)
}
static int
-disassemble_insn(disasm_ctx_t *ctx, unsigned char *image, ssize_t len, int pc)
+disassemble_insn(disasm_ctx_t *ctx, unsigned char *image, ssize_t len, int pc,
+ __u64 func_ksym)
{
char buf[256];
int count;
- count = LLVMDisasmInstruction(*ctx, image + pc, len - pc, pc,
+ count = LLVMDisasmInstruction(*ctx, image + pc, len - pc, func_ksym + pc,
buf, sizeof(buf));
if (json_output)
printf_json(buf);
@@ -136,8 +138,21 @@ int disasm_init(void)
#ifdef HAVE_LIBBFD_SUPPORT
#define DISASM_SPACER "\t"
+struct disasm_info {
+ struct disassemble_info info;
+ __u64 func_ksym;
+};
+
+static void disasm_print_addr(bfd_vma addr, struct disassemble_info *info)
+{
+ struct disasm_info *dinfo = container_of(info, struct disasm_info, info);
+
+ addr += dinfo->func_ksym;
+ generic_print_address(addr, info);
+}
+
typedef struct {
- struct disassemble_info *info;
+ struct disasm_info *info;
disassembler_ftype disassemble;
bfd *bfdf;
} disasm_ctx_t;
@@ -215,7 +230,7 @@ static int fprintf_json_styled(void *out,
static int init_context(disasm_ctx_t *ctx, const char *arch,
const char *disassembler_options,
- unsigned char *image, ssize_t len)
+ unsigned char *image, ssize_t len, __u64 func_ksym)
{
struct disassemble_info *info;
char tpath[PATH_MAX];
@@ -238,12 +253,13 @@ static int init_context(disasm_ctx_t *ctx, const char *arch,
}
bfdf = ctx->bfdf;
- ctx->info = malloc(sizeof(struct disassemble_info));
+ ctx->info = malloc(sizeof(struct disasm_info));
if (!ctx->info) {
p_err("mem alloc failed");
goto err_close;
}
- info = ctx->info;
+ ctx->info->func_ksym = func_ksym;
+ info = &ctx->info->info;
if (json_output)
init_disassemble_info_compat(info, stdout,
@@ -272,6 +288,7 @@ static int init_context(disasm_ctx_t *ctx, const char *arch,
info->disassembler_options = disassembler_options;
info->buffer = image;
info->buffer_length = len;
+ info->print_address_func = disasm_print_addr;
disassemble_init_for_target(info);
@@ -304,9 +321,10 @@ static void destroy_context(disasm_ctx_t *ctx)
static int
disassemble_insn(disasm_ctx_t *ctx, __maybe_unused unsigned char *image,
- __maybe_unused ssize_t len, int pc)
+ __maybe_unused ssize_t len, int pc,
+ __maybe_unused __u64 func_ksym)
{
- return ctx->disassemble(pc, ctx->info);
+ return ctx->disassemble(pc, &ctx->info->info);
}
int disasm_init(void)
@@ -331,7 +349,7 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
if (!len)
return -1;
- if (init_context(&ctx, arch, disassembler_options, image, len))
+ if (init_context(&ctx, arch, disassembler_options, image, len, func_ksym))
return -1;
if (json_output)
@@ -360,7 +378,7 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
printf("%4x:" DISASM_SPACER, pc);
}
- count = disassemble_insn(&ctx, image, len, pc);
+ count = disassemble_insn(&ctx, image, len, pc, func_ksym);
if (json_output) {
/* Operand array, was started in fprintf_json. Before
diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
index afde9d0c2ea1..5cd503b763d7 100644
--- a/tools/bpf/bpftool/link.c
+++ b/tools/bpf/bpftool/link.c
@@ -526,6 +526,10 @@ static int show_link_close_json(int fd, struct bpf_link_info *info)
show_link_ifindex_json(info->netkit.ifindex, json_wtr);
show_link_attach_type_json(info->netkit.attach_type, json_wtr);
break;
+ case BPF_LINK_TYPE_SOCKMAP:
+ jsonw_uint_field(json_wtr, "map_id", info->sockmap.map_id);
+ show_link_attach_type_json(info->sockmap.attach_type, json_wtr);
+ break;
case BPF_LINK_TYPE_XDP:
show_link_ifindex_json(info->xdp.ifindex, json_wtr);
break;
@@ -915,6 +919,11 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info)
show_link_ifindex_plain(info->netkit.ifindex);
show_link_attach_type_plain(info->netkit.attach_type);
break;
+ case BPF_LINK_TYPE_SOCKMAP:
+ printf("\n\t");
+ printf("map_id %u ", info->sockmap.map_id);
+ show_link_attach_type_plain(info->sockmap.attach_type);
+ break;
case BPF_LINK_TYPE_XDP:
printf("\n\t");
show_link_ifindex_plain(info->xdp.ifindex);
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index b8bb08d10dec..9eb764fe4cc8 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -142,7 +142,8 @@ const char *get_fd_type_name(enum bpf_obj_type type);
char *get_fdinfo(int fd, const char *key);
int open_obj_pinned(const char *path, bool quiet);
int open_obj_pinned_any(const char *path, enum bpf_obj_type exp_type);
-int mount_bpffs_for_pin(const char *name, bool is_dir);
+int mount_bpffs_for_file(const char *file_name);
+int create_and_mount_bpffs_dir(const char *dir_name);
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(int *, char ***));
int do_pin_fd(int fd, const char *name);
diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c
index 968714b4c3d4..d2242d9f8441 100644
--- a/tools/bpf/bpftool/net.c
+++ b/tools/bpf/bpftool/net.c
@@ -67,6 +67,8 @@ enum net_attach_type {
NET_ATTACH_TYPE_XDP_GENERIC,
NET_ATTACH_TYPE_XDP_DRIVER,
NET_ATTACH_TYPE_XDP_OFFLOAD,
+ NET_ATTACH_TYPE_TCX_INGRESS,
+ NET_ATTACH_TYPE_TCX_EGRESS,
};
static const char * const attach_type_strings[] = {
@@ -74,6 +76,8 @@ static const char * const attach_type_strings[] = {
[NET_ATTACH_TYPE_XDP_GENERIC] = "xdpgeneric",
[NET_ATTACH_TYPE_XDP_DRIVER] = "xdpdrv",
[NET_ATTACH_TYPE_XDP_OFFLOAD] = "xdpoffload",
+ [NET_ATTACH_TYPE_TCX_INGRESS] = "tcx_ingress",
+ [NET_ATTACH_TYPE_TCX_EGRESS] = "tcx_egress",
};
static const char * const attach_loc_strings[] = {
@@ -482,9 +486,9 @@ static void __show_dev_tc_bpf(const struct ip_devname_ifindex *dev,
if (prog_flags[i] || json_output) {
NET_START_ARRAY("prog_flags", "%s ");
for (j = 0; prog_flags[i] && j < 32; j++) {
- if (!(prog_flags[i] & (1 << j)))
+ if (!(prog_flags[i] & (1U << j)))
continue;
- NET_DUMP_UINT_ONLY(1 << j);
+ NET_DUMP_UINT_ONLY(1U << j);
}
NET_END_ARRAY("");
}
@@ -493,9 +497,9 @@ static void __show_dev_tc_bpf(const struct ip_devname_ifindex *dev,
if (link_flags[i] || json_output) {
NET_START_ARRAY("link_flags", "%s ");
for (j = 0; link_flags[i] && j < 32; j++) {
- if (!(link_flags[i] & (1 << j)))
+ if (!(link_flags[i] & (1U << j)))
continue;
- NET_DUMP_UINT_ONLY(1 << j);
+ NET_DUMP_UINT_ONLY(1U << j);
}
NET_END_ARRAY("");
}
@@ -647,6 +651,32 @@ static int do_attach_detach_xdp(int progfd, enum net_attach_type attach_type,
return bpf_xdp_attach(ifindex, progfd, flags, NULL);
}
+static int get_tcx_type(enum net_attach_type attach_type)
+{
+ switch (attach_type) {
+ case NET_ATTACH_TYPE_TCX_INGRESS:
+ return BPF_TCX_INGRESS;
+ case NET_ATTACH_TYPE_TCX_EGRESS:
+ return BPF_TCX_EGRESS;
+ default:
+ return -1;
+ }
+}
+
+static int do_attach_tcx(int progfd, enum net_attach_type attach_type, int ifindex)
+{
+ int type = get_tcx_type(attach_type);
+
+ return bpf_prog_attach(progfd, ifindex, type, 0);
+}
+
+static int do_detach_tcx(int targetfd, enum net_attach_type attach_type)
+{
+ int type = get_tcx_type(attach_type);
+
+ return bpf_prog_detach(targetfd, type);
+}
+
static int do_attach(int argc, char **argv)
{
enum net_attach_type attach_type;
@@ -684,10 +714,23 @@ static int do_attach(int argc, char **argv)
}
}
+ switch (attach_type) {
/* attach xdp prog */
- if (is_prefix("xdp", attach_type_strings[attach_type]))
- err = do_attach_detach_xdp(progfd, attach_type, ifindex,
- overwrite);
+ case NET_ATTACH_TYPE_XDP:
+ case NET_ATTACH_TYPE_XDP_GENERIC:
+ case NET_ATTACH_TYPE_XDP_DRIVER:
+ case NET_ATTACH_TYPE_XDP_OFFLOAD:
+ err = do_attach_detach_xdp(progfd, attach_type, ifindex, overwrite);
+ break;
+ /* attach tcx prog */
+ case NET_ATTACH_TYPE_TCX_INGRESS:
+ case NET_ATTACH_TYPE_TCX_EGRESS:
+ err = do_attach_tcx(progfd, attach_type, ifindex);
+ break;
+ default:
+ break;
+ }
+
if (err) {
p_err("interface %s attach failed: %s",
attach_type_strings[attach_type], strerror(-err));
@@ -721,10 +764,23 @@ static int do_detach(int argc, char **argv)
if (ifindex < 1)
return -EINVAL;
+ switch (attach_type) {
/* detach xdp prog */
- progfd = -1;
- if (is_prefix("xdp", attach_type_strings[attach_type]))
+ case NET_ATTACH_TYPE_XDP:
+ case NET_ATTACH_TYPE_XDP_GENERIC:
+ case NET_ATTACH_TYPE_XDP_DRIVER:
+ case NET_ATTACH_TYPE_XDP_OFFLOAD:
+ progfd = -1;
err = do_attach_detach_xdp(progfd, attach_type, ifindex, NULL);
+ break;
+ /* detach tcx prog */
+ case NET_ATTACH_TYPE_TCX_INGRESS:
+ case NET_ATTACH_TYPE_TCX_EGRESS:
+ err = do_detach_tcx(ifindex, attach_type);
+ break;
+ default:
+ break;
+ }
if (err < 0) {
p_err("interface %s detach failed: %s",
@@ -824,6 +880,9 @@ static void show_link_netfilter(void)
nf_link_count++;
}
+ if (!nf_link_info)
+ return;
+
qsort(nf_link_info, nf_link_count, sizeof(*nf_link_info), netfilter_link_compar);
for (id = 0; id < nf_link_count; id++) {
@@ -928,7 +987,8 @@ static int do_help(int argc, char **argv)
" %1$s %2$s help\n"
"\n"
" " HELP_SPEC_PROGRAM "\n"
- " ATTACH_TYPE := { xdp | xdpgeneric | xdpdrv | xdpoffload }\n"
+ " ATTACH_TYPE := { xdp | xdpgeneric | xdpdrv | xdpoffload | tcx_ingress\n"
+ " | tcx_egress }\n"
" " HELP_SPEC_OPTIONS " }\n"
"\n"
"Note: Only xdp, tcx, tc, netkit, flow_dissector and netfilter attachments\n"
diff --git a/tools/bpf/bpftool/pids.c b/tools/bpf/bpftool/pids.c
index 00c77edb6331..23f488cf1740 100644
--- a/tools/bpf/bpftool/pids.c
+++ b/tools/bpf/bpftool/pids.c
@@ -54,6 +54,7 @@ static void add_ref(struct hashmap *map, struct pid_iter_entry *e)
ref = &refs->refs[refs->ref_cnt];
ref->pid = e->pid;
memcpy(ref->comm, e->comm, sizeof(ref->comm));
+ ref->comm[sizeof(ref->comm) - 1] = '\0';
refs->ref_cnt++;
return;
@@ -77,6 +78,7 @@ static void add_ref(struct hashmap *map, struct pid_iter_entry *e)
ref = &refs->refs[0];
ref->pid = e->pid;
memcpy(ref->comm, e->comm, sizeof(ref->comm));
+ ref->comm[sizeof(ref->comm) - 1] = '\0';
refs->ref_cnt = 1;
refs->has_bpf_cookie = e->has_bpf_cookie;
refs->bpf_cookie = e->bpf_cookie;
@@ -101,7 +103,6 @@ int build_obj_refs_table(struct hashmap **map, enum bpf_obj_type type)
char buf[4096 / sizeof(*e) * sizeof(*e)];
struct pid_iter_bpf *skel;
int err, ret, fd = -1, i;
- libbpf_print_fn_t default_print;
*map = hashmap__new(hash_fn_for_key_as_id, equal_fn_for_key_as_id, NULL);
if (IS_ERR(*map)) {
@@ -118,12 +119,18 @@ int build_obj_refs_table(struct hashmap **map, enum bpf_obj_type type)
skel->rodata->obj_type = type;
- /* we don't want output polluted with libbpf errors if bpf_iter is not
- * supported
- */
- default_print = libbpf_set_print(libbpf_print_none);
- err = pid_iter_bpf__load(skel);
- libbpf_set_print(default_print);
+ if (!verifier_logs) {
+ libbpf_print_fn_t default_print;
+
+ /* Unless debug information is on, we don't want the output to
+ * be polluted with libbpf errors if bpf_iter is not supported.
+ */
+ default_print = libbpf_set_print(libbpf_print_none);
+ err = pid_iter_bpf__load(skel);
+ libbpf_set_print(default_print);
+ } else {
+ err = pid_iter_bpf__load(skel);
+ }
if (err) {
/* too bad, kernel doesn't support BPF iterators yet */
err = 0;
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 9cb42a3366c0..e71be67f1d86 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -822,11 +822,18 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
printf("%s:\n", sym_name);
}
- if (disasm_print_insn(img, lens[i], opcodes,
- name, disasm_opt, btf,
- prog_linfo, ksyms[i], i,
- linum))
- goto exit_free;
+ if (ksyms) {
+ if (disasm_print_insn(img, lens[i], opcodes,
+ name, disasm_opt, btf,
+ prog_linfo, ksyms[i], i,
+ linum))
+ goto exit_free;
+ } else {
+ if (disasm_print_insn(img, lens[i], opcodes,
+ name, disasm_opt, btf,
+ NULL, 0, 0, false))
+ goto exit_free;
+ }
img += lens[i];
@@ -1778,7 +1785,10 @@ offload_dev:
goto err_close_obj;
}
- err = mount_bpffs_for_pin(pinfile, !first_prog_only);
+ if (first_prog_only)
+ err = mount_bpffs_for_file(pinfile);
+ else
+ err = create_and_mount_bpffs_dir(pinfile);
if (err)
goto err_close_obj;
@@ -1810,6 +1820,10 @@ offload_dev:
}
if (pinmaps) {
+ err = create_and_mount_bpffs_dir(pinmaps);
+ if (err)
+ goto err_unpin;
+
err = bpf_object__pin_maps(obj, pinmaps);
if (err) {
p_err("failed to pin all maps");
@@ -2078,7 +2092,7 @@ static int profile_parse_metrics(int argc, char **argv)
NEXT_ARG();
}
if (selected_cnt > MAX_NUM_PROFILE_METRICS) {
- p_err("too many (%d) metrics, please specify no more than %d metrics at at time",
+ p_err("too many (%d) metrics, please specify no more than %d metrics at a time",
selected_cnt, MAX_NUM_PROFILE_METRICS);
return -1;
}
@@ -2482,7 +2496,7 @@ static int do_help(int argc, char **argv)
" cgroup/connect_unix | cgroup/getpeername4 | cgroup/getpeername6 |\n"
" cgroup/getpeername_unix | cgroup/getsockname4 | cgroup/getsockname6 |\n"
" cgroup/getsockname_unix | cgroup/sendmsg4 | cgroup/sendmsg6 |\n"
- " cgroup/sendmsg°unix | cgroup/recvmsg4 | cgroup/recvmsg6 | cgroup/recvmsg_unix |\n"
+ " cgroup/sendmsg_unix | cgroup/recvmsg4 | cgroup/recvmsg6 | cgroup/recvmsg_unix |\n"
" cgroup/getsockopt | cgroup/setsockopt | cgroup/sock_release |\n"
" struct_ops | fentry | fexit | freplace | sk_lookup }\n"
" ATTACH_TYPE := { sk_msg_verdict | sk_skb_verdict | sk_skb_stream_verdict |\n"
diff --git a/tools/bpf/bpftool/skeleton/pid_iter.bpf.c b/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
index 26004f0c5a6a..948dde25034e 100644
--- a/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
+++ b/tools/bpf/bpftool/skeleton/pid_iter.bpf.c
@@ -29,6 +29,7 @@ enum bpf_link_type___local {
};
extern const void bpf_link_fops __ksym;
+extern const void bpf_link_fops_poll __ksym __weak;
extern const void bpf_map_fops __ksym;
extern const void bpf_prog_fops __ksym;
extern const void btf_fops __ksym;
@@ -84,7 +85,11 @@ int iter(struct bpf_iter__task_file *ctx)
fops = &btf_fops;
break;
case BPF_OBJ_LINK:
- fops = &bpf_link_fops;
+ if (&bpf_link_fops_poll &&
+ file->f_op == &bpf_link_fops_poll)
+ fops = &bpf_link_fops_poll;
+ else
+ fops = &bpf_link_fops;
break;
default:
return 0;
@@ -102,8 +107,8 @@ int iter(struct bpf_iter__task_file *ctx)
BPF_LINK_TYPE_PERF_EVENT___local)) {
struct bpf_link *link = (struct bpf_link *) file->private_data;
- if (link->type == bpf_core_enum_value(enum bpf_link_type___local,
- BPF_LINK_TYPE_PERF_EVENT___local)) {
+ if (BPF_CORE_READ(link, type) == bpf_core_enum_value(enum bpf_link_type___local,
+ BPF_LINK_TYPE_PERF_EVENT___local)) {
e.has_bpf_cookie = true;
e.bpf_cookie = get_bpf_cookie(link);
}
diff --git a/tools/bpf/bpftool/skeleton/profiler.bpf.c b/tools/bpf/bpftool/skeleton/profiler.bpf.c
index 2f80edc682f1..f48c783cb9f7 100644
--- a/tools/bpf/bpftool/skeleton/profiler.bpf.c
+++ b/tools/bpf/bpftool/skeleton/profiler.bpf.c
@@ -40,17 +40,17 @@ struct {
const volatile __u32 num_cpu = 1;
const volatile __u32 num_metric = 1;
-#define MAX_NUM_MATRICS 4
+#define MAX_NUM_METRICS 4
SEC("fentry/XXX")
int BPF_PROG(fentry_XXX)
{
- struct bpf_perf_event_value___local *ptrs[MAX_NUM_MATRICS];
+ struct bpf_perf_event_value___local *ptrs[MAX_NUM_METRICS];
u32 key = bpf_get_smp_processor_id();
u32 i;
/* look up before reading, to reduce error */
- for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) {
+ for (i = 0; i < num_metric && i < MAX_NUM_METRICS; i++) {
u32 flag = i;
ptrs[i] = bpf_map_lookup_elem(&fentry_readings, &flag);
@@ -58,7 +58,7 @@ int BPF_PROG(fentry_XXX)
return 0;
}
- for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) {
+ for (i = 0; i < num_metric && i < MAX_NUM_METRICS; i++) {
struct bpf_perf_event_value___local reading;
int err;
@@ -99,14 +99,14 @@ fexit_update_maps(u32 id, struct bpf_perf_event_value___local *after)
SEC("fexit/XXX")
int BPF_PROG(fexit_XXX)
{
- struct bpf_perf_event_value___local readings[MAX_NUM_MATRICS];
+ struct bpf_perf_event_value___local readings[MAX_NUM_METRICS];
u32 cpu = bpf_get_smp_processor_id();
u32 i, zero = 0;
int err;
u64 *count;
/* read all events before updating the maps, to reduce error */
- for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) {
+ for (i = 0; i < num_metric && i < MAX_NUM_METRICS; i++) {
err = bpf_perf_event_read_value(&events, cpu + i * num_cpu,
(void *)(readings + i),
sizeof(*readings));
@@ -116,7 +116,7 @@ int BPF_PROG(fexit_XXX)
count = bpf_map_lookup_elem(&counts, &zero);
if (count) {
*count += 1;
- for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++)
+ for (i = 0; i < num_metric && i < MAX_NUM_METRICS; i++)
fexit_update_maps(i, &readings[i]);
}
return 0;
diff --git a/tools/bpf/bpftool/struct_ops.c b/tools/bpf/bpftool/struct_ops.c
index d573f2640d8e..aa43dead249c 100644
--- a/tools/bpf/bpftool/struct_ops.c
+++ b/tools/bpf/bpftool/struct_ops.c
@@ -515,7 +515,7 @@ static int do_register(int argc, char **argv)
if (argc == 1)
linkdir = GET_ARG();
- if (linkdir && mount_bpffs_for_pin(linkdir, true)) {
+ if (linkdir && create_and_mount_bpffs_dir(linkdir)) {
p_err("can't mount bpffs for pinning");
return -1;
}
diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c
index 567f56dfd9f1..d0094345fb2b 100644
--- a/tools/bpf/bpftool/xlated_dumper.c
+++ b/tools/bpf/bpftool/xlated_dumper.c
@@ -349,7 +349,7 @@ void dump_xlated_plain(struct dump_data *dd, void *buf, unsigned int len,
double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW);
- printf("% 4d: ", i);
+ printf("%4u: ", i);
print_bpf_insn(&cbs, insn + i, true);
if (opcodes) {
@@ -415,7 +415,7 @@ void dump_xlated_for_graph(struct dump_data *dd, void *buf_start, void *buf_end,
}
}
- printf("%d: ", insn_off);
+ printf("%u: ", insn_off);
print_bpf_insn(&cbs, cur, true);
if (opcodes) {
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index d9520cb826b3..d47191c6e55e 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -141,6 +141,7 @@ struct object {
};
static int verbose;
+static int warnings;
static int eprintf(int level, int var, const char *fmt, ...)
{
@@ -409,6 +410,14 @@ static int elf_collect(struct object *obj)
obj->efile.idlist = data;
obj->efile.idlist_shndx = idx;
obj->efile.idlist_addr = sh.sh_addr;
+ } else if (!strcmp(name, BTF_BASE_ELF_SEC)) {
+ /* If a .BTF.base section is found, do not resolve
+ * BTF ids relative to vmlinux; resolve relative
+ * to the .BTF.base section instead. btf__parse_split()
+ * will take care of this once the base BTF it is
+ * passed is NULL.
+ */
+ obj->base_btf_path = NULL;
}
if (compressed_section_fix(elf, scn, &sh))
@@ -596,6 +605,7 @@ static int symbols_resolve(struct object *obj)
if (id->id) {
pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
str, id->id, type_id, id->id);
+ warnings++;
} else {
id->id = type_id;
(*nr)--;
@@ -617,8 +627,10 @@ static int id_patch(struct object *obj, struct btf_id *id)
int i;
/* For set, set8, id->id may be 0 */
- if (!id->id && !id->is_set && !id->is_set8)
+ if (!id->id && !id->is_set && !id->is_set8) {
pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
+ warnings++;
+ }
for (i = 0; i < id->addr_cnt; i++) {
unsigned long addr = id->addr[i];
@@ -671,8 +683,8 @@ static int sets_patch(struct object *obj)
next = rb_first(&obj->sets);
while (next) {
- struct btf_id_set8 *set8;
- struct btf_id_set *set;
+ struct btf_id_set8 *set8 = NULL;
+ struct btf_id_set *set = NULL;
unsigned long addr, off;
struct btf_id *id;
@@ -696,7 +708,7 @@ static int sets_patch(struct object *obj)
* Make sure id is at the beginning of the pairs
* struct, otherwise the below qsort would not work.
*/
- BUILD_BUG_ON(set8->pairs != &set8->pairs[0].id);
+ BUILD_BUG_ON((u32 *)set8->pairs != &set8->pairs[0].id);
qsort(set8->pairs, set8->cnt, sizeof(set8->pairs[0]), cmp_id);
/*
@@ -728,7 +740,7 @@ static int sets_patch(struct object *obj)
static int symbols_patch(struct object *obj)
{
- int err;
+ off_t err;
if (__symbols_patch(obj, &obj->structs) ||
__symbols_patch(obj, &obj->unions) ||
@@ -774,6 +786,7 @@ int main(int argc, const char **argv)
.funcs = RB_ROOT,
.sets = RB_ROOT,
};
+ bool fatal_warnings = false;
struct option btfid_options[] = {
OPT_INCR('v', "verbose", &verbose,
"be more verbose (show errors, etc)"),
@@ -781,6 +794,8 @@ int main(int argc, const char **argv)
"BTF data"),
OPT_STRING('b', "btf_base", &obj.base_btf_path, "file",
"path of file providing base BTF"),
+ OPT_BOOLEAN(0, "fatal_warnings", &fatal_warnings,
+ "turn warnings into errors"),
OPT_END()
};
int err = -1;
@@ -815,7 +830,8 @@ int main(int argc, const char **argv)
if (symbols_patch(&obj))
goto out;
- err = 0;
+ if (!(fatal_warnings && warnings))
+ err = 0;
out:
if (obj.efile.elf) {
elf_end(obj.efile.elf);
diff --git a/tools/bpf/runqslower/Makefile b/tools/bpf/runqslower/Makefile
index d8288936c912..c4f1f1735af6 100644
--- a/tools/bpf/runqslower/Makefile
+++ b/tools/bpf/runqslower/Makefile
@@ -15,6 +15,7 @@ INCLUDES := -I$(OUTPUT) -I$(BPF_INCLUDE) -I$(abspath ../../include/uapi)
CFLAGS := -g -Wall $(CLANG_CROSS_FLAGS)
CFLAGS += $(EXTRA_CFLAGS)
LDFLAGS += $(EXTRA_LDFLAGS)
+LDLIBS += -lelf -lz
# Try to detect best kernel BTF source
KERNEL_REL := $(shell uname -r)
@@ -51,7 +52,7 @@ clean:
libbpf_hdrs: $(BPFOBJ)
$(OUTPUT)/runqslower: $(OUTPUT)/runqslower.o $(BPFOBJ)
- $(QUIET_LINK)$(CC) $(CFLAGS) $^ -lelf -lz -o $@
+ $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(OUTPUT)/runqslower.o: runqslower.h $(OUTPUT)/runqslower.skel.h \
$(OUTPUT)/runqslower.bpf.o | libbpf_hdrs
diff --git a/tools/bpf/runqslower/runqslower.bpf.c b/tools/bpf/runqslower/runqslower.bpf.c
index 9a5c1f008fe6..fced54a3adf6 100644
--- a/tools/bpf/runqslower/runqslower.bpf.c
+++ b/tools/bpf/runqslower/runqslower.bpf.c
@@ -70,7 +70,6 @@ int handle__sched_switch(u64 *ctx)
struct task_struct *next = (struct task_struct *)ctx[2];
struct runq_event event = {};
u64 *tsp, delta_us;
- long state;
u32 pid;
/* ivcsw: treat like an enqueue event and store timestamp */