diff options
Diffstat (limited to 'tools/bpf/bpftool/prog.c')
-rw-r--r-- | tools/bpf/bpftool/prog.c | 99 |
1 files changed, 98 insertions, 1 deletions
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index b1cd3bc8db70..99ab42c56724 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c | |||
@@ -77,6 +77,26 @@ static const char * const prog_type_name[] = { | |||
77 | [BPF_PROG_TYPE_FLOW_DISSECTOR] = "flow_dissector", | 77 | [BPF_PROG_TYPE_FLOW_DISSECTOR] = "flow_dissector", |
78 | }; | 78 | }; |
79 | 79 | ||
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 | |||
80 | static void print_boot_time(__u64 nsecs, char *buf, unsigned int size) | 100 | static void print_boot_time(__u64 nsecs, char *buf, unsigned int size) |
81 | { | 101 | { |
82 | struct timespec real_time_ts, boot_time_ts; | 102 | struct timespec real_time_ts, boot_time_ts; |
@@ -697,6 +717,77 @@ int map_replace_compar(const void *p1, const void *p2) | |||
697 | return a->idx - b->idx; | 717 | return a->idx - b->idx; |
698 | } | 718 | } |
699 | 719 | ||
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 | } | ||
700 | static int do_load(int argc, char **argv) | 791 | static int do_load(int argc, char **argv) |
701 | { | 792 | { |
702 | enum bpf_attach_type expected_attach_type; | 793 | enum bpf_attach_type expected_attach_type; |
@@ -942,6 +1033,8 @@ static int do_help(int argc, char **argv) | |||
942 | " %s %s pin PROG FILE\n" | 1033 | " %s %s pin PROG FILE\n" |
943 | " %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n" | 1034 | " %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n" |
944 | " [map { idx IDX | name NAME } MAP]\n" | 1035 | " [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" | ||
945 | " %s %s help\n" | 1038 | " %s %s help\n" |
946 | "\n" | 1039 | "\n" |
947 | " " HELP_SPEC_MAP "\n" | 1040 | " " HELP_SPEC_MAP "\n" |
@@ -953,10 +1046,12 @@ static int do_help(int argc, char **argv) | |||
953 | " cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n" | 1046 | " cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n" |
954 | " cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n" | 1047 | " cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n" |
955 | " cgroup/sendmsg4 | cgroup/sendmsg6 }\n" | 1048 | " cgroup/sendmsg4 | cgroup/sendmsg6 }\n" |
1049 | " ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse }\n" | ||
956 | " " HELP_SPEC_OPTIONS "\n" | 1050 | " " HELP_SPEC_OPTIONS "\n" |
957 | "", | 1051 | "", |
958 | bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], | 1052 | 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]); | ||
960 | 1055 | ||
961 | return 0; | 1056 | return 0; |
962 | } | 1057 | } |
@@ -968,6 +1063,8 @@ static const struct cmd cmds[] = { | |||
968 | { "dump", do_dump }, | 1063 | { "dump", do_dump }, |
969 | { "pin", do_pin }, | 1064 | { "pin", do_pin }, |
970 | { "load", do_load }, | 1065 | { "load", do_load }, |
1066 | { "attach", do_attach }, | ||
1067 | { "detach", do_detach }, | ||
971 | { 0 } | 1068 | { 0 } |
972 | }; | 1069 | }; |
973 | 1070 | ||