diff options
author | Stanislav Fomichev <sdf@google.com> | 2018-11-09 11:21:46 -0500 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2018-11-10 18:56:11 -0500 |
commit | 092f08927300086b6520dfa3aa4d9450266f27ae (patch) | |
tree | 62b5e46802857fc60f2b945d0a1c08544ca95865 /tools/bpf/bpftool/prog.c | |
parent | 3767a94b3253fc8c3df96913d7dec796619161c7 (diff) |
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>
Diffstat (limited to 'tools/bpf/bpftool/prog.c')
-rw-r--r-- | tools/bpf/bpftool/prog.c | 85 |
1 files changed, 46 insertions, 39 deletions
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index c2ce4220bbca..5ff5544596e7 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c | |||
@@ -81,6 +81,7 @@ static const char * const attach_type_strings[] = { | |||
81 | [BPF_SK_SKB_STREAM_PARSER] = "stream_parser", | 81 | [BPF_SK_SKB_STREAM_PARSER] = "stream_parser", |
82 | [BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict", | 82 | [BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict", |
83 | [BPF_SK_MSG_VERDICT] = "msg_verdict", | 83 | [BPF_SK_MSG_VERDICT] = "msg_verdict", |
84 | [BPF_FLOW_DISSECTOR] = "flow_dissector", | ||
84 | [__MAX_BPF_ATTACH_TYPE] = NULL, | 85 | [__MAX_BPF_ATTACH_TYPE] = NULL, |
85 | }; | 86 | }; |
86 | 87 | ||
@@ -721,30 +722,49 @@ int map_replace_compar(const void *p1, const void *p2) | |||
721 | return a->idx - b->idx; | 722 | return a->idx - b->idx; |
722 | } | 723 | } |
723 | 724 | ||
724 | static int do_attach(int argc, char **argv) | 725 | static int parse_attach_detach_args(int argc, char **argv, int *progfd, |
726 | enum bpf_attach_type *attach_type, | ||
727 | int *mapfd) | ||
725 | { | 728 | { |
726 | enum bpf_attach_type attach_type; | 729 | if (!REQ_ARGS(3)) |
727 | int err, mapfd, progfd; | ||
728 | |||
729 | if (!REQ_ARGS(5)) { | ||
730 | p_err("too few parameters for map attach"); | ||
731 | return -EINVAL; | 730 | return -EINVAL; |
732 | } | ||
733 | 731 | ||
734 | progfd = prog_parse_fd(&argc, &argv); | 732 | *progfd = prog_parse_fd(&argc, &argv); |
735 | if (progfd < 0) | 733 | if (*progfd < 0) |
736 | return progfd; | 734 | return *progfd; |
737 | 735 | ||
738 | attach_type = parse_attach_type(*argv); | 736 | *attach_type = parse_attach_type(*argv); |
739 | if (attach_type == __MAX_BPF_ATTACH_TYPE) { | 737 | if (*attach_type == __MAX_BPF_ATTACH_TYPE) { |
740 | p_err("invalid attach type"); | 738 | p_err("invalid attach/detach type"); |
741 | return -EINVAL; | 739 | return -EINVAL; |
742 | } | 740 | } |
741 | |||
742 | if (*attach_type == BPF_FLOW_DISSECTOR) { | ||
743 | *mapfd = -1; | ||
744 | return 0; | ||
745 | } | ||
746 | |||
743 | NEXT_ARG(); | 747 | NEXT_ARG(); |
748 | if (!REQ_ARGS(2)) | ||
749 | return -EINVAL; | ||
750 | |||
751 | *mapfd = map_parse_fd(&argc, &argv); | ||
752 | if (*mapfd < 0) | ||
753 | return *mapfd; | ||
754 | |||
755 | return 0; | ||
756 | } | ||
744 | 757 | ||
745 | mapfd = map_parse_fd(&argc, &argv); | 758 | static int do_attach(int argc, char **argv) |
746 | if (mapfd < 0) | 759 | { |
747 | return mapfd; | 760 | enum bpf_attach_type attach_type; |
761 | int err, progfd; | ||
762 | int mapfd; | ||
763 | |||
764 | err = parse_attach_detach_args(argc, argv, | ||
765 | &progfd, &attach_type, &mapfd); | ||
766 | if (err) | ||
767 | return err; | ||
748 | 768 | ||
749 | err = bpf_prog_attach(progfd, mapfd, attach_type, 0); | 769 | err = bpf_prog_attach(progfd, mapfd, attach_type, 0); |
750 | if (err) { | 770 | if (err) { |
@@ -760,27 +780,13 @@ static int do_attach(int argc, char **argv) | |||
760 | static int do_detach(int argc, char **argv) | 780 | static int do_detach(int argc, char **argv) |
761 | { | 781 | { |
762 | enum bpf_attach_type attach_type; | 782 | enum bpf_attach_type attach_type; |
763 | int err, mapfd, progfd; | 783 | int err, progfd; |
764 | 784 | int mapfd; | |
765 | if (!REQ_ARGS(5)) { | ||
766 | p_err("too few parameters for map detach"); | ||
767 | return -EINVAL; | ||
768 | } | ||
769 | |||
770 | progfd = prog_parse_fd(&argc, &argv); | ||
771 | if (progfd < 0) | ||
772 | return progfd; | ||
773 | 785 | ||
774 | attach_type = parse_attach_type(*argv); | 786 | err = parse_attach_detach_args(argc, argv, |
775 | if (attach_type == __MAX_BPF_ATTACH_TYPE) { | 787 | &progfd, &attach_type, &mapfd); |
776 | p_err("invalid attach type"); | 788 | if (err) |
777 | return -EINVAL; | 789 | return err; |
778 | } | ||
779 | NEXT_ARG(); | ||
780 | |||
781 | mapfd = map_parse_fd(&argc, &argv); | ||
782 | if (mapfd < 0) | ||
783 | return mapfd; | ||
784 | 790 | ||
785 | err = bpf_prog_detach2(progfd, mapfd, attach_type); | 791 | err = bpf_prog_detach2(progfd, mapfd, attach_type); |
786 | if (err) { | 792 | if (err) { |
@@ -1094,8 +1100,8 @@ static int do_help(int argc, char **argv) | |||
1094 | " [type TYPE] [dev NAME] \\\n" | 1100 | " [type TYPE] [dev NAME] \\\n" |
1095 | " [map { idx IDX | name NAME } MAP]\\\n" | 1101 | " [map { idx IDX | name NAME } MAP]\\\n" |
1096 | " [pinmaps MAP_DIR]\n" | 1102 | " [pinmaps MAP_DIR]\n" |
1097 | " %s %s attach PROG ATTACH_TYPE MAP\n" | 1103 | " %s %s attach PROG ATTACH_TYPE [MAP]\n" |
1098 | " %s %s detach PROG ATTACH_TYPE MAP\n" | 1104 | " %s %s detach PROG ATTACH_TYPE [MAP]\n" |
1099 | " %s %s help\n" | 1105 | " %s %s help\n" |
1100 | "\n" | 1106 | "\n" |
1101 | " " HELP_SPEC_MAP "\n" | 1107 | " " HELP_SPEC_MAP "\n" |
@@ -1107,7 +1113,8 @@ static int do_help(int argc, char **argv) | |||
1107 | " cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n" | 1113 | " cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n" |
1108 | " cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n" | 1114 | " cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n" |
1109 | " cgroup/sendmsg4 | cgroup/sendmsg6 }\n" | 1115 | " cgroup/sendmsg4 | cgroup/sendmsg6 }\n" |
1110 | " ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse }\n" | 1116 | " ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse |\n" |
1117 | " flow_dissector }\n" | ||
1111 | " " HELP_SPEC_OPTIONS "\n" | 1118 | " " HELP_SPEC_OPTIONS "\n" |
1112 | "", | 1119 | "", |
1113 | bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], | 1120 | bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], |