bpftool: support loading flow dissector
This commit adds support for loading/attaching/detaching flow dissector program. When `bpftool loadall` is called with a flow_dissector prog (i.e. when the 'type flow_dissector' argument is passed), we load and pin all programs. User is responsible to construct the jump table for the tail calls. The last argument of `bpftool attach` is made optional for this use case. Example: bpftool prog load tools/testing/selftests/bpf/bpf_flow.o \ /sys/fs/bpf/flow type flow_dissector \ pinmaps /sys/fs/bpf/flow bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 0 0 0 0 \ value pinned /sys/fs/bpf/flow/IP bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 1 0 0 0 \ value pinned /sys/fs/bpf/flow/IPV6 bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 2 0 0 0 \ value pinned /sys/fs/bpf/flow/IPV6OP bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 3 0 0 0 \ value pinned /sys/fs/bpf/flow/IPV6FR bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 4 0 0 0 \ value pinned /sys/fs/bpf/flow/MPLS bpftool map update pinned /sys/fs/bpf/flow/jmp_table \ key 5 0 0 0 \ value pinned /sys/fs/bpf/flow/VLAN bpftool prog attach pinned /sys/fs/bpf/flow/flow_dissector flow_dissector Tested by using the above lines to load the prog in the test_flow_dissector.sh selftest. Signed-off-by: Stanislav Fomichev <sdf@google.com> Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
3767a94b32
commit
092f089273
@ -26,8 +26,8 @@ MAP COMMANDS
|
||||
| **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}]
|
||||
| **bpftool** **prog pin** *PROG* *FILE*
|
||||
| **bpftool** **prog { load | loadall }** *OBJ* *PATH* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*]
|
||||
| **bpftool** **prog attach** *PROG* *ATTACH_TYPE* *MAP*
|
||||
| **bpftool** **prog detach** *PROG* *ATTACH_TYPE* *MAP*
|
||||
| **bpftool** **prog attach** *PROG* *ATTACH_TYPE* [*MAP*]
|
||||
| **bpftool** **prog detach** *PROG* *ATTACH_TYPE* [*MAP*]
|
||||
| **bpftool** **prog help**
|
||||
|
|
||||
| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
|
||||
@ -40,7 +40,9 @@ MAP COMMANDS
|
||||
| **cgroup/bind4** | **cgroup/bind6** | **cgroup/post_bind4** | **cgroup/post_bind6** |
|
||||
| **cgroup/connect4** | **cgroup/connect6** | **cgroup/sendmsg4** | **cgroup/sendmsg6**
|
||||
| }
|
||||
| *ATTACH_TYPE* := { **msg_verdict** | **skb_verdict** | **skb_parse** }
|
||||
| *ATTACH_TYPE* := {
|
||||
| **msg_verdict** | **skb_verdict** | **skb_parse** | **flow_dissector**
|
||||
| }
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
@ -103,13 +105,17 @@ DESCRIPTION
|
||||
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*)
|
||||
to the map *MAP*.
|
||||
**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*)
|
||||
from the map *MAP*.
|
||||
**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 help**
|
||||
Print short help message.
|
||||
|
@ -299,7 +299,8 @@ _bpftool()
|
||||
fi
|
||||
|
||||
if [[ ${#words[@]} == 6 ]]; then
|
||||
COMPREPLY=( $( compgen -W "msg_verdict skb_verdict skb_parse" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "msg_verdict skb_verdict \
|
||||
skb_parse flow_dissector" -- "$cur" ) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
@ -338,7 +339,16 @@ _bpftool()
|
||||
|
||||
case $prev in
|
||||
type)
|
||||
COMPREPLY=( $( compgen -W "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/connect4 cgroup/connect6 cgroup/sendmsg4 cgroup/sendmsg6 cgroup/post_bind4 cgroup/post_bind6" -- \
|
||||
COMPREPLY=( $( compgen -W "socket kprobe \
|
||||
kretprobe classifier flow_dissector \
|
||||
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/connect4 cgroup/connect6 \
|
||||
cgroup/sendmsg4 cgroup/sendmsg6 \
|
||||
cgroup/post_bind4 cgroup/post_bind6" -- \
|
||||
"$cur" ) )
|
||||
return 0
|
||||
;;
|
||||
|
@ -81,6 +81,7 @@ static const char * const attach_type_strings[] = {
|
||||
[BPF_SK_SKB_STREAM_PARSER] = "stream_parser",
|
||||
[BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict",
|
||||
[BPF_SK_MSG_VERDICT] = "msg_verdict",
|
||||
[BPF_FLOW_DISSECTOR] = "flow_dissector",
|
||||
[__MAX_BPF_ATTACH_TYPE] = NULL,
|
||||
};
|
||||
|
||||
@ -721,30 +722,49 @@ int map_replace_compar(const void *p1, const void *p2)
|
||||
return a->idx - b->idx;
|
||||
}
|
||||
|
||||
static int parse_attach_detach_args(int argc, char **argv, int *progfd,
|
||||
enum bpf_attach_type *attach_type,
|
||||
int *mapfd)
|
||||
{
|
||||
if (!REQ_ARGS(3))
|
||||
return -EINVAL;
|
||||
|
||||
*progfd = prog_parse_fd(&argc, &argv);
|
||||
if (*progfd < 0)
|
||||
return *progfd;
|
||||
|
||||
*attach_type = parse_attach_type(*argv);
|
||||
if (*attach_type == __MAX_BPF_ATTACH_TYPE) {
|
||||
p_err("invalid attach/detach type");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (*attach_type == BPF_FLOW_DISSECTOR) {
|
||||
*mapfd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NEXT_ARG();
|
||||
if (!REQ_ARGS(2))
|
||||
return -EINVAL;
|
||||
|
||||
*mapfd = map_parse_fd(&argc, &argv);
|
||||
if (*mapfd < 0)
|
||||
return *mapfd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_attach(int argc, char **argv)
|
||||
{
|
||||
enum bpf_attach_type attach_type;
|
||||
int err, mapfd, progfd;
|
||||
int err, progfd;
|
||||
int mapfd;
|
||||
|
||||
if (!REQ_ARGS(5)) {
|
||||
p_err("too few parameters for map attach");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
progfd = prog_parse_fd(&argc, &argv);
|
||||
if (progfd < 0)
|
||||
return progfd;
|
||||
|
||||
attach_type = parse_attach_type(*argv);
|
||||
if (attach_type == __MAX_BPF_ATTACH_TYPE) {
|
||||
p_err("invalid attach type");
|
||||
return -EINVAL;
|
||||
}
|
||||
NEXT_ARG();
|
||||
|
||||
mapfd = map_parse_fd(&argc, &argv);
|
||||
if (mapfd < 0)
|
||||
return mapfd;
|
||||
err = parse_attach_detach_args(argc, argv,
|
||||
&progfd, &attach_type, &mapfd);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = bpf_prog_attach(progfd, mapfd, attach_type, 0);
|
||||
if (err) {
|
||||
@ -760,27 +780,13 @@ static int do_attach(int argc, char **argv)
|
||||
static int do_detach(int argc, char **argv)
|
||||
{
|
||||
enum bpf_attach_type attach_type;
|
||||
int err, mapfd, progfd;
|
||||
int err, progfd;
|
||||
int mapfd;
|
||||
|
||||
if (!REQ_ARGS(5)) {
|
||||
p_err("too few parameters for map detach");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
progfd = prog_parse_fd(&argc, &argv);
|
||||
if (progfd < 0)
|
||||
return progfd;
|
||||
|
||||
attach_type = parse_attach_type(*argv);
|
||||
if (attach_type == __MAX_BPF_ATTACH_TYPE) {
|
||||
p_err("invalid attach type");
|
||||
return -EINVAL;
|
||||
}
|
||||
NEXT_ARG();
|
||||
|
||||
mapfd = map_parse_fd(&argc, &argv);
|
||||
if (mapfd < 0)
|
||||
return mapfd;
|
||||
err = parse_attach_detach_args(argc, argv,
|
||||
&progfd, &attach_type, &mapfd);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = bpf_prog_detach2(progfd, mapfd, attach_type);
|
||||
if (err) {
|
||||
@ -1094,8 +1100,8 @@ static int do_help(int argc, char **argv)
|
||||
" [type TYPE] [dev NAME] \\\n"
|
||||
" [map { idx IDX | name NAME } MAP]\\\n"
|
||||
" [pinmaps MAP_DIR]\n"
|
||||
" %s %s attach PROG ATTACH_TYPE MAP\n"
|
||||
" %s %s detach PROG ATTACH_TYPE MAP\n"
|
||||
" %s %s attach PROG ATTACH_TYPE [MAP]\n"
|
||||
" %s %s detach PROG ATTACH_TYPE [MAP]\n"
|
||||
" %s %s help\n"
|
||||
"\n"
|
||||
" " HELP_SPEC_MAP "\n"
|
||||
@ -1107,7 +1113,8 @@ static int do_help(int argc, char **argv)
|
||||
" cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n"
|
||||
" cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n"
|
||||
" cgroup/sendmsg4 | cgroup/sendmsg6 }\n"
|
||||
" ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse }\n"
|
||||
" ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse |\n"
|
||||
" flow_dissector }\n"
|
||||
" " HELP_SPEC_OPTIONS "\n"
|
||||
"",
|
||||
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
|
||||
|
Loading…
Reference in New Issue
Block a user