Skip to content

Commit ba95c74

Browse files
qmonnetborkmann
authored andcommitted
tools: bpftool: add "prog run" subcommand to test-run programs
Add a new "bpftool prog run" subcommand to run a loaded program on input data (and possibly with input context) passed by the user. Print output data (and output context if relevant) into a file or into the console. Print return value and duration for the test run into the console. A "repeat" argument can be passed to run the program several times in a row. The command does not perform any kind of verification based on program type (Is this program type allowed to use an input context?) or on data consistency (Can I work with empty input data?), this is left to the kernel. Example invocation: # perl -e 'print "\x0" x 14' | ./bpftool prog run \ pinned /sys/fs/bpf/sample_ret0 \ data_in - data_out - repeat 5 0000000 0000 0000 0000 0000 0000 0000 0000 | ........ ...... Return value: 0, duration (average): 260ns When one of data_in or ctx_in is "-", bpftool reads from standard input, in binary format. Other formats (JSON, hexdump) might be supported (via an optional command line keyword like "data_fmt_in") in the future if relevant, but this would require doing more parsing in bpftool. v2: - Fix argument names for function check_single_stdin(). (Yonghong) Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Acked-by: Yonghong Song <yhs@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent e232cb6 commit ba95c74

File tree

6 files changed

+485
-3
lines changed

6 files changed

+485
-3
lines changed

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ PROG COMMANDS
2929
| **bpftool** **prog attach** *PROG* *ATTACH_TYPE* [*MAP*]
3030
| **bpftool** **prog detach** *PROG* *ATTACH_TYPE* [*MAP*]
3131
| **bpftool** **prog tracelog**
32+
| **bpftool** **prog run** *PROG* **data_in** *FILE* [**data_out** *FILE* [**data_size_out** *L*]] [**ctx_in** *FILE* [**ctx_out** *FILE* [**ctx_size_out** *M*]]] [**repeat** *N*]
3233
| **bpftool** **prog help**
3334
|
3435
| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
@@ -146,6 +147,39 @@ DESCRIPTION
146147
streaming data from BPF programs to user space, one can use
147148
perf events (see also **bpftool-map**\ (8)).
148149

150+
**bpftool prog run** *PROG* **data_in** *FILE* [**data_out** *FILE* [**data_size_out** *L*]] [**ctx_in** *FILE* [**ctx_out** *FILE* [**ctx_size_out** *M*]]] [**repeat** *N*]
151+
Run BPF program *PROG* in the kernel testing infrastructure
152+
for BPF, meaning that the program works on the data and
153+
context provided by the user, and not on actual packets or
154+
monitored functions etc. Return value and duration for the
155+
test run are printed out to the console.
156+
157+
Input data is read from the *FILE* passed with **data_in**.
158+
If this *FILE* is "**-**", input data is read from standard
159+
input. Input context, if any, is read from *FILE* passed with
160+
**ctx_in**. Again, "**-**" can be used to read from standard
161+
input, but only if standard input is not already in use for
162+
input data. If a *FILE* is passed with **data_out**, output
163+
data is written to that file. Similarly, output context is
164+
written to the *FILE* passed with **ctx_out**. For both
165+
output flows, "**-**" can be used to print to the standard
166+
output (as plain text, or JSON if relevant option was
167+
passed). If output keywords are omitted, output data and
168+
context are discarded. Keywords **data_size_out** and
169+
**ctx_size_out** are used to pass the size (in bytes) for the
170+
output buffers to the kernel, although the default of 32 kB
171+
should be more than enough for most cases.
172+
173+
Keyword **repeat** is used to indicate the number of
174+
consecutive runs to perform. Note that output data and
175+
context printed to files correspond to the last of those
176+
runs. The duration printed out at the end of the runs is an
177+
average over all runs performed by the command.
178+
179+
Not all program types support test run. Among those which do,
180+
not all of them can take the **ctx_in**/**ctx_out**
181+
arguments. bpftool does not perform checks on program types.
182+
149183
**bpftool prog help**
150184
Print short help message.
151185

tools/bpf/bpftool/bash-completion/bpftool

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,34 @@ _bpftool()
408408
tracelog)
409409
return 0
410410
;;
411+
run)
412+
if [[ ${#words[@]} -lt 5 ]]; then
413+
_filedir
414+
return 0
415+
fi
416+
case $prev in
417+
id)
418+
_bpftool_get_prog_ids
419+
return 0
420+
;;
421+
data_in|data_out|ctx_in|ctx_out)
422+
_filedir
423+
return 0
424+
;;
425+
repeat|data_size_out|ctx_size_out)
426+
return 0
427+
;;
428+
*)
429+
_bpftool_once_attr 'data_in data_out data_size_out \
430+
ctx_in ctx_out ctx_size_out repeat'
431+
return 0
432+
;;
433+
esac
434+
;;
411435
*)
412436
[[ $prev == $object ]] && \
413-
COMPREPLY=( $( compgen -W 'dump help pin attach detach load \
414-
show list tracelog' -- "$cur" ) )
437+
COMPREPLY=( $( compgen -W 'dump help pin attach detach \
438+
load show list tracelog run' -- "$cur" ) )
415439
;;
416440
esac
417441
;;

tools/bpf/bpftool/main.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,35 @@ bool is_prefix(const char *pfx, const char *str)
117117
return !memcmp(str, pfx, strlen(pfx));
118118
}
119119

120+
/* Last argument MUST be NULL pointer */
121+
int detect_common_prefix(const char *arg, ...)
122+
{
123+
unsigned int count = 0;
124+
const char *ref;
125+
char msg[256];
126+
va_list ap;
127+
128+
snprintf(msg, sizeof(msg), "ambiguous prefix: '%s' could be '", arg);
129+
va_start(ap, arg);
130+
while ((ref = va_arg(ap, const char *))) {
131+
if (!is_prefix(arg, ref))
132+
continue;
133+
count++;
134+
if (count > 1)
135+
strncat(msg, "' or '", sizeof(msg) - strlen(msg) - 1);
136+
strncat(msg, ref, sizeof(msg) - strlen(msg) - 1);
137+
}
138+
va_end(ap);
139+
strncat(msg, "'", sizeof(msg) - strlen(msg) - 1);
140+
141+
if (count >= 2) {
142+
p_err(msg);
143+
return -1;
144+
}
145+
146+
return 0;
147+
}
148+
120149
void fprint_hex(FILE *f, void *arg, unsigned int n, const char *sep)
121150
{
122151
unsigned char *data = arg;

tools/bpf/bpftool/main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ void p_err(const char *fmt, ...);
101101
void p_info(const char *fmt, ...);
102102

103103
bool is_prefix(const char *pfx, const char *str);
104+
int detect_common_prefix(const char *arg, ...);
104105
void fprint_hex(FILE *f, void *arg, unsigned int n, const char *sep);
105106
void usage(void) __noreturn;
106107

0 commit comments

Comments
 (0)