From 93ef3d32aba0e5d6604896853012563fe0be4614 Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov <evgsyr@gmail.com> Date: Fri, 1 Jun 2018 02:55:21 +0200 Subject: [PATCH] tests: check BPF_OBJ_GET_INFO_BY_FD decoding * tests/bpf-obj_get_info_by_fd-prog-v.c: New file. * tests/bpf-obj_get_info_by_fd-prog.c: Likewise. * tests/bpf-obj_get_info_by_fd-v.c: Likewise. * tests/bpf-obj_get_info_by_fd.c: Likewise. * configure.ac (AC_CHECK_HEADERS): Check for struct bpf_insn, struct bpf_map_info, and struct bpf_prog_info. * tests/pure_executables.list: Add bpf-obj_get_info_by_fd, bpf-obj_get_info_by_fd-v, bpf-obj_get_info_by_fd-prog, and bpf-obj_get_info_by_fd-prog-v. * tests/.gitignore: Likewise. * tests/gen_tests.in (bpf-obj_get_info_by_fd, bpf-obj_get_info_by_fd-v, bpf-obj_get_info_by_fd-prog, bpf-obj_get_info_by_fd-prog-v): New tests. Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org> --- configure.ac | 6 +- tests/.gitignore | 4 + tests/Makefile.am | 4 + tests/bpf-obj_get_info_by_fd-prog-v.c | 3 + tests/bpf-obj_get_info_by_fd-prog.c | 2 + tests/bpf-obj_get_info_by_fd-v.c | 2 + tests/bpf-obj_get_info_by_fd.c | 499 ++++++++++++++++++++++++++ tests/gen_tests.in | 4 + tests/pure_executables.list | 4 + 9 files changed, 527 insertions(+), 1 deletion(-) create mode 100644 tests/bpf-obj_get_info_by_fd-prog-v.c create mode 100644 tests/bpf-obj_get_info_by_fd-prog.c create mode 100644 tests/bpf-obj_get_info_by_fd-v.c create mode 100644 tests/bpf-obj_get_info_by_fd.c diff --git a/configure.ac b/configure.ac index 43197687..f6868f21 100644 --- a/configure.ac +++ b/configure.ac @@ -466,7 +466,11 @@ AC_CHECK_HEADERS([linux/input.h], [ ]) AC_CHECK_HEADERS([linux/bpf.h], [ - AC_CHECK_TYPES([struct bpf_insn],,, [#include <linux/bpf.h>]) + AC_CHECK_TYPES(m4_normalize([ + struct bpf_insn, + struct bpf_map_info, + struct bpf_prog_info + ]),,, [#include <linux/bpf.h>]) st_BPF_ATTR ]) diff --git a/tests/.gitignore b/tests/.gitignore index 13fa77b7..a754f788 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -21,6 +21,10 @@ attach-p-cmd-p block_reset_raise_run bpf bpf-v +bpf-obj_get_info_by_fd +bpf-obj_get_info_by_fd-v +bpf-obj_get_info_by_fd-prog +bpf-obj_get_info_by_fd-prog-v bpf-success bpf-success-v brk diff --git a/tests/Makefile.am b/tests/Makefile.am index 17a82336..3cae26c8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -93,6 +93,10 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \ attach-p-cmd-cmd \ attach-p-cmd-p \ block_reset_raise_run \ + bpf-obj_get_info_by_fd \ + bpf-obj_get_info_by_fd-v \ + bpf-obj_get_info_by_fd-prog \ + bpf-obj_get_info_by_fd-prog-v \ bpf-success \ bpf-success-v \ caps-abbrev \ diff --git a/tests/bpf-obj_get_info_by_fd-prog-v.c b/tests/bpf-obj_get_info_by_fd-prog-v.c new file mode 100644 index 00000000..d7e10b43 --- /dev/null +++ b/tests/bpf-obj_get_info_by_fd-prog-v.c @@ -0,0 +1,3 @@ +#define CHECK_OBJ_PROG 1 +#define VERBOSE 1 +#include "bpf-obj_get_info_by_fd.c" diff --git a/tests/bpf-obj_get_info_by_fd-prog.c b/tests/bpf-obj_get_info_by_fd-prog.c new file mode 100644 index 00000000..19a5f75a --- /dev/null +++ b/tests/bpf-obj_get_info_by_fd-prog.c @@ -0,0 +1,2 @@ +#define CHECK_OBJ_PROG 1 +#include "bpf-obj_get_info_by_fd.c" diff --git a/tests/bpf-obj_get_info_by_fd-v.c b/tests/bpf-obj_get_info_by_fd-v.c new file mode 100644 index 00000000..2debc5f1 --- /dev/null +++ b/tests/bpf-obj_get_info_by_fd-v.c @@ -0,0 +1,2 @@ +#define VERBOSE 1 +#include "bpf-obj_get_info_by_fd.c" diff --git a/tests/bpf-obj_get_info_by_fd.c b/tests/bpf-obj_get_info_by_fd.c new file mode 100644 index 00000000..67b5122a --- /dev/null +++ b/tests/bpf-obj_get_info_by_fd.c @@ -0,0 +1,499 @@ +/* + * Check bpf(BPF_OBJ_GET_INFO_BY_FD) decoding. + * + * Copyright (c) 2018 The strace developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tests.h" + +#ifndef CHECK_OBJ_PROG +# define CHECK_OBJ_PROG 0 +#endif + +#include <inttypes.h> +#include <stddef.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/sysmacros.h> +#include <asm/unistd.h> + +#include "print_fields.h" +#include "scno.h" + +#ifdef HAVE_LINUX_BPF_H +# include <linux/bpf.h> +#endif + +#include "bpf_attr.h" + +#include "xlat.h" +#include "xlat/bpf_map_flags.h" +#include "xlat/bpf_map_types.h" +#include "xlat/bpf_prog_types.h" + +#define XLAT_MACROS_ONLY +#include "xlat/bpf_commands.h" +#include "xlat/bpf_op_alu.h" +#include "xlat/bpf_op_jmp.h" +#include "xlat/bpf_size.h" +#include "xlat/bpf_src.h" +#include "xlat/ebpf_class.h" +#include "xlat/ebpf_mode.h" +#include "xlat/ebpf_op_alu.h" +#include "xlat/ebpf_regs.h" +#include "xlat/ebpf_size.h" + +#ifndef HAVE_STRUCT_BPF_INSN +struct bpf_insn { + uint8_t code; + uint8_t dst_reg:4; + uint8_t src_reg:4; + int16_t off; + int32_t imm; +}; +#endif + +static const char *errstr; + +static long +sys_bpf(kernel_ulong_t cmd, void *attr, kernel_ulong_t size) +{ + long rc = syscall(__NR_bpf, cmd, attr, size); + errstr = sprintrc(rc); + return rc; +} + +static void +print_map_create(void *attr_void, size_t size, long rc) +{ + /* struct BPF_MAP_CREATE_struct *attr = attr_void; */ + + printf("bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_ARRAY, key_size=4" + ", value_size=8, max_entries=1"); + if (size > offsetof(struct BPF_MAP_CREATE_struct, map_flags)) + printf(", map_flags=0"); + if (size > offsetof(struct BPF_MAP_CREATE_struct, inner_map_fd)) + printf(", inner_map_fd=0</dev/null>"); + if (size > offsetof(struct BPF_MAP_CREATE_struct, map_name)) + printf(", map_name=\"test_map\""); + if (size > offsetof(struct BPF_MAP_CREATE_struct, map_ifindex)) + printf(", map_ifindex=0"); + printf("}, %zu) = ", size); + if (rc >= 0) + printf("%ld<anon_inode:bpf-map>\n", rc); + else + puts(errstr); +} + +#if CHECK_OBJ_PROG +static struct bpf_insn socket_prog[] = { + { /* 0 */ + .code = BPF_ALU64 | BPF_K | BPF_MOV, + .dst_reg = BPF_REG_1, + .imm = 0, + }, + { /* 1 */ + .code = BPF_STX | BPF_W | BPF_MEM, + .dst_reg = BPF_REG_10, + .src_reg = BPF_REG_1, + .off = -4, + }, + { /* 2 */ + .code = BPF_ALU64 | BPF_X | BPF_MOV, + .dst_reg = BPF_REG_2, + .src_reg = BPF_REG_10, + }, + { /* 3 */ + .code = BPF_ALU64 | BPF_K | BPF_ADD, + .dst_reg = BPF_REG_2, + .imm = -4, + }, + { /* 4 */ + .code = BPF_LD | BPF_DW | BPF_IMM, + .dst_reg = BPF_REG_1, + .src_reg = 1 /* BPF_PSEUDO_MAP_FD */, + .imm = 0, /* to be set to map fd */ + }, + { /* 5 */ + .imm = 0, + }, + { /* 6 */ + .code = BPF_JMP | BPF_K | BPF_CALL, + .imm = 0x1, /* BPF_FUNC_map_lookup_elem */ + }, + { /* 7 */ + .code = BPF_ALU64 | BPF_K | BPF_MOV, + .dst_reg = BPF_REG_0, + .imm = 0, + }, + { /* 8 */ + .code = BPF_JMP | BPF_K | BPF_EXIT, + }, +}; + +# if VERBOSE +static const char *socket_prog_fmt = + "[{code=BPF_ALU64|BPF_K|BPF_MOV" + ", dst_reg=BPF_REG_1, src_reg=BPF_REG_0, off=0, imm=0}" + ", {code=BPF_STX|BPF_W|BPF_MEM" + ", dst_reg=BPF_REG_10, src_reg=BPF_REG_1, off=-4, imm=0}" + ", {code=BPF_ALU64|BPF_X|BPF_MOV" + ", dst_reg=BPF_REG_2, src_reg=BPF_REG_10, off=0, imm=0}" + ", {code=BPF_ALU64|BPF_K|BPF_ADD" + ", dst_reg=BPF_REG_2, src_reg=BPF_REG_0, off=0, imm=0xfffffffc}" + ", {code=BPF_LD|BPF_DW|BPF_IMM" + ", dst_reg=BPF_REG_1, src_reg=BPF_REG_1, off=0, imm=%#x}" + ", {code=BPF_LD|BPF_W|BPF_IMM" + ", dst_reg=BPF_REG_0, src_reg=BPF_REG_0, off=0, imm=0}" + ", {code=BPF_JMP|BPF_K|BPF_CALL" + ", dst_reg=BPF_REG_0, src_reg=BPF_REG_0, off=0, imm=0x1}" + ", {code=BPF_ALU64|BPF_K|BPF_MOV" + ", dst_reg=BPF_REG_0, src_reg=BPF_REG_0, off=0, imm=0}" + ", {code=BPF_JMP|BPF_K|BPF_EXIT" + ", dst_reg=BPF_REG_0, src_reg=BPF_REG_0, off=0, imm=0}" + "]"; +# endif /* VERBOSE */ + +static const char *license = "BSD"; +static char log_buf[4096]; + +static void +print_prog_load(void *attr_void, size_t size, long rc) +{ + printf("bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_SOCKET_FILTER" + ", insn_cnt=%zu, insns=", ARRAY_SIZE(socket_prog)); +# if VERBOSE + printf(socket_prog_fmt, socket_prog[4].imm); +# else + printf("%p", socket_prog); +# endif + if (size > offsetof(struct BPF_PROG_LOAD_struct, license)) + printf(", license=\"BSD\""); + if (size > offsetof(struct BPF_PROG_LOAD_struct, log_buf)) + printf(", log_level=42, log_size=%zu, log_buf=\"\"", + sizeof(log_buf)); + if (size > offsetof(struct BPF_PROG_LOAD_struct, kern_version)) + printf(", kern_version=KERNEL_VERSION(57005, 192, 222)"); + if (size > offsetof(struct BPF_PROG_LOAD_struct, prog_flags)) + printf(", prog_flags=0"); + if (size > offsetof(struct BPF_PROG_LOAD_struct, prog_name)) + printf(", prog_name=\"test_prog\""); + if (size > offsetof(struct BPF_PROG_LOAD_struct, prog_ifindex)) + printf(", prog_ifindex=0"); + if (size > offsetof(struct BPF_PROG_LOAD_struct, expected_attach_type)) + printf(", expected_attach_type=BPF_CGROUP_INET_INGRESS"); + printf("}, %zu) = ", size); + if (rc >= 0) + printf("%ld<anon_inode:bpf-prog>\n", rc); + else + puts(errstr); +} +#endif /* CHECK_OBJ_PROG */ + +static long +try_bpf(kernel_ulong_t cmd, void (*printer)(void *attr, size_t size, long rc), + void *attr, size_t **sizes) +{ + long rc; + + for (rc = -1; **sizes; (*sizes)++) { + rc = sys_bpf(cmd, attr, **sizes); + printer(attr, **sizes, rc); + + if (rc >= 0) + break; + } + + return rc; +} + +int +main(void) +{ + struct BPF_MAP_CREATE_struct bpf_map_create_attr = { + .map_type = BPF_MAP_TYPE_ARRAY, + .key_size = 4, + .value_size = 8, + .max_entries = 1, + .map_name = "test_map", + }; + size_t bpf_map_create_attr_sizes[] = { + sizeof(bpf_map_create_attr), + offsetofend(struct BPF_MAP_CREATE_struct, max_entries), + 0, + }; + +#if CHECK_OBJ_PROG + struct BPF_PROG_LOAD_struct bpf_prog_load_attr = { + .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, + .insn_cnt = ARRAY_SIZE(socket_prog), + .insns = (uintptr_t) socket_prog, + .license = (uintptr_t) license, + .log_level = 42, + .log_size = sizeof(log_buf), + .log_buf = (uintptr_t) log_buf, + .kern_version = 0xdeadc0de, + .prog_name = "test_prog", + }; + size_t bpf_prog_load_attr_sizes[] = { + sizeof(bpf_prog_load_attr), + offsetofend(struct BPF_PROG_LOAD_struct, prog_name), + offsetofend(struct BPF_PROG_LOAD_struct, prog_flags), + offsetofend(struct BPF_PROG_LOAD_struct, kern_version), + offsetofend(struct BPF_PROG_LOAD_struct, log_buf), + offsetofend(struct BPF_PROG_LOAD_struct, license), + offsetofend(struct BPF_PROG_LOAD_struct, insns), + 0, + }; +#endif /* CHECK_OBJ_PROG */ + + size_t *bpf_map_create_attr_size = bpf_map_create_attr_sizes; + int map_fd = try_bpf(BPF_MAP_CREATE, print_map_create, + &bpf_map_create_attr, &bpf_map_create_attr_size); + if (map_fd < 0) + perror_msg_and_skip("BPF_MAP_CREATE failed"); + +#if CHECK_OBJ_PROG + socket_prog[4].imm = map_fd; + + size_t *bpf_prog_load_attr_size = bpf_prog_load_attr_sizes; + int prog_fd = try_bpf(BPF_PROG_LOAD, print_prog_load, + &bpf_prog_load_attr, &bpf_prog_load_attr_size); + if (prog_fd < 0) + perror_msg_and_skip("BPF_PROG_LOAD failed (log: \"%s\")", + log_buf); +#endif /* CHECK_OBJ_PROG */ + + /* + * This has to be a macro, otherwise the compiler complains that + * initializer element is not constant. + */ + #define MAP_INFO_SZ (sizeof(*map_info) + 64) + struct bpf_map_info_struct *map_info = calloc(1, MAP_INFO_SZ); + struct BPF_OBJ_GET_INFO_BY_FD_struct bpf_map_get_info_attr = { + .bpf_fd = map_fd, + .info_len = MAP_INFO_SZ, + .info = (uintptr_t) map_info, + }; + + int ret = sys_bpf(BPF_OBJ_GET_INFO_BY_FD, &bpf_map_get_info_attr, + sizeof(bpf_map_get_info_attr)); + if (ret < 0) + perror_msg_and_skip("BPF_OBJ_GET_INFO_BY_FD map failed"); + + printf("bpf(BPF_OBJ_GET_INFO_BY_FD" + ", {info={bpf_fd=%d<anon_inode:bpf-map>, info_len=%zu", + map_fd, MAP_INFO_SZ); + if (bpf_map_get_info_attr.info_len != MAP_INFO_SZ) + printf(" => %u", bpf_map_get_info_attr.info_len); + + printf(", info="); +#if VERBOSE + printf("{type="); + printxval(bpf_map_types, map_info->type, "BPF_MAP_TYPE_???"); + PRINT_FIELD_U(", ", *map_info, id); + PRINT_FIELD_U(", ", *map_info, key_size); + PRINT_FIELD_U(", ", *map_info, value_size); + PRINT_FIELD_U(", ", *map_info, max_entries); + printf(", map_flags="); + printflags(bpf_map_flags, map_info->map_flags, "BPF_F_???"); + + if (bpf_map_get_info_attr.info_len > + offsetof(struct bpf_map_info_struct, name)) { + printf(", name="); + print_quoted_cstring(map_info->name, sizeof(map_info->name)); + } + if (bpf_map_get_info_attr.info_len > + offsetof(struct bpf_map_info_struct, ifindex)) + printf(", ifindex=%u", map_info->ifindex); + if (bpf_map_get_info_attr.info_len > + offsetof(struct bpf_map_info_struct, netns_dev)) + printf(", netns_dev=makedev(%u, %u)", + major(map_info->netns_dev), minor(map_info->netns_dev)); + if (bpf_map_get_info_attr.info_len > + offsetof(struct bpf_map_info_struct, netns_ino)) + printf(", netns_ino=%" PRIu64, map_info->netns_ino); + printf("}"); +#else /* !VERBOSE */ + printf("%p", map_info); +#endif /* VERBOSE */ + printf("}}, %zu) = %s\n", sizeof(bpf_map_get_info_attr), errstr); + +#if CHECK_OBJ_PROG + /* + * This has to be a macro, otherwise the compiler complains that + * initializer element is not constant. + */ + #define PROG_INFO_SZ (sizeof(*prog_info) + 64) + struct bpf_prog_info_struct *prog_info = calloc(1, PROG_INFO_SZ); + struct bpf_insn *xlated_prog = tail_alloc(sizeof(*xlated_prog) * 42); + uint32_t *map_ids = tail_alloc(sizeof(*map_ids) * 2); + struct BPF_OBJ_GET_INFO_BY_FD_struct bpf_prog_get_info_attr = { + .bpf_fd = prog_fd, + .info_len = PROG_INFO_SZ, + .info = (uintptr_t) prog_info, + }; + size_t old_prog_info_len = PROG_INFO_SZ; + + for (unsigned int i = 0; i < 4; i++) { + prog_info->jited_prog_len = 0; + switch (i) { + case 1: + prog_info->xlated_prog_insns = + (uintptr_t) (xlated_prog + 42); + prog_info->xlated_prog_len = 336; + prog_info->map_ids = (uintptr_t) (map_ids + 2); + prog_info->nr_map_ids = 2; + break; + case 2: + prog_info->xlated_prog_insns = (uintptr_t) xlated_prog; + /* TODO: check xlated_prog output */ + prog_info->xlated_prog_len = 0; + prog_info->map_ids = (uintptr_t) map_ids; + prog_info->nr_map_ids = 0; + break; + case 3: + prog_info->xlated_prog_insns = (uintptr_t) xlated_prog; + prog_info->xlated_prog_len = 0; + prog_info->map_ids = (uintptr_t) map_ids; + prog_info->nr_map_ids = 2; + break; + } + + ret = sys_bpf(BPF_OBJ_GET_INFO_BY_FD, &bpf_prog_get_info_attr, + sizeof(bpf_prog_get_info_attr)); + if (i != 1 && ret < 0) + perror_msg_and_skip("BPF_OBJ_GET_INFO_BY_FD" + " prog %u failed", i); + + printf("bpf(BPF_OBJ_GET_INFO_BY_FD" + ", {info={bpf_fd=%d<anon_inode:bpf-prog>, info_len=%zu", + prog_fd, old_prog_info_len); + if (!i && bpf_prog_get_info_attr.info_len != PROG_INFO_SZ) + printf(" => %u", bpf_prog_get_info_attr.info_len); + old_prog_info_len = bpf_prog_get_info_attr.info_len; + + printf(", info="); +# if VERBOSE + printf("{type="); + printxval(bpf_prog_types, prog_info->type, "BPF_PROG_TYPE_???"); + PRINT_FIELD_U(", ", *prog_info, id); + printf(", tag="); + print_quoted_hex(prog_info->tag, sizeof(prog_info->tag)); + printf(", jited_prog_len=0"); + if (prog_info->jited_prog_len) + printf(" => %u", prog_info->jited_prog_len); + printf(", jited_prog_insns=NULL"); + switch (i) { + case 0: + printf(", xlated_prog_len=0"); + if (prog_info->xlated_prog_len) + printf(" => %u", prog_info->xlated_prog_len); + printf(", xlated_prog_insns=NULL"); + break; + case 1: + printf(", xlated_prog_len=336"); + if (prog_info->xlated_prog_len != 336) + printf(" => %u", prog_info->xlated_prog_len); + if (prog_info->xlated_prog_len) + printf(", xlated_prog_insns=%p", xlated_prog + 42); + else + printf(", xlated_prog_insns=[]"); + break; + case 2: + case 3: + printf(", xlated_prog_len=0"); + if (prog_info->xlated_prog_len) + printf(" => %u", prog_info->xlated_prog_len); + printf(", xlated_prog_insns=[]"); + break; + } + + if (bpf_prog_get_info_attr.info_len > + offsetof(struct bpf_prog_info_struct, load_time)) + printf(", load_time=%" PRIu64, prog_info->load_time); + if (bpf_prog_get_info_attr.info_len > + offsetof(struct bpf_prog_info_struct, created_by_uid)) + printf(", created_by_uid=%u", + prog_info->created_by_uid); + + if (bpf_prog_get_info_attr.info_len > + offsetof(struct bpf_prog_info_struct, map_ids)) { + switch (i) { + case 0: + printf(", nr_map_ids=0"); + if (prog_info->nr_map_ids) + printf(" => 1"); + printf(", map_ids=NULL"); + break; + case 1: + printf(", nr_map_ids=2, map_ids=%p", + map_ids + 2); + break; + case 2: + printf(", nr_map_ids=0"); + if (prog_info->nr_map_ids) + printf(" => 1"); + printf(", map_ids=[]"); + break; + case 3: + printf(", nr_map_ids=2"); + if (prog_info->nr_map_ids != 2) + printf(" => 1"); + printf(", map_ids=[%u]", map_info->id); + break; + } + } + + if (bpf_prog_get_info_attr.info_len > + offsetof(struct bpf_prog_info_struct, name)) + printf(", name=\"test_prog\""); + if (bpf_prog_get_info_attr.info_len > + offsetof(struct bpf_prog_info_struct, ifindex)) + printf(", ifindex=%u", prog_info->ifindex); + if (bpf_prog_get_info_attr.info_len > + offsetof(struct bpf_prog_info_struct, netns_dev)) + printf(", netns_dev=makedev(%u, %u)", + major(prog_info->netns_dev), + minor(prog_info->netns_dev)); + if (bpf_prog_get_info_attr.info_len > + offsetof(struct bpf_prog_info_struct, netns_ino)) + printf(", netns_ino=%" PRIu64, prog_info->netns_ino); + + printf("}"); +# else /* !VERBOSE */ + printf("%p", prog_info); +# endif /* VERBOSE */ + printf("}}, %zu) = %s\n", + sizeof(bpf_prog_get_info_attr), errstr); + } +#endif /* CHECK_OBJ_PROG */ + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/gen_tests.in b/tests/gen_tests.in index 4400c485..f3518d19 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -37,6 +37,10 @@ aio -a14 -e trace=io_setup,io_submit,io_getevents,io_cancel,io_destroy alarm -a10 bpf -a20 bpf-v -a20 -v -e trace=bpf +bpf-obj_get_info_by_fd -a20 -y -e trace=bpf +bpf-obj_get_info_by_fd-v -a20 -y -v -e trace=bpf +bpf-obj_get_info_by_fd-prog -a20 -y -e trace=bpf +bpf-obj_get_info_by_fd-prog-v -a20 -y -v -e trace=bpf btrfs +ioctl.test chmod -a28 chown -a28 diff --git a/tests/pure_executables.list b/tests/pure_executables.list index 80c8ae75..df84fe66 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -10,6 +10,10 @@ aio alarm bpf bpf-v +bpf-obj_get_info_by_fd +bpf-obj_get_info_by_fd-v +bpf-obj_get_info_by_fd-prog +bpf-obj_get_info_by_fd-prog-v brk btrfs caps -- 2.40.0