diff options
author | Roman Gushchin <guro@fb.com> | 2017-12-13 10:18:53 -0500 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2017-12-14 07:37:13 -0500 |
commit | 49a086c201a9356287471aa5846a427bdcecc4f7 (patch) | |
tree | 0fc32d8eb8543ded1ccef6f36cbebd070dafc0b3 /tools | |
parent | fe4d44b23f6b38194a92c6b8a50d921a071c4db4 (diff) |
bpftool: implement prog load command
Add the prog load command to load a bpf program from a specified
binary file and pin it to bpffs.
Usage description and examples are given in the corresponding man
page.
Syntax:
$ bpftool prog load OBJ FILE
FILE is a non-existing file on bpffs.
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Quentin Monnet <quentin.monnet@netronome.com>
Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/bpf/bpftool/Documentation/bpftool-prog.rst | 10 | ||||
-rw-r--r-- | tools/bpf/bpftool/Documentation/bpftool.rst | 2 | ||||
-rw-r--r-- | tools/bpf/bpftool/common.c | 71 | ||||
-rw-r--r-- | tools/bpf/bpftool/main.h | 1 | ||||
-rw-r--r-- | tools/bpf/bpftool/prog.c | 29 |
5 files changed, 79 insertions, 34 deletions
diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index 36e8d1c3c40d..ffdb20e8280f 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst | |||
@@ -15,7 +15,7 @@ SYNOPSIS | |||
15 | *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } | 15 | *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } |
16 | 16 | ||
17 | *COMMANDS* := | 17 | *COMMANDS* := |
18 | { **show** | **dump xlated** | **dump jited** | **pin** | **help** } | 18 | { **show** | **dump xlated** | **dump jited** | **pin** | **load** | **help** } |
19 | 19 | ||
20 | MAP COMMANDS | 20 | MAP COMMANDS |
21 | ============= | 21 | ============= |
@@ -24,6 +24,7 @@ MAP COMMANDS | |||
24 | | **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes**}] | 24 | | **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes**}] |
25 | | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] | 25 | | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] |
26 | | **bpftool** **prog pin** *PROG* *FILE* | 26 | | **bpftool** **prog pin** *PROG* *FILE* |
27 | | **bpftool** **prog load** *OBJ* *FILE* | ||
27 | | **bpftool** **prog help** | 28 | | **bpftool** **prog help** |
28 | | | 29 | | |
29 | | *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } | 30 | | *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } |
@@ -57,6 +58,11 @@ DESCRIPTION | |||
57 | 58 | ||
58 | Note: *FILE* must be located in *bpffs* mount. | 59 | Note: *FILE* must be located in *bpffs* mount. |
59 | 60 | ||
61 | **bpftool prog load** *OBJ* *FILE* | ||
62 | Load bpf program from binary *OBJ* and pin as *FILE*. | ||
63 | |||
64 | Note: *FILE* must be located in *bpffs* mount. | ||
65 | |||
60 | **bpftool prog help** | 66 | **bpftool prog help** |
61 | Print short help message. | 67 | Print short help message. |
62 | 68 | ||
@@ -126,8 +132,10 @@ EXAMPLES | |||
126 | | | 132 | | |
127 | | **# mount -t bpf none /sys/fs/bpf/** | 133 | | **# mount -t bpf none /sys/fs/bpf/** |
128 | | **# bpftool prog pin id 10 /sys/fs/bpf/prog** | 134 | | **# bpftool prog pin id 10 /sys/fs/bpf/prog** |
135 | | **# bpftool prog load ./my_prog.o /sys/fs/bpf/prog2** | ||
129 | | **# ls -l /sys/fs/bpf/** | 136 | | **# ls -l /sys/fs/bpf/** |
130 | | -rw------- 1 root root 0 Jul 22 01:43 prog | 137 | | -rw------- 1 root root 0 Jul 22 01:43 prog |
138 | | -rw------- 1 root root 0 Jul 22 01:44 prog2 | ||
131 | 139 | ||
132 | **# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes** | 140 | **# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes** |
133 | 141 | ||
diff --git a/tools/bpf/bpftool/Documentation/bpftool.rst b/tools/bpf/bpftool/Documentation/bpftool.rst index 926c03d5a8da..f547a0c0aa34 100644 --- a/tools/bpf/bpftool/Documentation/bpftool.rst +++ b/tools/bpf/bpftool/Documentation/bpftool.rst | |||
@@ -26,7 +26,7 @@ SYNOPSIS | |||
26 | | **pin** | **help** } | 26 | | **pin** | **help** } |
27 | 27 | ||
28 | *PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin** | 28 | *PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin** |
29 | | **help** } | 29 | | **load** | **help** } |
30 | 30 | ||
31 | DESCRIPTION | 31 | DESCRIPTION |
32 | =========== | 32 | =========== |
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 2bd3b280e6dd..b62c94e3997a 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c | |||
@@ -163,13 +163,49 @@ int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type) | |||
163 | return fd; | 163 | return fd; |
164 | } | 164 | } |
165 | 165 | ||
166 | int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) | 166 | int do_pin_fd(int fd, const char *name) |
167 | { | 167 | { |
168 | char err_str[ERR_MAX_LEN]; | 168 | char err_str[ERR_MAX_LEN]; |
169 | unsigned int id; | ||
170 | char *endptr; | ||
171 | char *file; | 169 | char *file; |
172 | char *dir; | 170 | char *dir; |
171 | int err = 0; | ||
172 | |||
173 | err = bpf_obj_pin(fd, name); | ||
174 | if (!err) | ||
175 | goto out; | ||
176 | |||
177 | file = malloc(strlen(name) + 1); | ||
178 | strcpy(file, name); | ||
179 | dir = dirname(file); | ||
180 | |||
181 | if (errno != EPERM || is_bpffs(dir)) { | ||
182 | p_err("can't pin the object (%s): %s", name, strerror(errno)); | ||
183 | goto out_free; | ||
184 | } | ||
185 | |||
186 | /* Attempt to mount bpffs, then retry pinning. */ | ||
187 | err = mnt_bpffs(dir, err_str, ERR_MAX_LEN); | ||
188 | if (!err) { | ||
189 | err = bpf_obj_pin(fd, name); | ||
190 | if (err) | ||
191 | p_err("can't pin the object (%s): %s", name, | ||
192 | strerror(errno)); | ||
193 | } else { | ||
194 | err_str[ERR_MAX_LEN - 1] = '\0'; | ||
195 | p_err("can't mount BPF file system to pin the object (%s): %s", | ||
196 | name, err_str); | ||
197 | } | ||
198 | |||
199 | out_free: | ||
200 | free(file); | ||
201 | out: | ||
202 | return err; | ||
203 | } | ||
204 | |||
205 | int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) | ||
206 | { | ||
207 | unsigned int id; | ||
208 | char *endptr; | ||
173 | int err; | 209 | int err; |
174 | int fd; | 210 | int fd; |
175 | 211 | ||
@@ -195,35 +231,8 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) | |||
195 | return -1; | 231 | return -1; |
196 | } | 232 | } |
197 | 233 | ||
198 | err = bpf_obj_pin(fd, *argv); | 234 | err = do_pin_fd(fd, *argv); |
199 | if (!err) | ||
200 | goto out_close; | ||
201 | |||
202 | file = malloc(strlen(*argv) + 1); | ||
203 | strcpy(file, *argv); | ||
204 | dir = dirname(file); | ||
205 | |||
206 | if (errno != EPERM || is_bpffs(dir)) { | ||
207 | p_err("can't pin the object (%s): %s", *argv, strerror(errno)); | ||
208 | goto out_free; | ||
209 | } | ||
210 | 235 | ||
211 | /* Attempt to mount bpffs, then retry pinning. */ | ||
212 | err = mnt_bpffs(dir, err_str, ERR_MAX_LEN); | ||
213 | if (!err) { | ||
214 | err = bpf_obj_pin(fd, *argv); | ||
215 | if (err) | ||
216 | p_err("can't pin the object (%s): %s", *argv, | ||
217 | strerror(errno)); | ||
218 | } else { | ||
219 | err_str[ERR_MAX_LEN - 1] = '\0'; | ||
220 | p_err("can't mount BPF file system to pin the object (%s): %s", | ||
221 | *argv, err_str); | ||
222 | } | ||
223 | |||
224 | out_free: | ||
225 | free(file); | ||
226 | out_close: | ||
227 | close(fd); | 236 | close(fd); |
228 | return err; | 237 | return err; |
229 | } | 238 | } |
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index bff330b49791..bec1ccbb49c7 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h | |||
@@ -111,6 +111,7 @@ char *get_fdinfo(int fd, const char *key); | |||
111 | int open_obj_pinned(char *path); | 111 | int open_obj_pinned(char *path); |
112 | int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type); | 112 | int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type); |
113 | int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)); | 113 | int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)); |
114 | int do_pin_fd(int fd, const char *name); | ||
114 | 115 | ||
115 | int do_prog(int argc, char **arg); | 116 | int do_prog(int argc, char **arg); |
116 | int do_map(int argc, char **arg); | 117 | int do_map(int argc, char **arg); |
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index ad619b96c276..037484ceaeaf 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <sys/stat.h> | 45 | #include <sys/stat.h> |
46 | 46 | ||
47 | #include <bpf.h> | 47 | #include <bpf.h> |
48 | #include <libbpf.h> | ||
48 | 49 | ||
49 | #include "main.h" | 50 | #include "main.h" |
50 | #include "disasm.h" | 51 | #include "disasm.h" |
@@ -635,6 +636,30 @@ static int do_pin(int argc, char **argv) | |||
635 | return err; | 636 | return err; |
636 | } | 637 | } |
637 | 638 | ||
639 | static int do_load(int argc, char **argv) | ||
640 | { | ||
641 | struct bpf_object *obj; | ||
642 | int prog_fd; | ||
643 | |||
644 | if (argc != 2) | ||
645 | usage(); | ||
646 | |||
647 | if (bpf_prog_load(argv[0], BPF_PROG_TYPE_UNSPEC, &obj, &prog_fd)) { | ||
648 | p_err("failed to load program\n"); | ||
649 | return -1; | ||
650 | } | ||
651 | |||
652 | if (do_pin_fd(prog_fd, argv[1])) { | ||
653 | p_err("failed to pin program\n"); | ||
654 | return -1; | ||
655 | } | ||
656 | |||
657 | if (json_output) | ||
658 | jsonw_null(json_wtr); | ||
659 | |||
660 | return 0; | ||
661 | } | ||
662 | |||
638 | static int do_help(int argc, char **argv) | 663 | static int do_help(int argc, char **argv) |
639 | { | 664 | { |
640 | if (json_output) { | 665 | if (json_output) { |
@@ -647,13 +672,14 @@ static int do_help(int argc, char **argv) | |||
647 | " %s %s dump xlated PROG [{ file FILE | opcodes }]\n" | 672 | " %s %s dump xlated PROG [{ file FILE | opcodes }]\n" |
648 | " %s %s dump jited PROG [{ file FILE | opcodes }]\n" | 673 | " %s %s dump jited PROG [{ file FILE | opcodes }]\n" |
649 | " %s %s pin PROG FILE\n" | 674 | " %s %s pin PROG FILE\n" |
675 | " %s %s load OBJ FILE\n" | ||
650 | " %s %s help\n" | 676 | " %s %s help\n" |
651 | "\n" | 677 | "\n" |
652 | " " HELP_SPEC_PROGRAM "\n" | 678 | " " HELP_SPEC_PROGRAM "\n" |
653 | " " HELP_SPEC_OPTIONS "\n" | 679 | " " HELP_SPEC_OPTIONS "\n" |
654 | "", | 680 | "", |
655 | bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], | 681 | bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], |
656 | bin_name, argv[-2], bin_name, argv[-2]); | 682 | bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]); |
657 | 683 | ||
658 | return 0; | 684 | return 0; |
659 | } | 685 | } |
@@ -663,6 +689,7 @@ static const struct cmd cmds[] = { | |||
663 | { "help", do_help }, | 689 | { "help", do_help }, |
664 | { "dump", do_dump }, | 690 | { "dump", do_dump }, |
665 | { "pin", do_pin }, | 691 | { "pin", do_pin }, |
692 | { "load", do_load }, | ||
666 | { 0 } | 693 | { 0 } |
667 | }; | 694 | }; |
668 | 695 | ||