aboutsummaryrefslogtreecommitdiffstats
path: root/tools/bpf/bpftool/prog.c
diff options
context:
space:
mode:
authorStanislav Fomichev <sdf@google.com>2018-11-09 11:21:46 -0500
committerAlexei Starovoitov <ast@kernel.org>2018-11-10 18:56:11 -0500
commit092f08927300086b6520dfa3aa4d9450266f27ae (patch)
tree62b5e46802857fc60f2b945d0a1c08544ca95865 /tools/bpf/bpftool/prog.c
parent3767a94b3253fc8c3df96913d7dec796619161c7 (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.c85
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
724static int do_attach(int argc, char **argv) 725static 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); 758static 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)
760static int do_detach(int argc, char **argv) 780static 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],