Skip to content

Commit 49a086c

Browse files
rgushchinborkmann
authored andcommitted
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 <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: Daniel Borkmann <[email protected]> Reviewed-by: Jakub Kicinski <[email protected]> Cc: Martin KaFai Lau <[email protected]> Cc: Quentin Monnet <[email protected]> Cc: David Ahern <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent fe4d44b commit 49a086c

File tree

5 files changed

+79
-34
lines changed

5 files changed

+79
-34
lines changed

tools/bpf/bpftool/Documentation/bpftool-prog.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ SYNOPSIS
1515
*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } }
1616

1717
*COMMANDS* :=
18-
{ **show** | **dump xlated** | **dump jited** | **pin** | **help** }
18+
{ **show** | **dump xlated** | **dump jited** | **pin** | **load** | **help** }
1919

2020
MAP COMMANDS
2121
=============
@@ -24,6 +24,7 @@ MAP COMMANDS
2424
| **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes**}]
2525
| **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}]
2626
| **bpftool** **prog pin** *PROG* *FILE*
27+
| **bpftool** **prog load** *OBJ* *FILE*
2728
| **bpftool** **prog help**
2829
|
2930
| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
@@ -57,6 +58,11 @@ DESCRIPTION
5758

5859
Note: *FILE* must be located in *bpffs* mount.
5960

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+
6066
**bpftool prog help**
6167
Print short help message.
6268

@@ -126,8 +132,10 @@ EXAMPLES
126132
|
127133
| **# mount -t bpf none /sys/fs/bpf/**
128134
| **# bpftool prog pin id 10 /sys/fs/bpf/prog**
135+
| **# bpftool prog load ./my_prog.o /sys/fs/bpf/prog2**
129136
| **# ls -l /sys/fs/bpf/**
130137
| -rw------- 1 root root 0 Jul 22 01:43 prog
138+
| -rw------- 1 root root 0 Jul 22 01:44 prog2
131139
132140
**# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes**
133141

tools/bpf/bpftool/Documentation/bpftool.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ SYNOPSIS
2626
| **pin** | **help** }
2727
2828
*PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin**
29-
| **help** }
29+
| **load** | **help** }
3030
3131
DESCRIPTION
3232
===========

tools/bpf/bpftool/common.c

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,49 @@ int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type)
163163
return fd;
164164
}
165165

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)
167167
{
168168
char err_str[ERR_MAX_LEN];
169-
unsigned int id;
170-
char *endptr;
171169
char *file;
172170
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;
173209
int err;
174210
int fd;
175211

@@ -195,35 +231,8 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))
195231
return -1;
196232
}
197233

198-
err = bpf_obj_pin(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-
}
234+
err = do_pin_fd(fd, *argv);
210235

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:
227236
close(fd);
228237
return err;
229238
}

tools/bpf/bpftool/main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ char *get_fdinfo(int fd, const char *key);
111111
int open_obj_pinned(char *path);
112112
int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type);
113113
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32));
114+
int do_pin_fd(int fd, const char *name);
114115

115116
int do_prog(int argc, char **arg);
116117
int do_map(int argc, char **arg);

tools/bpf/bpftool/prog.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <sys/stat.h>
4646

4747
#include <bpf.h>
48+
#include <libbpf.h>
4849

4950
#include "main.h"
5051
#include "disasm.h"
@@ -635,6 +636,30 @@ static int do_pin(int argc, char **argv)
635636
return err;
636637
}
637638

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+
638663
static int do_help(int argc, char **argv)
639664
{
640665
if (json_output) {
@@ -647,13 +672,14 @@ static int do_help(int argc, char **argv)
647672
" %s %s dump xlated PROG [{ file FILE | opcodes }]\n"
648673
" %s %s dump jited PROG [{ file FILE | opcodes }]\n"
649674
" %s %s pin PROG FILE\n"
675+
" %s %s load OBJ FILE\n"
650676
" %s %s help\n"
651677
"\n"
652678
" " HELP_SPEC_PROGRAM "\n"
653679
" " HELP_SPEC_OPTIONS "\n"
654680
"",
655681
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]);
657683

658684
return 0;
659685
}
@@ -663,6 +689,7 @@ static const struct cmd cmds[] = {
663689
{ "help", do_help },
664690
{ "dump", do_dump },
665691
{ "pin", do_pin },
692+
{ "load", do_load },
666693
{ 0 }
667694
};
668695

0 commit comments

Comments
 (0)