diff options
author | Stanislav Fomichev <sdf@google.com> | 2018-11-09 11:21:44 -0500 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2018-11-10 18:56:11 -0500 |
commit | 77380998d91dee8aafdbe42634776ba1ef692f1e (patch) | |
tree | 9fa3bca83bbc5eeba47a8e00e647f5be999eb698 /tools/bpf/bpftool/prog.c | |
parent | 33a2c75c55e24aa30ff9fed805ae8bea13c1e2a3 (diff) |
bpftool: add loadall command
This patch adds new *loadall* command which slightly differs from the
existing *load*. *load* command loads all programs from the obj file,
but pins only the first programs. *loadall* pins all programs from the
obj file under specified directory.
The intended usecase is flow_dissector, where we want to load a bunch
of progs, pin them all and after that construct a jump table.
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 | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index b9b84553bec4..97d930042cd5 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c | |||
@@ -792,15 +792,16 @@ static int do_detach(int argc, char **argv) | |||
792 | jsonw_null(json_wtr); | 792 | jsonw_null(json_wtr); |
793 | return 0; | 793 | return 0; |
794 | } | 794 | } |
795 | static int do_load(int argc, char **argv) | 795 | |
796 | static int load_with_options(int argc, char **argv, bool first_prog_only) | ||
796 | { | 797 | { |
797 | enum bpf_attach_type expected_attach_type; | 798 | enum bpf_attach_type expected_attach_type; |
798 | struct bpf_object_open_attr attr = { | 799 | struct bpf_object_open_attr attr = { |
799 | .prog_type = BPF_PROG_TYPE_UNSPEC, | 800 | .prog_type = BPF_PROG_TYPE_UNSPEC, |
800 | }; | 801 | }; |
801 | struct map_replace *map_replace = NULL; | 802 | struct map_replace *map_replace = NULL; |
803 | struct bpf_program *prog = NULL, *pos; | ||
802 | unsigned int old_map_fds = 0; | 804 | unsigned int old_map_fds = 0; |
803 | struct bpf_program *prog; | ||
804 | struct bpf_object *obj; | 805 | struct bpf_object *obj; |
805 | struct bpf_map *map; | 806 | struct bpf_map *map; |
806 | const char *pinfile; | 807 | const char *pinfile; |
@@ -918,26 +919,25 @@ static int do_load(int argc, char **argv) | |||
918 | goto err_free_reuse_maps; | 919 | goto err_free_reuse_maps; |
919 | } | 920 | } |
920 | 921 | ||
921 | prog = bpf_program__next(NULL, obj); | 922 | bpf_object__for_each_program(pos, obj) { |
922 | if (!prog) { | 923 | enum bpf_prog_type prog_type = attr.prog_type; |
923 | p_err("object file doesn't contain any bpf program"); | ||
924 | goto err_close_obj; | ||
925 | } | ||
926 | 924 | ||
927 | bpf_program__set_ifindex(prog, ifindex); | 925 | if (attr.prog_type == BPF_PROG_TYPE_UNSPEC) { |
928 | if (attr.prog_type == BPF_PROG_TYPE_UNSPEC) { | 926 | const char *sec_name = bpf_program__title(pos, false); |
929 | const char *sec_name = bpf_program__title(prog, false); | ||
930 | 927 | ||
931 | err = libbpf_prog_type_by_name(sec_name, &attr.prog_type, | 928 | err = libbpf_prog_type_by_name(sec_name, &prog_type, |
932 | &expected_attach_type); | 929 | &expected_attach_type); |
933 | if (err < 0) { | 930 | if (err < 0) { |
934 | p_err("failed to guess program type based on section name %s\n", | 931 | p_err("failed to guess program type based on section name %s\n", |
935 | sec_name); | 932 | sec_name); |
936 | goto err_close_obj; | 933 | goto err_close_obj; |
934 | } | ||
937 | } | 935 | } |
936 | |||
937 | bpf_program__set_ifindex(pos, ifindex); | ||
938 | bpf_program__set_type(pos, prog_type); | ||
939 | bpf_program__set_expected_attach_type(pos, expected_attach_type); | ||
938 | } | 940 | } |
939 | bpf_program__set_type(prog, attr.prog_type); | ||
940 | bpf_program__set_expected_attach_type(prog, expected_attach_type); | ||
941 | 941 | ||
942 | qsort(map_replace, old_map_fds, sizeof(*map_replace), | 942 | qsort(map_replace, old_map_fds, sizeof(*map_replace), |
943 | map_replace_compar); | 943 | map_replace_compar); |
@@ -1003,9 +1003,31 @@ static int do_load(int argc, char **argv) | |||
1003 | goto err_close_obj; | 1003 | goto err_close_obj; |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | if (do_pin_fd(bpf_program__fd(prog), pinfile)) | 1006 | err = mount_bpffs_for_pin(pinfile); |
1007 | if (err) | ||
1007 | goto err_close_obj; | 1008 | goto err_close_obj; |
1008 | 1009 | ||
1010 | if (first_prog_only) { | ||
1011 | prog = bpf_program__next(NULL, obj); | ||
1012 | if (!prog) { | ||
1013 | p_err("object file doesn't contain any bpf program"); | ||
1014 | goto err_close_obj; | ||
1015 | } | ||
1016 | |||
1017 | err = bpf_obj_pin(bpf_program__fd(prog), pinfile); | ||
1018 | if (err) { | ||
1019 | p_err("failed to pin program %s", | ||
1020 | bpf_program__title(prog, false)); | ||
1021 | goto err_close_obj; | ||
1022 | } | ||
1023 | } else { | ||
1024 | err = bpf_object__pin_programs(obj, pinfile); | ||
1025 | if (err) { | ||
1026 | p_err("failed to pin all programs"); | ||
1027 | goto err_close_obj; | ||
1028 | } | ||
1029 | } | ||
1030 | |||
1009 | if (json_output) | 1031 | if (json_output) |
1010 | jsonw_null(json_wtr); | 1032 | jsonw_null(json_wtr); |
1011 | 1033 | ||
@@ -1025,6 +1047,16 @@ err_free_reuse_maps: | |||
1025 | return -1; | 1047 | return -1; |
1026 | } | 1048 | } |
1027 | 1049 | ||
1050 | static int do_load(int argc, char **argv) | ||
1051 | { | ||
1052 | return load_with_options(argc, argv, true); | ||
1053 | } | ||
1054 | |||
1055 | static int do_loadall(int argc, char **argv) | ||
1056 | { | ||
1057 | return load_with_options(argc, argv, false); | ||
1058 | } | ||
1059 | |||
1028 | static int do_help(int argc, char **argv) | 1060 | static int do_help(int argc, char **argv) |
1029 | { | 1061 | { |
1030 | if (json_output) { | 1062 | if (json_output) { |
@@ -1037,7 +1069,8 @@ static int do_help(int argc, char **argv) | |||
1037 | " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n" | 1069 | " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n" |
1038 | " %s %s dump jited PROG [{ file FILE | opcodes }]\n" | 1070 | " %s %s dump jited PROG [{ file FILE | opcodes }]\n" |
1039 | " %s %s pin PROG FILE\n" | 1071 | " %s %s pin PROG FILE\n" |
1040 | " %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n" | 1072 | " %s %s { load | loadall } OBJ PATH \\\n" |
1073 | " [type TYPE] [dev NAME] \\\n" | ||
1041 | " [map { idx IDX | name NAME } MAP]\n" | 1074 | " [map { idx IDX | name NAME } MAP]\n" |
1042 | " %s %s attach PROG ATTACH_TYPE MAP\n" | 1075 | " %s %s attach PROG ATTACH_TYPE MAP\n" |
1043 | " %s %s detach PROG ATTACH_TYPE MAP\n" | 1076 | " %s %s detach PROG ATTACH_TYPE MAP\n" |
@@ -1069,6 +1102,7 @@ static const struct cmd cmds[] = { | |||
1069 | { "dump", do_dump }, | 1102 | { "dump", do_dump }, |
1070 | { "pin", do_pin }, | 1103 | { "pin", do_pin }, |
1071 | { "load", do_load }, | 1104 | { "load", do_load }, |
1105 | { "loadall", do_loadall }, | ||
1072 | { "attach", do_attach }, | 1106 | { "attach", do_attach }, |
1073 | { "detach", do_detach }, | 1107 | { "detach", do_detach }, |
1074 | { 0 } | 1108 | { 0 } |