Commit 49a086c2 authored by Roman Gushchin's avatar Roman Gushchin Committed by Daniel Borkmann

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: default avatarRoman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: default avatarJakub 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: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent fe4d44b2
...@@ -15,7 +15,7 @@ SYNOPSIS ...@@ -15,7 +15,7 @@ SYNOPSIS
*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } }
*COMMANDS* := *COMMANDS* :=
{ **show** | **dump xlated** | **dump jited** | **pin** | **help** } { **show** | **dump xlated** | **dump jited** | **pin** | **load** | **help** }
MAP COMMANDS MAP COMMANDS
============= =============
...@@ -24,6 +24,7 @@ MAP COMMANDS ...@@ -24,6 +24,7 @@ MAP COMMANDS
| **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes**}] | **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes**}]
| **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}]
| **bpftool** **prog pin** *PROG* *FILE* | **bpftool** **prog pin** *PROG* *FILE*
| **bpftool** **prog load** *OBJ* *FILE*
| **bpftool** **prog help** | **bpftool** **prog help**
| |
| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } | *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
...@@ -57,6 +58,11 @@ DESCRIPTION ...@@ -57,6 +58,11 @@ DESCRIPTION
Note: *FILE* must be located in *bpffs* mount. Note: *FILE* must be located in *bpffs* mount.
**bpftool prog load** *OBJ* *FILE*
Load bpf program from binary *OBJ* and pin as *FILE*.
Note: *FILE* must be located in *bpffs* mount.
**bpftool prog help** **bpftool prog help**
Print short help message. Print short help message.
...@@ -126,8 +132,10 @@ EXAMPLES ...@@ -126,8 +132,10 @@ EXAMPLES
| |
| **# mount -t bpf none /sys/fs/bpf/** | **# mount -t bpf none /sys/fs/bpf/**
| **# bpftool prog pin id 10 /sys/fs/bpf/prog** | **# bpftool prog pin id 10 /sys/fs/bpf/prog**
| **# bpftool prog load ./my_prog.o /sys/fs/bpf/prog2**
| **# ls -l /sys/fs/bpf/** | **# ls -l /sys/fs/bpf/**
| -rw------- 1 root root 0 Jul 22 01:43 prog | -rw------- 1 root root 0 Jul 22 01:43 prog
| -rw------- 1 root root 0 Jul 22 01:44 prog2
**# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes** **# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes**
......
...@@ -26,7 +26,7 @@ SYNOPSIS ...@@ -26,7 +26,7 @@ SYNOPSIS
| **pin** | **help** } | **pin** | **help** }
*PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin** *PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin**
| **help** } | **load** | **help** }
DESCRIPTION DESCRIPTION
=========== ===========
......
...@@ -163,13 +163,49 @@ int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type) ...@@ -163,13 +163,49 @@ int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type)
return fd; return fd;
} }
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) int do_pin_fd(int fd, const char *name)
{ {
char err_str[ERR_MAX_LEN]; char err_str[ERR_MAX_LEN];
unsigned int id;
char *endptr;
char *file; char *file;
char *dir; char *dir;
int err = 0;
err = bpf_obj_pin(fd, name);
if (!err)
goto out;
file = malloc(strlen(name) + 1);
strcpy(file, name);
dir = dirname(file);
if (errno != EPERM || is_bpffs(dir)) {
p_err("can't pin the object (%s): %s", name, strerror(errno));
goto out_free;
}
/* Attempt to mount bpffs, then retry pinning. */
err = mnt_bpffs(dir, err_str, ERR_MAX_LEN);
if (!err) {
err = bpf_obj_pin(fd, name);
if (err)
p_err("can't pin the object (%s): %s", name,
strerror(errno));
} else {
err_str[ERR_MAX_LEN - 1] = '\0';
p_err("can't mount BPF file system to pin the object (%s): %s",
name, err_str);
}
out_free:
free(file);
out:
return err;
}
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))
{
unsigned int id;
char *endptr;
int err; int err;
int fd; int fd;
...@@ -195,35 +231,8 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) ...@@ -195,35 +231,8 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))
return -1; return -1;
} }
err = bpf_obj_pin(fd, *argv); err = do_pin_fd(fd, *argv);
if (!err)
goto out_close;
file = malloc(strlen(*argv) + 1);
strcpy(file, *argv);
dir = dirname(file);
if (errno != EPERM || is_bpffs(dir)) {
p_err("can't pin the object (%s): %s", *argv, strerror(errno));
goto out_free;
}
/* Attempt to mount bpffs, then retry pinning. */
err = mnt_bpffs(dir, err_str, ERR_MAX_LEN);
if (!err) {
err = bpf_obj_pin(fd, *argv);
if (err)
p_err("can't pin the object (%s): %s", *argv,
strerror(errno));
} else {
err_str[ERR_MAX_LEN - 1] = '\0';
p_err("can't mount BPF file system to pin the object (%s): %s",
*argv, err_str);
}
out_free:
free(file);
out_close:
close(fd); close(fd);
return err; return err;
} }
......
...@@ -111,6 +111,7 @@ char *get_fdinfo(int fd, const char *key); ...@@ -111,6 +111,7 @@ char *get_fdinfo(int fd, const char *key);
int open_obj_pinned(char *path); int open_obj_pinned(char *path);
int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type); int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type);
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)); int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32));
int do_pin_fd(int fd, const char *name);
int do_prog(int argc, char **arg); int do_prog(int argc, char **arg);
int do_map(int argc, char **arg); int do_map(int argc, char **arg);
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <bpf.h> #include <bpf.h>
#include <libbpf.h>
#include "main.h" #include "main.h"
#include "disasm.h" #include "disasm.h"
...@@ -635,6 +636,30 @@ static int do_pin(int argc, char **argv) ...@@ -635,6 +636,30 @@ static int do_pin(int argc, char **argv)
return err; return err;
} }
static int do_load(int argc, char **argv)
{
struct bpf_object *obj;
int prog_fd;
if (argc != 2)
usage();
if (bpf_prog_load(argv[0], BPF_PROG_TYPE_UNSPEC, &obj, &prog_fd)) {
p_err("failed to load program\n");
return -1;
}
if (do_pin_fd(prog_fd, argv[1])) {
p_err("failed to pin program\n");
return -1;
}
if (json_output)
jsonw_null(json_wtr);
return 0;
}
static int do_help(int argc, char **argv) static int do_help(int argc, char **argv)
{ {
if (json_output) { if (json_output) {
...@@ -647,13 +672,14 @@ static int do_help(int argc, char **argv) ...@@ -647,13 +672,14 @@ static int do_help(int argc, char **argv)
" %s %s dump xlated PROG [{ file FILE | opcodes }]\n" " %s %s dump xlated PROG [{ file FILE | opcodes }]\n"
" %s %s dump jited PROG [{ file FILE | opcodes }]\n" " %s %s dump jited PROG [{ file FILE | opcodes }]\n"
" %s %s pin PROG FILE\n" " %s %s pin PROG FILE\n"
" %s %s load OBJ FILE\n"
" %s %s help\n" " %s %s help\n"
"\n" "\n"
" " HELP_SPEC_PROGRAM "\n" " " HELP_SPEC_PROGRAM "\n"
" " HELP_SPEC_OPTIONS "\n" " " HELP_SPEC_OPTIONS "\n"
"", "",
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
bin_name, argv[-2], bin_name, argv[-2]); bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]);
return 0; return 0;
} }
...@@ -663,6 +689,7 @@ static const struct cmd cmds[] = { ...@@ -663,6 +689,7 @@ static const struct cmd cmds[] = {
{ "help", do_help }, { "help", do_help },
{ "dump", do_dump }, { "dump", do_dump },
{ "pin", do_pin }, { "pin", do_pin },
{ "load", do_load },
{ 0 } { 0 }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment