Skip to content

Commit b7d3826

Browse files
jrfastabAlexei Starovoitov
authored andcommitted
bpf: bpftool, add support for attaching programs to maps
Sock map/hash introduce support for attaching programs to maps. To date I have been doing this with custom tooling but this is less than ideal as we shift to using bpftool as the single CLI for our BPF uses. This patch adds new sub commands 'attach' and 'detach' to the 'prog' command to attach programs to maps and then detach them. Signed-off-by: John Fastabend <john.fastabend@gmail.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 7d1f12b commit b7d3826

File tree

4 files changed

+128
-3
lines changed

4 files changed

+128
-3
lines changed

tools/bpf/bpftool/Documentation/bpftool-prog.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ MAP COMMANDS
2525
| **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}]
2626
| **bpftool** **prog pin** *PROG* *FILE*
2727
| **bpftool** **prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*]
28+
| **bpftool** **prog attach** *PROG* *ATTACH_TYPE* *MAP*
29+
| **bpftool** **prog detach** *PROG* *ATTACH_TYPE* *MAP*
2830
| **bpftool** **prog help**
2931
|
3032
| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
@@ -37,6 +39,7 @@ MAP COMMANDS
3739
| **cgroup/bind4** | **cgroup/bind6** | **cgroup/post_bind4** | **cgroup/post_bind6** |
3840
| **cgroup/connect4** | **cgroup/connect6** | **cgroup/sendmsg4** | **cgroup/sendmsg6**
3941
| }
42+
| *ATTACH_TYPE* := { **msg_verdict** | **skb_verdict** | **skb_parse** }
4043
4144

4245
DESCRIPTION
@@ -90,6 +93,14 @@ DESCRIPTION
9093

9194
Note: *FILE* must be located in *bpffs* mount.
9295

96+
**bpftool prog attach** *PROG* *ATTACH_TYPE* *MAP*
97+
Attach bpf program *PROG* (with type specified by *ATTACH_TYPE*)
98+
to the map *MAP*.
99+
100+
**bpftool prog detach** *PROG* *ATTACH_TYPE* *MAP*
101+
Detach bpf program *PROG* (with type specified by *ATTACH_TYPE*)
102+
from the map *MAP*.
103+
93104
**bpftool prog help**
94105
Print short help message.
95106

tools/bpf/bpftool/Documentation/bpftool.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ SYNOPSIS
2626
| **pin** | **event_pipe** | **help** }
2727
2828
*PROG-COMMANDS* := { **show** | **list** | **dump jited** | **dump xlated** | **pin**
29-
| **load** | **help** }
29+
| **load** | **attach** | **detach** | **help** }
3030
3131
*CGROUP-COMMANDS* := { **show** | **list** | **attach** | **detach** | **help** }
3232

