char char_data[256];
};
+struct bpf_attr_check {
+ union bpf_attr_data data;
+ size_t size;
+ const char *str;
+ void (*init_fn)(struct bpf_attr_check *check);
+ void (*print_fn)(const struct bpf_attr_check *check,
+ unsigned long addr);
+};
+
+struct bpf_check {
+ kernel_ulong_t cmd;
+ const char *cmd_str;
+ const struct bpf_attr_check *checks;
+ size_t count;
+};
+
static const kernel_ulong_t long_bits = (kernel_ulong_t) 0xfacefeed00000000ULL;
static const char *errstr;
static unsigned int sizeof_attr = sizeof(union bpf_attr_data);
#endif
static void
-test_bpf_(kernel_ulong_t cmd, const char *cmd_str,
- unsigned int (*init_first)(const unsigned long eop),
- void (*print_first)(const unsigned long eop),
- unsigned int (*init_attr)(const unsigned long eop),
- void (*print_attr)(const unsigned long eop))
+print_bpf_attr(const struct bpf_attr_check *check, unsigned long addr)
+{
+ if (check->print_fn)
+ check->print_fn(check, addr);
+ else
+ printf("%s", check->str);
+}
+
+static void
+test_bpf(const struct bpf_check *cmd_check)
{
+ const struct bpf_attr_check *check = 0;
+ const union bpf_attr_data *data = 0;
+ unsigned int offset = 0;
+
/* zero addr */
- sys_bpf(cmd, 0, long_bits | sizeof(union bpf_attr_data));
+ sys_bpf(cmd_check->cmd, 0, long_bits | sizeof(union bpf_attr_data));
printf("bpf(%s, NULL, %u) = %s\n",
- cmd_str, sizeof_attr, errstr);
+ cmd_check->cmd_str, sizeof_attr, errstr);
/* zero size */
unsigned long addr = end_of_page - sizeof_attr;
- sys_bpf(cmd, addr, long_bits);
+ sys_bpf(cmd_check->cmd, addr, long_bits);
printf("bpf(%s, %#lx, 0) = %s\n",
- cmd_str, addr, errstr);
-
- /* the first field only */
- unsigned int offset = init_first(end_of_page);
- addr = end_of_page - offset;
- sys_bpf(cmd, addr, offset);
- printf("bpf(%s, {", cmd_str);
- print_first(addr);
- printf("}, %u) = %s\n", offset, errstr);
-
- /* efault after the first field */
- sys_bpf(cmd, addr, offset + 1);
- printf("bpf(%s, %#lx, %u) = %s\n",
- cmd_str, addr, offset + 1, errstr);
-
- /* the relevant part of bpf_attr_data */
- offset = init_attr(end_of_page);
- addr = end_of_page - offset;
- sys_bpf(cmd, addr, offset);
- printf("bpf(%s, {", cmd_str);
- print_attr(addr);
- printf("}, %u) = %s\n", offset, errstr);
-
- /* short read of the relevant part of bpf_attr_data */
- sys_bpf(cmd, addr + 1, offset);
- printf("bpf(%s, %#lx, %u) = %s\n",
- cmd_str, addr + 1, offset, errstr);
+ cmd_check->cmd_str, addr, errstr);
+
+ for (size_t i = 0; i < cmd_check->count; i++) {
+ check = &cmd_check->checks[i];
+ if (check->init_fn)
+ check->init_fn((struct bpf_attr_check *) check);
+ data = &check->data;
+ offset = check->size;
+
+ addr = end_of_page - offset;
+ memcpy((void *) addr, data, offset);
+
+ /* starting piece of bpf_attr_data */
+ sys_bpf(cmd_check->cmd, addr, offset);
+ printf("bpf(%s, {", cmd_check->cmd_str);
+ print_bpf_attr(check, addr);
+ printf("}, %u) = %s\n", offset, errstr);
+
+ /* short read of the starting piece */
+ sys_bpf(cmd_check->cmd, addr + 1, offset);
+ printf("bpf(%s, %#lx, %u) = %s\n",
+ cmd_check->cmd_str, addr + 1, offset, errstr);
+ }
if (offset < sizeof_attr) {
/* short read of the whole bpf_attr_data */
- memmove((void *) end_of_page - sizeof_attr + 1,
- (void *) addr, offset);
+ memcpy((void *) end_of_page - sizeof_attr + 1, data, offset);
addr = end_of_page - sizeof_attr + 1;
- memset((void *) addr + offset, 0,
- sizeof_attr - offset - 1);
- sys_bpf(cmd, addr, sizeof_attr);
+ memset((void *) addr + offset, 0, sizeof_attr - offset - 1);
+ sys_bpf(cmd_check->cmd, addr, sizeof_attr);
printf("bpf(%s, %#lx, %u) = %s\n",
- cmd_str, addr, sizeof_attr, errstr);
+ cmd_check->cmd_str, addr, sizeof_attr, errstr);
/* the whole bpf_attr_data */
- memmove((void *) end_of_page - sizeof_attr,
- (void *) addr, offset);
+ memcpy((void *) end_of_page - sizeof_attr, data, offset);
addr = end_of_page - sizeof_attr;
- memset((void *) addr + offset, 0,
- sizeof_attr - offset);
- sys_bpf(cmd, addr, sizeof_attr);
- printf("bpf(%s, {", cmd_str);
- print_attr(addr);
+ memset((void *) addr + offset, 0, sizeof_attr - offset);
+ sys_bpf(cmd_check->cmd, addr, sizeof_attr);
+ printf("bpf(%s, {", cmd_check->cmd_str);
+ print_bpf_attr(check, addr);
printf("}, %u) = %s\n", sizeof_attr, errstr);
/* non-zero bytes after the relevant part */
fill_memory_ex((void *) addr + offset,
sizeof_attr - offset, '0', 10);
- sys_bpf(cmd, addr, sizeof_attr);
- printf("bpf(%s, {", cmd_str);
- print_attr(addr);
+ sys_bpf(cmd_check->cmd, addr, sizeof_attr);
+ printf("bpf(%s, {", cmd_check->cmd_str);
+ print_bpf_attr(check, addr);
printf(", ");
print_extra_data((char *) addr, offset,
sizeof_attr - offset);
}
/* short read of the whole page */
- memmove((void *) end_of_page - page_size + 1,
- (void *) addr, offset);
+ memcpy((void *) end_of_page - page_size + 1, data, offset);
addr = end_of_page - page_size + 1;
- memset((void *) addr + offset, 0,
- page_size - offset - 1);
- sys_bpf(cmd, addr, page_size);
+ memset((void *) addr + offset, 0, page_size - offset - 1);
+ sys_bpf(cmd_check->cmd, addr, page_size);
printf("bpf(%s, %#lx, %u) = %s\n",
- cmd_str, addr, page_size, errstr);
+ cmd_check->cmd_str, addr, page_size, errstr);
/* the whole page */
- memmove((void *) end_of_page - page_size,
- (void *) addr, offset);
+ memcpy((void *) end_of_page - page_size, data, offset);
addr = end_of_page - page_size;
memset((void *) addr + offset, 0, page_size - offset);
- sys_bpf(cmd, addr, page_size);
- printf("bpf(%s, {", cmd_str);
- print_attr(addr);
+ sys_bpf(cmd_check->cmd, addr, page_size);
+ printf("bpf(%s, {", cmd_check->cmd_str);
+ print_bpf_attr(check, addr);
printf("}, %u) = %s\n", page_size, errstr);
/* non-zero bytes after the whole bpf_attr_data */
fill_memory_ex((void *) addr + offset,
page_size - offset, '0', 10);
- sys_bpf(cmd, addr, page_size);
- printf("bpf(%s, {", cmd_str);
- print_attr(addr);
+ sys_bpf(cmd_check->cmd, addr, page_size);
+ printf("bpf(%s, {", cmd_check->cmd_str);
+ print_bpf_attr(check, addr);
printf(", ");
print_extra_data((char *) addr, offset,
page_size - offset);
printf("}, %u) = %s\n", page_size, errstr);
/* more than a page */
- sys_bpf(cmd, addr, page_size + 1);
+ sys_bpf(cmd_check->cmd, addr, page_size + 1);
printf("bpf(%s, %#lx, %u) = %s\n",
- cmd_str, addr, page_size + 1, errstr);
-}
-
-#define TEST_BPF(cmd_) \
- test_bpf_((cmd_), #cmd_, \
- init_ ## cmd_ ## _first, print_ ## cmd_ ## _first, \
- init_ ## cmd_ ## _attr, print_ ## cmd_ ## _attr) \
- /* End of TEST_BPF definition. */
-
-#define DEF_BPF_INIT_FIRST(cmd_, field_, value_) \
- static unsigned int \
- init_ ## cmd_ ## _first(const unsigned long eop) \
- { \
- static const struct cmd_ ## _struct attr = { \
- .field_ = value_ \
- }; \
- static const unsigned int offset = sizeof(attr.field_); \
- const unsigned long addr = eop - offset; \
- \
- memcpy((void *) addr, &attr.field_, offset); \
- return offset; \
- } \
- /* End of DEF_INIT_FIRST definition. */
-
-DEF_BPF_INIT_FIRST(BPF_MAP_CREATE, map_type, 2)
-
-static void
-print_BPF_MAP_CREATE_first(const unsigned long addr)
-{
- printf("map_type=BPF_MAP_TYPE_ARRAY, key_size=0, value_size=0"
- ", max_entries=0, map_flags=0, inner_map_fd=0");
-}
-
-static unsigned int
-init_BPF_MAP_CREATE_attr(const unsigned long eop)
-{
- static const struct BPF_MAP_CREATE_struct attr = {
- .map_type = 1,
- .key_size = 4,
- .value_size = 8,
- .max_entries = 256,
- .map_flags = 7,
- .inner_map_fd = -1,
- .numa_node = 42
- };
- static const unsigned int offset =
- offsetofend(struct BPF_MAP_CREATE_struct, numa_node);
- const unsigned long addr = eop - offset;
-
- memcpy((void *) addr, &attr, offset);
- return offset;
-}
-
-static void
-print_BPF_MAP_CREATE_attr(const unsigned long addr)
-{
- printf("map_type=BPF_MAP_TYPE_HASH, key_size=4"
- ", value_size=8, max_entries=256"
- ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NO_COMMON_LRU"
- "|BPF_F_NUMA_NODE, inner_map_fd=-1, numa_node=42");
-}
-
-DEF_BPF_INIT_FIRST(BPF_MAP_LOOKUP_ELEM, map_fd, -1)
-
-static void
-print_BPF_MAP_LOOKUP_ELEM_first(const unsigned long addr)
-{
- printf("map_fd=-1, key=0, value=0");
-}
-
-static unsigned int
-init_BPF_MAP_LOOKUP_ELEM_attr(const unsigned long eop)
-{
- static const struct BPF_MAP_LOOKUP_ELEM_struct attr = {
- .map_fd = -1,
- .key = 0xdeadbeef,
- .value = 0xbadc0ded
- };
- static const unsigned int offset =
- offsetofend(struct BPF_MAP_LOOKUP_ELEM_struct, value);
- const unsigned long addr = eop - offset;
-
- memcpy((void *) addr, &attr, offset);
- return offset;
-}
-
-static void
-print_BPF_MAP_LOOKUP_ELEM_attr(const unsigned long addr)
-{
- printf("map_fd=-1, key=0xdeadbeef, value=0xbadc0ded");
-}
-
-#define init_BPF_MAP_UPDATE_ELEM_first init_BPF_MAP_LOOKUP_ELEM_first
-
-static void
-print_BPF_MAP_UPDATE_ELEM_first(const unsigned long addr)
-{
- printf("map_fd=-1, key=0, value=0, flags=BPF_ANY");
-}
-
-static unsigned int
-init_BPF_MAP_UPDATE_ELEM_attr(const unsigned long eop)
-{
- static const struct BPF_MAP_UPDATE_ELEM_struct attr = {
- .map_fd = -1,
- .key = 0xdeadbeef,
- .value = 0xbadc0ded,
- .flags = 2
- };
- static const unsigned int offset =
- offsetofend(struct BPF_MAP_UPDATE_ELEM_struct, flags);
- const unsigned long addr = eop - offset;
-
- memcpy((void *) addr, &attr, offset);
- return offset;
-}
-
-static void
-print_BPF_MAP_UPDATE_ELEM_attr(const unsigned long addr)
-{
- printf("map_fd=-1, key=0xdeadbeef, value=0xbadc0ded, flags=BPF_EXIST");
-}
-
-#define init_BPF_MAP_DELETE_ELEM_first init_BPF_MAP_LOOKUP_ELEM_first
-
-static void
-print_BPF_MAP_DELETE_ELEM_first(const unsigned long addr)
-{
- printf("map_fd=-1, key=0");
-}
-
-static unsigned int
-init_BPF_MAP_DELETE_ELEM_attr(const unsigned long eop)
-{
- static const struct BPF_MAP_DELETE_ELEM_struct attr = {
- .map_fd = -1,
- .key = 0xdeadbeef
- };
- static const unsigned int offset =
- offsetofend(struct BPF_MAP_DELETE_ELEM_struct, key);
- const unsigned long addr = eop - offset;
-
- memcpy((void *) addr, &attr, offset);
- return offset;
-}
-
-static void
-print_BPF_MAP_DELETE_ELEM_attr(const unsigned long addr)
-{
- printf("map_fd=-1, key=0xdeadbeef");
-}
-
-#define init_BPF_MAP_GET_NEXT_KEY_first init_BPF_MAP_LOOKUP_ELEM_first
-
-static void
-print_BPF_MAP_GET_NEXT_KEY_first(const unsigned long addr)
-{
- printf("map_fd=-1, key=0, next_key=0");
-}
-
-static unsigned int
-init_BPF_MAP_GET_NEXT_KEY_attr(const unsigned long eop)
-{
- static const struct BPF_MAP_GET_NEXT_KEY_struct attr = {
- .map_fd = -1,
- .key = 0xdeadbeef,
- .next_key = 0xbadc0ded
- };
- static const unsigned int offset =
- offsetofend(struct BPF_MAP_GET_NEXT_KEY_struct, next_key);
- const unsigned long addr = eop - offset;
-
- memcpy((void *) addr, &attr, offset);
- return offset;
-}
+ cmd_check->cmd_str, addr, page_size + 1, errstr);
+}
+
+static const struct bpf_attr_check BPF_MAP_CREATE_checks[] = {
+ {
+ .data = { .BPF_MAP_CREATE_data = { .map_type = 2 } },
+ .size = offsetofend(struct BPF_MAP_CREATE_struct, map_type),
+ .str = "map_type=BPF_MAP_TYPE_ARRAY, key_size=0, value_size=0"
+ ", max_entries=0, map_flags=0, inner_map_fd=0"
+ },
+ {
+ .data = { .BPF_MAP_CREATE_data = {
+ .map_type = 1,
+ .key_size = 4,
+ .value_size = 8,
+ .max_entries = 256,
+ .map_flags = 7,
+ .inner_map_fd = -1,
+ .numa_node = 42
+ } },
+ .size = offsetofend(struct BPF_MAP_CREATE_struct, numa_node),
+ .str = "map_type=BPF_MAP_TYPE_HASH, key_size=4"
+ ", value_size=8, max_entries=256"
+ ", map_flags=BPF_F_NO_PREALLOC|BPF_F_NO_COMMON_LRU"
+ "|BPF_F_NUMA_NODE, inner_map_fd=-1, numa_node=42"
+ }
+};
-static void
-print_BPF_MAP_GET_NEXT_KEY_attr(const unsigned long addr)
-{
- printf("map_fd=-1, key=0xdeadbeef, next_key=0xbadc0ded");
-}
+static const struct bpf_attr_check BPF_MAP_LOOKUP_ELEM_checks[] = {
+ {
+ .data = { .BPF_MAP_LOOKUP_ELEM_data = { .map_fd = -1 } },
+ .size = offsetofend(struct BPF_MAP_LOOKUP_ELEM_struct, map_fd),
+ .str = "map_fd=-1, key=0, value=0"
+ },
+ {
+ .data = { .BPF_MAP_LOOKUP_ELEM_data = {
+ .map_fd = -1,
+ .key = 0xdeadbeef,
+ .value = 0xbadc0ded
+ } },
+ .size = offsetofend(struct BPF_MAP_LOOKUP_ELEM_struct, value),
+ .str = "map_fd=-1, key=0xdeadbeef, value=0xbadc0ded"
+ }
+};
-DEF_BPF_INIT_FIRST(BPF_PROG_LOAD, prog_type, 1)
+static const struct bpf_attr_check BPF_MAP_UPDATE_ELEM_checks[] = {
+ {
+ .data = { .BPF_MAP_UPDATE_ELEM_data = { .map_fd = -1 } },
+ .size = offsetofend(struct BPF_MAP_UPDATE_ELEM_struct, map_fd),
+ .str = "map_fd=-1, key=0, value=0, flags=BPF_ANY"
+ },
+ {
+ .data = { .BPF_MAP_UPDATE_ELEM_data = {
+ .map_fd = -1,
+ .key = 0xdeadbeef,
+ .value = 0xbadc0ded,
+ .flags = 2
+ } },
+ .size = offsetofend(struct BPF_MAP_UPDATE_ELEM_struct, flags),
+ .str = "map_fd=-1, key=0xdeadbeef, value=0xbadc0ded"
+ ", flags=BPF_EXIST"
+ }
+};
-static void
-print_BPF_PROG_LOAD_first(const unsigned long addr)
-{
+static const struct bpf_attr_check BPF_MAP_DELETE_ELEM_checks[] = {
+ {
+ .data = { .BPF_MAP_DELETE_ELEM_data = { .map_fd = -1 } },
+ .size = offsetofend(struct BPF_MAP_DELETE_ELEM_struct, map_fd),
+ .str = "map_fd=-1, key=0"
+ },
+ {
+ .data = { .BPF_MAP_DELETE_ELEM_data = {
+ .map_fd = -1,
+ .key = 0xdeadbeef
+ } },
+ .size = offsetofend(struct BPF_MAP_DELETE_ELEM_struct, key),
+ .str = "map_fd=-1, key=0xdeadbeef"
+ }
+};
- printf("prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=0, insns=0"
- ", license=NULL");
-}
+static const struct bpf_attr_check BPF_MAP_GET_NEXT_KEY_checks[] = {
+ {
+ .data = { .BPF_MAP_GET_NEXT_KEY_data = { .map_fd = -1 } },
+ .size = offsetofend(struct BPF_MAP_GET_NEXT_KEY_struct, map_fd),
+ .str = "map_fd=-1, key=0, next_key=0"
+ },
+ {
+ .data = { .BPF_MAP_GET_NEXT_KEY_data = {
+ .map_fd = -1,
+ .key = 0xdeadbeef,
+ .next_key = 0xbadc0ded
+ } },
+ .size = offsetofend(struct BPF_MAP_GET_NEXT_KEY_struct, next_key),
+ .str = "map_fd=-1, key=0xdeadbeef, next_key=0xbadc0ded"
+ }
+};
static const struct bpf_insn insns[] = {
{ .code = 0x95 }
};
+static const char license[] = "GPL";
static char log_buf[4096];
+static const char pathname[] = "/sys/fs/bpf/foo/bar";
-static unsigned int
-init_BPF_PROG_LOAD_attr(const unsigned long eop)
+static void
+init_BPF_PROG_LOAD_attr(struct bpf_attr_check *check)
{
- const struct BPF_PROG_LOAD_struct attr = {
- .prog_type = 1,
- .insn_cnt = ARRAY_SIZE(insns),
- .insns = (uintptr_t) insns,
- .license = (uintptr_t) "GPL",
- .log_level = 42,
- .log_size = sizeof(log_buf),
- .log_buf = (uintptr_t) log_buf,
- .kern_version = 0xcafef00d,
- .prog_flags = 1
- };
- static const unsigned int offset =
- offsetofend(struct BPF_PROG_LOAD_struct, prog_flags);
- const unsigned long addr = eop - offset;
-
- memcpy((void *) addr, &attr, offset);
- return offset;
+ struct BPF_PROG_LOAD_struct *attr = &check->data.BPF_PROG_LOAD_data;
+ attr->insns = (uintptr_t) insns;
+ attr->license = (uintptr_t) license;
+ attr->log_buf = (uintptr_t) log_buf;
}
static void
-print_BPF_PROG_LOAD_attr(const unsigned long addr)
+print_BPF_PROG_LOAD_attr(const struct bpf_attr_check *check, unsigned long addr)
{
printf("prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=%u, insns=%p"
- ", license=\"GPL\", log_level=42, log_size=4096, log_buf=%p"
+ ", license=\"%s\", log_level=42, log_size=4096, log_buf=%p"
", kern_version=KERNEL_VERSION(51966, 240, 13)"
", prog_flags=BPF_F_STRICT_ALIGNMENT",
(unsigned int) ARRAY_SIZE(insns), insns,
- log_buf);
-}
-
-DEF_BPF_INIT_FIRST(BPF_OBJ_PIN, pathname, 0)
-
-static void
-print_BPF_OBJ_PIN_first(const unsigned long addr)
-{
-
- printf("pathname=NULL, bpf_fd=0");
-}
-
-static unsigned int
-init_BPF_OBJ_PIN_attr(const unsigned long eop)
-{
- const struct BPF_OBJ_PIN_struct attr = {
- .pathname = (uintptr_t) "/sys/fs/bpf/foo/bar",
- .bpf_fd = -1
- };
- static const unsigned int offset =
- offsetofend(struct BPF_OBJ_PIN_struct, bpf_fd);
- const unsigned long addr = eop - offset;
-
- memcpy((void *) addr, &attr, offset);
- return offset;
-}
-
-static void
-print_BPF_OBJ_PIN_attr(const unsigned long addr)
-{
- printf("pathname=\"/sys/fs/bpf/foo/bar\", bpf_fd=-1");
-}
-
-#define init_BPF_OBJ_GET_first init_BPF_OBJ_PIN_first
-#define print_BPF_OBJ_GET_first print_BPF_OBJ_PIN_first
-#define init_BPF_OBJ_GET_attr init_BPF_OBJ_PIN_attr
-#define print_BPF_OBJ_GET_attr print_BPF_OBJ_PIN_attr
-
-DEF_BPF_INIT_FIRST(BPF_PROG_ATTACH, target_fd, -1)
-
-static void
-print_BPF_PROG_ATTACH_first(const unsigned long addr)
-{
- printf("target_fd=-1, attach_bpf_fd=0"
- ", attach_type=BPF_CGROUP_INET_INGRESS, attach_flags=0");
-}
-
-static unsigned int
-init_BPF_PROG_ATTACH_attr(const unsigned long eop)
-{
- static const struct BPF_PROG_ATTACH_struct attr = {
- .target_fd = -1,
- .attach_bpf_fd = -2,
- .attach_type = 2,
- .attach_flags = 1
- };
- static const unsigned int offset =
- offsetofend(struct BPF_PROG_ATTACH_struct, attach_flags);
- const unsigned long addr = eop - offset;
-
- memcpy((void *) addr, &attr, offset);
- return offset;
-}
-
-static void
-print_BPF_PROG_ATTACH_attr(const unsigned long addr)
-{
- printf("target_fd=-1, attach_bpf_fd=-2"
- ", attach_type=BPF_CGROUP_INET_SOCK_CREATE"
- ", attach_flags=BPF_F_ALLOW_OVERRIDE");
-}
-
-#define init_BPF_PROG_DETACH_first init_BPF_PROG_ATTACH_first
-
-static unsigned int
-init_BPF_PROG_DETACH_attr(const unsigned long eop)
-{
- static const struct BPF_PROG_DETACH_struct attr = {
- .target_fd = -1,
- .attach_type = 2
- };
- static const unsigned int offset =
- offsetofend(struct BPF_PROG_DETACH_struct, attach_type);
- const unsigned long addr = eop - offset;
-
- memcpy((void *) addr, &attr, offset);
- return offset;
-}
-
-
-static void
-print_BPF_PROG_DETACH_first(const unsigned long addr)
-{
- printf("target_fd=-1, attach_type=BPF_CGROUP_INET_INGRESS");
-}
-
-static void
-print_BPF_PROG_DETACH_attr(const unsigned long addr)
-{
- printf("target_fd=-1, attach_type=BPF_CGROUP_INET_SOCK_CREATE");
-}
-
-DEF_BPF_INIT_FIRST(BPF_PROG_TEST_RUN, prog_fd, -1)
-
-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 struct BPF_PROG_TEST_RUN_struct sample_BPF_PROG_TEST_RUN_attr = {
- .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
+ license, log_buf);
+}
+
+static struct bpf_attr_check BPF_PROG_LOAD_checks[] = {
+ {
+ .data = { .BPF_PROG_LOAD_data = { .prog_type = 1 } },
+ .size = offsetofend(struct BPF_PROG_LOAD_struct, prog_type),
+ .str = "prog_type=BPF_PROG_TYPE_SOCKET_FILTER"
+ ", insn_cnt=0, insns=0, license=NULL"
+ },
+ {
+ .data = { .BPF_PROG_LOAD_data = {
+ .prog_type = 1,
+ .insn_cnt = ARRAY_SIZE(insns),
+ .log_level = 42,
+ .log_size = sizeof(log_buf),
+ .kern_version = 0xcafef00d,
+ .prog_flags = 1
+ } },
+ .size = offsetofend(struct BPF_PROG_LOAD_struct, prog_flags),
+ .init_fn = init_BPF_PROG_LOAD_attr,
+ .print_fn = print_BPF_PROG_LOAD_attr
+ }
};
-static unsigned int
-init_BPF_PROG_TEST_RUN_attr(const unsigned long eop)
-{
- static const unsigned int offset =
- offsetofend(struct BPF_PROG_TEST_RUN_struct, duration);
- 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, prog_fd);
- PRINT_FIELD_U(", ", sample_BPF_PROG_TEST_RUN_attr, retval);
- PRINT_FIELD_U(", ", sample_BPF_PROG_TEST_RUN_attr, data_size_in);
- PRINT_FIELD_U(", ", sample_BPF_PROG_TEST_RUN_attr, data_size_out);
- PRINT_FIELD_X(", ", sample_BPF_PROG_TEST_RUN_attr, data_in);
- PRINT_FIELD_X(", ", sample_BPF_PROG_TEST_RUN_attr, data_out);
- PRINT_FIELD_U(", ", sample_BPF_PROG_TEST_RUN_attr, repeat);
- PRINT_FIELD_U(", ", sample_BPF_PROG_TEST_RUN_attr, duration);
- printf("}");
-}
-
-DEF_BPF_INIT_FIRST(BPF_PROG_GET_NEXT_ID, start_id, 0xdeadbeef)
static void
-print_BPF_PROG_GET_NEXT_ID_first(const unsigned long addr)
-{
- printf("start_id=%u, next_id=0", 0xdeadbeef);
-}
-
-static unsigned int
-init_BPF_PROG_GET_NEXT_ID_attr(const unsigned long eop)
-{
- static const struct BPF_PROG_GET_NEXT_ID_struct attr = {
- .start_id = 0xbadc0ded,
- .next_id = 0xcafef00d
- };
- static const unsigned int offset =
- offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, next_id);
- const unsigned long addr = eop - offset;
-
- memcpy((void *) addr, &attr, offset);
- return offset;
-}
-
-static void
-print_BPF_PROG_GET_NEXT_ID_attr(const unsigned long addr)
-{
- printf("start_id=%u, next_id=%u", 0xbadc0ded, 0xcafef00d);
-}
-
-#define init_BPF_MAP_GET_NEXT_ID_first init_BPF_PROG_GET_NEXT_ID_first
-#define print_BPF_MAP_GET_NEXT_ID_first print_BPF_PROG_GET_NEXT_ID_first
-#define init_BPF_MAP_GET_NEXT_ID_attr init_BPF_PROG_GET_NEXT_ID_attr
-#define print_BPF_MAP_GET_NEXT_ID_attr print_BPF_PROG_GET_NEXT_ID_attr
-
-#define init_BPF_PROG_GET_FD_BY_ID_first init_BPF_PROG_GET_NEXT_ID_first
-#define init_BPF_PROG_GET_FD_BY_ID_attr init_BPF_PROG_GET_NEXT_ID_attr
-
-static void
-print_BPF_PROG_GET_FD_BY_ID_first(const unsigned long addr)
-{
- printf("prog_id=%u, next_id=0", 0xdeadbeef);
-}
+init_BPF_OBJ_PIN_attr(struct bpf_attr_check *check)
+{
+ struct BPF_OBJ_PIN_struct *attr = &check->data.BPF_OBJ_PIN_data;
+ attr->pathname = (uintptr_t) pathname;
+}
+
+static struct bpf_attr_check BPF_OBJ_PIN_checks[] = {
+ {
+ .data = { .BPF_OBJ_PIN_data = { .pathname = 0 } },
+ .size = offsetofend(struct BPF_OBJ_PIN_struct, pathname),
+ .str = "pathname=NULL, bpf_fd=0"
+ },
+ {
+ .data = { .BPF_OBJ_PIN_data = { .bpf_fd = -1 } },
+ .size = offsetofend(struct BPF_OBJ_PIN_struct, bpf_fd),
+ .init_fn = init_BPF_OBJ_PIN_attr,
+ .str = "pathname=\"/sys/fs/bpf/foo/bar\", bpf_fd=-1"
+ }
+};
-static void
-print_BPF_PROG_GET_FD_BY_ID_attr(const unsigned long addr)
-{
- printf("prog_id=%u, next_id=%u", 0xbadc0ded, 0xcafef00d);
-}
+#define BPF_OBJ_GET_checks BPF_OBJ_PIN_checks
+
+static const struct bpf_attr_check BPF_PROG_ATTACH_checks[] = {
+ {
+ .data = { .BPF_PROG_ATTACH_data = { .target_fd = -1 } },
+ .size = offsetofend(struct BPF_PROG_ATTACH_struct, target_fd),
+ .str = "target_fd=-1, attach_bpf_fd=0"
+ ", attach_type=BPF_CGROUP_INET_INGRESS, attach_flags=0"
+ },
+ {
+ .data = { .BPF_PROG_ATTACH_data = {
+ .target_fd = -1,
+ .attach_bpf_fd = -2,
+ .attach_type = 2,
+ .attach_flags = 1
+ } },
+ .size = offsetofend(struct BPF_PROG_ATTACH_struct, attach_flags),
+ .str = "target_fd=-1, attach_bpf_fd=-2"
+ ", attach_type=BPF_CGROUP_INET_SOCK_CREATE"
+ ", attach_flags=BPF_F_ALLOW_OVERRIDE"
+ }
+};
-#define init_BPF_MAP_GET_FD_BY_ID_first init_BPF_PROG_GET_NEXT_ID_first
-#define init_BPF_MAP_GET_FD_BY_ID_attr init_BPF_PROG_GET_NEXT_ID_attr
-static void
-print_BPF_MAP_GET_FD_BY_ID_first(const unsigned long addr)
-{
- printf("map_id=%u, next_id=0", 0xdeadbeef);
-}
+static const struct bpf_attr_check BPF_PROG_DETACH_checks[] = {
+ {
+ .data = { .BPF_PROG_DETACH_data = { .target_fd = -1 } },
+ .size = offsetofend(struct BPF_PROG_DETACH_struct, target_fd),
+ .str = "target_fd=-1, attach_type=BPF_CGROUP_INET_INGRESS"
+ },
+ {
+ .data = { .BPF_PROG_DETACH_data = {
+ .target_fd = -1,
+ .attach_type = 2
+ } },
+ .size = offsetofend(struct BPF_PROG_DETACH_struct, attach_type),
+ .str = "target_fd=-1, attach_type=BPF_CGROUP_INET_SOCK_CREATE"
+ }
+};
-static void
-print_BPF_MAP_GET_FD_BY_ID_attr(const unsigned long addr)
-{
- printf("map_id=%u, next_id=%u", 0xbadc0ded, 0xcafef00d);
-}
+static const struct bpf_attr_check BPF_PROG_TEST_RUN_checks[] = {
+ {
+ .data = { .BPF_PROG_TEST_RUN_data = { .prog_fd = -1 } },
+ .size = offsetofend(struct BPF_PROG_TEST_RUN_struct, prog_fd),
+ .str = "test={prog_fd=-1, retval=0, data_size_in=0"
+ ", data_size_out=0, data_in=0, data_out=0"
+ ", repeat=0, duration=0}"
+ },
+ {
+ .data = { .BPF_PROG_TEST_RUN_data = {
+ .prog_fd = -1,
+ .retval = 0xfac1fed2,
+ .data_size_in = 0xfac3fed4,
+ .data_size_out = 0xfac5fed6,
+ .data_in = (uint64_t) 0xfacef11dbadc2dedULL,
+ .data_out = (uint64_t) 0xfacef33dbadc4dedULL,
+ .repeat = 0xfac7fed8,
+ .duration = 0xfac9feda
+ } },
+ .size = offsetofend(struct BPF_PROG_TEST_RUN_struct, duration),
+ .str = "test={prog_fd=-1, retval=4207017682"
+ ", data_size_in=4207148756, data_size_out=4207279830"
+ ", data_in=0xfacef11dbadc2ded"
+ ", data_out=0xfacef33dbadc4ded"
+ ", repeat=4207410904, duration=4207541978}"
+ }
+};
-DEF_BPF_INIT_FIRST(BPF_OBJ_GET_INFO_BY_FD, bpf_fd, -1)
+static const struct bpf_attr_check BPF_PROG_GET_NEXT_ID_checks[] = {
+ {
+ .data = { .BPF_PROG_GET_NEXT_ID_data = {
+ .start_id = 0xdeadbeef
+ } },
+ .size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, start_id),
+ .str = "start_id=3735928559, next_id=0"
+ },
+ {
+ .data = { .BPF_PROG_GET_NEXT_ID_data = {
+ .start_id = 0xbadc0ded,
+ .next_id = 0xcafef00d
+ } },
+ .size = offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, next_id),
+ .str = "start_id=3134983661, next_id=3405705229"
+ }
+};
-static void
-print_BPF_OBJ_GET_INFO_BY_FD_first(const unsigned long addr)
-{
- printf("info={bpf_fd=-1, info_len=0, info=0}");
-}
+#define BPF_MAP_GET_NEXT_ID_checks BPF_PROG_GET_NEXT_ID_checks
+
+static const struct bpf_attr_check BPF_PROG_GET_FD_BY_ID_checks[] = {
+ {
+ .data = { .BPF_PROG_GET_FD_BY_ID_data = {
+ .prog_id = 0xdeadbeef
+ } },
+ .size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, prog_id),
+ .str = "prog_id=3735928559, next_id=0"
+ },
+ {
+ .data = { .BPF_PROG_GET_FD_BY_ID_data = {
+ .prog_id = 0xbadc0ded,
+ .next_id = 0xcafef00d
+ } },
+ .size = offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, next_id),
+ .str = "prog_id=3134983661, next_id=3405705229"
+ }
+};
-static const struct BPF_OBJ_GET_INFO_BY_FD_struct
- sample_BPF_OBJ_GET_INFO_BY_FD_attr = {
- .bpf_fd = -1,
- .info_len = 0xdeadbeef,
- .info = (uint64_t) 0xfacefeedbadc0ded
- };
-static unsigned int
-init_BPF_OBJ_GET_INFO_BY_FD_attr(const unsigned long eop)
-{
- static const unsigned int offset =
- offsetofend(struct BPF_OBJ_GET_INFO_BY_FD_struct, info);
- const unsigned long addr = eop - offset;
+static const struct bpf_attr_check BPF_MAP_GET_FD_BY_ID_checks[] = {
+ {
+ .data = { .BPF_MAP_GET_FD_BY_ID_data = {
+ .map_id = 0xdeadbeef
+ } },
+ .size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, map_id),
+ .str = "map_id=3735928559, next_id=0"
+ },
+ {
+ .data = { .BPF_MAP_GET_FD_BY_ID_data = {
+ .map_id = 0xbadc0ded,
+ .next_id = 0xcafef00d
+ } },
+ .size = offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, next_id),
+ .str = "map_id=3134983661, next_id=3405705229"
+ }
+};
- memcpy((void *) addr, &sample_BPF_OBJ_GET_INFO_BY_FD_attr, offset);
- return offset;
-}
+static const struct bpf_attr_check BPF_OBJ_GET_INFO_BY_FD_checks[] = {
+ {
+ .data = { .BPF_OBJ_GET_INFO_BY_FD_data = { .bpf_fd = -1 } },
+ .size = offsetofend(struct BPF_OBJ_GET_INFO_BY_FD_struct, bpf_fd),
+ .str = "info={bpf_fd=-1, info_len=0, info=0}"
+ },
+ {
+ .data = { .BPF_OBJ_GET_INFO_BY_FD_data = {
+ .bpf_fd = -1,
+ .info_len = 0xdeadbeef,
+ .info = (uint64_t) 0xfacefeedbadc0dedULL
+ } },
+ .size = offsetofend(struct BPF_OBJ_GET_INFO_BY_FD_struct, info),
+ .str = "info={bpf_fd=-1, info_len=3735928559"
+ ", info=0xfacefeedbadc0ded}"
+ }
+};
-static void
-print_BPF_OBJ_GET_INFO_BY_FD_attr(const unsigned long addr)
-{
- PRINT_FIELD_D("info={", sample_BPF_OBJ_GET_INFO_BY_FD_attr, bpf_fd);
- PRINT_FIELD_U(", ", sample_BPF_OBJ_GET_INFO_BY_FD_attr, info_len);
- PRINT_FIELD_X(", ", sample_BPF_OBJ_GET_INFO_BY_FD_attr, info);
- printf("}");
-}
+#define CHK(cmd_) \
+ { \
+ cmd_, #cmd_, \
+ cmd_##_checks, ARRAY_SIZE(cmd_##_checks), \
+ } \
+ /* End of CHK definition */
int
main(void)
{
+ static const struct bpf_check checks[] = {
+ CHK(BPF_MAP_CREATE),
+ CHK(BPF_MAP_LOOKUP_ELEM),
+ CHK(BPF_MAP_UPDATE_ELEM),
+ CHK(BPF_MAP_DELETE_ELEM),
+ CHK(BPF_MAP_GET_NEXT_KEY),
+ CHK(BPF_PROG_LOAD),
+ CHK(BPF_OBJ_PIN),
+ CHK(BPF_OBJ_GET),
+ CHK(BPF_PROG_ATTACH),
+ CHK(BPF_PROG_DETACH),
+ CHK(BPF_PROG_TEST_RUN),
+ CHK(BPF_PROG_GET_NEXT_ID),
+ CHK(BPF_MAP_GET_NEXT_ID),
+ CHK(BPF_PROG_GET_FD_BY_ID),
+ CHK(BPF_MAP_GET_FD_BY_ID),
+ CHK(BPF_OBJ_GET_INFO_BY_FD),
+ };
+
page_size = get_page_size();
end_of_page = (unsigned long) tail_alloc(1) + 1;
- TEST_BPF(BPF_MAP_CREATE);
- TEST_BPF(BPF_MAP_LOOKUP_ELEM);
- TEST_BPF(BPF_MAP_UPDATE_ELEM);
- TEST_BPF(BPF_MAP_DELETE_ELEM);
- TEST_BPF(BPF_MAP_GET_NEXT_KEY);
- TEST_BPF(BPF_PROG_LOAD);
- TEST_BPF(BPF_OBJ_PIN);
- TEST_BPF(BPF_OBJ_GET);
- TEST_BPF(BPF_PROG_ATTACH);
- TEST_BPF(BPF_PROG_DETACH);
- TEST_BPF(BPF_PROG_TEST_RUN);
- TEST_BPF(BPF_PROG_GET_NEXT_ID);
- TEST_BPF(BPF_MAP_GET_NEXT_ID);
- TEST_BPF(BPF_PROG_GET_FD_BY_ID);
- TEST_BPF(BPF_MAP_GET_FD_BY_ID);
- TEST_BPF(BPF_OBJ_GET_INFO_BY_FD);
+ for (size_t i = 0; i < ARRAY_SIZE(checks); i++)
+ test_bpf(checks + i);
sys_bpf(0xfacefeed, 0, (kernel_ulong_t) 0xfacefeedbadc0dedULL);
printf("bpf(0xfacefeed /* BPF_??? */, NULL, %u) = %s\n",