Implement decoding of BPF_PROG_TEST_RUN command of bpf syscall
* configure.ac: Check for union bpf_attr.test.duration. * bpf.c (decode_BPF_PROG_TEST_RUN): New function. (SYS_FUNC(bpf)) <bpf_cmd_decoders>: Use it. * NEWS: Mention this. * tests/bpf.c: Include "print_fields.h". Add macro guard for BPF_PROG_TEST_RUN decoder test. [HAVE_UNION_BPF_ATTR_TEST_DURATION] (sample_BPF_PROG_TEST_RUN_attr): New variable. [HAVE_UNION_BPF_ATTR_TEST_DURATION] (init_BPF_PROG_TEST_RUN_first, print_BPF_PROG_TEST_RUN_first, init_BPF_PROG_TEST_RUN_attr, print_BPF_PROG_TEST_RUN_attr): New functions. (main) [HAVE_UNION_BPF_ATTR_TEST_DURATION]: Use them.
This commit is contained in:
parent
2d95b53db4
commit
875115da2d
1
NEWS
1
NEWS
@ -4,6 +4,7 @@ Noteworthy changes in release ?.?? (????-??-??)
|
||||
* Improvements
|
||||
* Implemented decoding of netlink descriptor attributes as file descriptors.
|
||||
* Implemented decoding of hugetlb page size selection flags.
|
||||
* Implemented decoding of BPF_PROG_TEST_RUN command of bpf syscall.
|
||||
* Enhanced decoding of getsockopt and setsockopt syscalls for SOL_NETLINK
|
||||
level.
|
||||
* Enhanced decoding of BPF_MAP_CREATE command of bpf syscall.
|
||||
|
27
bpf.c
27
bpf.c
@ -280,6 +280,32 @@ DEF_BPF_CMD_DECODER(BPF_PROG_DETACH)
|
||||
return RVAL_DECODED;
|
||||
}
|
||||
|
||||
DEF_BPF_CMD_DECODER(BPF_PROG_TEST_RUN)
|
||||
{
|
||||
struct {
|
||||
uint32_t prog_fd, retval, data_size_in, data_size_out;
|
||||
uint64_t ATTRIBUTE_ALIGNED(8) data_in, data_out;
|
||||
uint32_t repeat, duration;
|
||||
} attr = {};
|
||||
const unsigned int len = size < sizeof(attr) ? size : sizeof(attr);
|
||||
|
||||
memcpy(&attr, data, len);
|
||||
|
||||
PRINT_FIELD_FD("{test={", attr, prog_fd, tcp);
|
||||
PRINT_FIELD_U(", ", attr, retval);
|
||||
PRINT_FIELD_U(", ", attr, data_size_in);
|
||||
PRINT_FIELD_U(", ", attr, data_size_out);
|
||||
PRINT_FIELD_X(", ", attr, data_in);
|
||||
PRINT_FIELD_X(", ", attr, data_out);
|
||||
PRINT_FIELD_U(", ", attr, repeat);
|
||||
PRINT_FIELD_U(", ", attr, duration);
|
||||
tprints("}");
|
||||
decode_attr_extra_data(tcp, data, size, sizeof(attr));
|
||||
tprints("}");
|
||||
|
||||
return RVAL_DECODED;
|
||||
}
|
||||
|
||||
SYS_FUNC(bpf)
|
||||
{
|
||||
static const bpf_cmd_decoder_t bpf_cmd_decoders[] = {
|
||||
@ -293,6 +319,7 @@ SYS_FUNC(bpf)
|
||||
BPF_CMD_ENTRY(BPF_OBJ_GET),
|
||||
BPF_CMD_ENTRY(BPF_PROG_ATTACH),
|
||||
BPF_CMD_ENTRY(BPF_PROG_DETACH),
|
||||
BPF_CMD_ENTRY(BPF_PROG_TEST_RUN),
|
||||
};
|
||||
|
||||
const unsigned int cmd = tcp->u_arg[0];
|
||||
|
@ -464,6 +464,7 @@ AC_CHECK_HEADERS([linux/bpf.h], [
|
||||
st_CHECK_UNION_BPF_ATTR([flags])
|
||||
st_CHECK_UNION_BPF_ATTR([numa_node])
|
||||
st_CHECK_UNION_BPF_ATTR([prog_flags])
|
||||
AC_CHECK_MEMBERS([union bpf_attr.test.duration],,, [#include <linux/bpf.h>])
|
||||
])
|
||||
|
||||
AC_CHECK_TYPES(m4_normalize([
|
||||
|
68
tests/bpf.c
68
tests/bpf.c
@ -35,7 +35,8 @@
|
||||
|| defined HAVE_UNION_BPF_ATTR_BPF_FD \
|
||||
|| defined HAVE_UNION_BPF_ATTR_FLAGS \
|
||||
|| defined HAVE_UNION_BPF_ATTR_NUMA_NODE \
|
||||
|| defined HAVE_UNION_BPF_ATTR_PROG_FLAGS)
|
||||
|| defined HAVE_UNION_BPF_ATTR_PROG_FLAGS \
|
||||
|| defined HAVE_UNION_BPF_ATTR_TEST_DURATION)
|
||||
|
||||
# include <stddef.h>
|
||||
# include <stdio.h>
|
||||
@ -43,6 +44,7 @@
|
||||
# include <string.h>
|
||||
# include <unistd.h>
|
||||
# include <linux/bpf.h>
|
||||
# include "print_fields.h"
|
||||
|
||||
static const kernel_ulong_t long_bits = (kernel_ulong_t) 0xfacefeed00000000ULL;
|
||||
static const char *errstr;
|
||||
@ -561,6 +563,66 @@ print_BPF_PROG_DETACH_attr(const unsigned long addr)
|
||||
|
||||
# endif /* HAVE_UNION_BPF_ATTR_ATTACH_FLAGS */
|
||||
|
||||
/* BPF_PROG_TEST_RUN command appears in kernel 4.12. */
|
||||
# ifdef HAVE_UNION_BPF_ATTR_TEST_DURATION
|
||||
|
||||
static unsigned int
|
||||
init_BPF_PROG_TEST_RUN_first(const unsigned long eop)
|
||||
{
|
||||
static const union bpf_attr attr = { .test.prog_fd = -1 };
|
||||
static const unsigned int offset = sizeof(attr.test.prog_fd);
|
||||
const unsigned long addr = eop - offset;
|
||||
|
||||
memcpy((void *) addr, &attr.test.prog_fd, offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void
|
||||
print_BPF_PROG_TEST_RUN_first(const unsigned long addr)
|
||||
{
|
||||
printf("test={prog_fd=-1, retval=0, data_size_in=0, data_size_out=0"
|
||||
", data_in=0, data_out=0, repeat=0, duration=0}");
|
||||
}
|
||||
|
||||
static const union bpf_attr sample_BPF_PROG_TEST_RUN_attr = {
|
||||
.test = {
|
||||
.prog_fd = -1,
|
||||
.retval = 0xfac1fed2,
|
||||
.data_size_in = 0xfac3fed4,
|
||||
.data_size_out = 0xfac5fed6,
|
||||
.data_in = (uint64_t) 0xfacef11dbadc2ded,
|
||||
.data_out = (uint64_t) 0xfacef33dbadc4ded,
|
||||
.repeat = 0xfac7fed8,
|
||||
.duration = 0xfac9feda
|
||||
}
|
||||
};
|
||||
static unsigned int
|
||||
init_BPF_PROG_TEST_RUN_attr(const unsigned long eop)
|
||||
{
|
||||
static const unsigned int offset =
|
||||
offsetofend(union bpf_attr, test);
|
||||
const unsigned long addr = eop - offset;
|
||||
|
||||
memcpy((void *) addr, &sample_BPF_PROG_TEST_RUN_attr, offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void
|
||||
print_BPF_PROG_TEST_RUN_attr(const unsigned long addr)
|
||||
{
|
||||
PRINT_FIELD_D("test={", sample_BPF_PROG_TEST_RUN_attr.test, prog_fd);
|
||||
PRINT_FIELD_U(", ", sample_BPF_PROG_TEST_RUN_attr.test, retval);
|
||||
PRINT_FIELD_U(", ", sample_BPF_PROG_TEST_RUN_attr.test, data_size_in);
|
||||
PRINT_FIELD_U(", ", sample_BPF_PROG_TEST_RUN_attr.test, data_size_out);
|
||||
PRINT_FIELD_X(", ", sample_BPF_PROG_TEST_RUN_attr.test, data_in);
|
||||
PRINT_FIELD_X(", ", sample_BPF_PROG_TEST_RUN_attr.test, data_out);
|
||||
PRINT_FIELD_U(", ", sample_BPF_PROG_TEST_RUN_attr.test, repeat);
|
||||
PRINT_FIELD_U(", ", sample_BPF_PROG_TEST_RUN_attr.test, duration);
|
||||
printf("}");
|
||||
}
|
||||
|
||||
# endif /* HAVE_UNION_BPF_ATTR_TEST_DURATION */
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
@ -592,6 +654,10 @@ main(void)
|
||||
TEST_BPF(BPF_PROG_DETACH);
|
||||
# endif
|
||||
|
||||
# ifdef HAVE_UNION_BPF_ATTR_TEST_DURATION
|
||||
TEST_BPF(BPF_PROG_TEST_RUN);
|
||||
# endif
|
||||
|
||||
sys_bpf(0xfacefeed, end_of_page, 40);
|
||||
printf("bpf(0xfacefeed /* BPF_??? */, %#lx, 40) = %s\n",
|
||||
end_of_page, errstr);
|
||||
|
Loading…
Reference in New Issue
Block a user