tools/bpf/bpftool/bash-completion/bpftool

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,23 @@ _bpftool()
292292
fi
293293
return 0
294294
;;
295+
attach|detach)
296+
if [[ ${#words[@]} == 7 ]]; then
297+
COMPREPLY=( $( compgen -W "id pinned" -- "$cur" ) )
298+
return 0
299+
fi
300+
301+
if [[ ${#words[@]} == 6 ]]; then
302+
COMPREPLY=( $( compgen -W "msg_verdict skb_verdict skb_parse" -- "$cur" ) )
303+
return 0
304+
fi
305+
306+
if [[ $prev == "$command" ]]; then
307+
COMPREPLY=( $( compgen -W "id pinned" -- "$cur" ) )
308+
return 0
309+
fi
310+
return 0
311+
;;
295312
load)
296313
local obj
297314

@@ -347,7 +364,7 @@ _bpftool()
347364
;;
348365
*)
349366
[[ $prev == $object ]] && \
350-
COMPREPLY=( $( compgen -W 'dump help pin load \
367+
COMPREPLY=( $( compgen -W 'dump help pin attach detach load \
351368
show list' -- "$cur" ) )
352369
;;
353370
esac

tools/bpf/bpftool/prog.c

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,26 @@ static const char * const prog_type_name[] = {
7777
[BPF_PROG_TYPE_FLOW_DISSECTOR] = "flow_dissector",
7878
};
7979

80+
static const char * const attach_type_strings[] = {
81+
[BPF_SK_SKB_STREAM_PARSER] = "stream_parser",
82+
[BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict",
83+
[BPF_SK_MSG_VERDICT] = "msg_verdict",
84+
[__MAX_BPF_ATTACH_TYPE] = NULL,
85+
};
86+
87+
enum bpf_attach_type parse_attach_type(const char *str)
88+
{
89+
enum bpf_attach_type type;
90+
91+
for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
92+
if (attach_type_strings[type] &&
93+
is_prefix(str, attach_type_strings[type]))
94+
return type;
95+
}
96+
97+
return __MAX_BPF_ATTACH_TYPE;
98+
}
99+
80100
static void print_boot_time(__u64 nsecs, char *buf, unsigned int size)
81101
{
82102
struct timespec real_time_ts, boot_time_ts;
@@ -697,6 +717,77 @@ int map_replace_compar(const void *p1, const void *p2)
697717
return a->idx - b->idx;
698718
}
699719

720+
static int do_attach(int argc, char **argv)
721+
{
722+
enum bpf_attach_type attach_type;
723+
int err, mapfd, progfd;
724+
725+
if (!REQ_ARGS(5)) {
726+
p_err("too few parameters for map attach");
727+
return -EINVAL;
728+
}
729+
730+
progfd = prog_parse_fd(&argc, &argv);
731+
if (progfd < 0)
732+
return progfd;
733+
734+
attach_type = parse_attach_type(*argv);
735+
if (attach_type == __MAX_BPF_ATTACH_TYPE) {
736+
p_err("invalid attach type");
737+
return -EINVAL;
738+
}
739+
NEXT_ARG();
740+
741+
mapfd = map_parse_fd(&argc, &argv);
742+
if (mapfd < 0)
743+
return mapfd;
744+
745+
err = bpf_prog_attach(progfd, mapfd, attach_type, 0);
746+
if (err) {
747+
p_err("failed prog attach to map");
748+
return -EINVAL;
749+
}
750+
751+
if (json_output)
752+
jsonw_null(json_wtr);
753+
return 0;
754+
}
755+
756+
static int do_detach(int argc, char **argv)
757+
{
758+
enum bpf_attach_type attach_type;
759+
int err, mapfd, progfd;
760+
761+
if (!REQ_ARGS(5)) {
762+
p_err("too few parameters for map detach");
763+
return -EINVAL;
764+
}
765+
766+
progfd = prog_parse_fd(&argc, &argv);
767+
if (progfd < 0)
768+
return progfd;
769+
770+
attach_type = parse_attach_type(*argv);
771+
if (attach_type == __MAX_BPF_ATTACH_TYPE) {
772+
p_err("invalid attach type");
773+
return -EINVAL;
774+
}
775+
NEXT_ARG();
776+
777+
mapfd = map_parse_fd(&argc, &argv);
778+
if (mapfd < 0)
779+
return mapfd;
780+
781+
err = bpf_prog_detach2(progfd, mapfd, attach_type);
782+
if (err) {
783+
p_err("failed prog detach from map");
784+
return -EINVAL;
785+
}
786+
787+
if (json_output)
788+
jsonw_null(json_wtr);
789+
return 0;
790+
}
700791
static int do_load(int argc, char **argv)
701792
{
702793
enum bpf_attach_type expected_attach_type;
@@ -942,6 +1033,8 @@ static int do_help(int argc, char **argv)
9421033
" %s %s pin PROG FILE\n"
9431034
" %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n"
9441035
" [map { idx IDX | name NAME } MAP]\n"
1036+
" %s %s attach PROG ATTACH_TYPE MAP\n"
1037+
" %s %s detach PROG ATTACH_TYPE MAP\n"
9451038
" %s %s help\n"
9461039
"\n"
9471040
" " HELP_SPEC_MAP "\n"
@@ -953,10 +1046,12 @@ static int do_help(int argc, char **argv)
9531046
" cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n"
9541047
" cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n"
9551048
" cgroup/sendmsg4 | cgroup/sendmsg6 }\n"
1049+
" ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse }\n"
9561050
" " HELP_SPEC_OPTIONS "\n"
9571051
"",
9581052
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
959-
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]);
1053+
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
1054+
bin_name, argv[-2], bin_name, argv[-2]);
9601055

9611056
return 0;
9621057
}
@@ -968,6 +1063,8 @@ static const struct cmd cmds[] = {
9681063
{ "dump", do_dump },
9691064
{ "pin", do_pin },
9701065
{ "load", do_load },
1066+
{ "attach", do_attach },
1067+
{ "detach", do_detach },
9711068
{ 0 }
9721069
};
9731070

0 commit comments

Comments
 (0)