aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorRoman Gushchin <guro@fb.com>2017-12-13 10:18:53 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2017-12-14 07:37:13 -0500
commit49a086c201a9356287471aa5846a427bdcecc4f7 (patch)
tree0fc32d8eb8543ded1ccef6f36cbebd070dafc0b3 /tools
parentfe4d44b23f6b38194a92c6b8a50d921a071c4db4 (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.rst10
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool.rst2
-rw-r--r--tools/bpf/bpftool/common.c71
-rw-r--r--tools/bpf/bpftool/main.h1
-rw-r--r--tools/bpf/bpftool/prog.c29
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
20MAP COMMANDS 20MAP 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
31DESCRIPTION 31DESCRIPTION
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
166int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) 166int 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
199out_free:
200 free(file);
201out:
202 return err;
203}
204
205int 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
224out_free:
225 free(file);
226out_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);
111int open_obj_pinned(char *path); 111int open_obj_pinned(char *path);
112int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type); 112int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type);
113int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)); 113int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32));
114int do_pin_fd(int fd, const char *name);
114 115
115int do_prog(int argc, char **arg); 116int do_prog(int argc, char **arg);
116int do_map(int argc, char **arg); 117int 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
639static 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
638static int do_help(int argc, char **argv) 663static 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