* configure.ac: Check for union bpf_attr.next_id.
* bpf.c (decode_BPF_PROG_GET_NEXT_ID, decode_BPF_PROG_GET_FD_BY_ID,
* decode_BPF_MAP_GET_FD_BY_ID): New functions.
(decode_BPF_MAP_GET_NEXT_ID): New macro.
(SYS_FUNC(bpf)) <bpf_cmd_decoders>: Use them.
* NEWS: Mention this.
* tests/bpf.c: Add macro guard for BPF_*_GET_*_ID decoder tests.
[HAVE_UNION_BPF_ATTR_NEXT_ID] (init_BPF_PROG_GET_NEXT_ID_first,
print_BPF_PROG_GET_NEXT_ID_first, init_BPF_PROG_GET_NEXT_ID_attr,
print_BPF_PROG_GET_NEXT_ID_attr, print_BPF_PROG_GET_FD_BY_ID_first,
print_BPF_PROG_GET_FD_BY_ID_attr, print_BPF_MAP_GET_NEXT_ID_first,
print_BPF_MAP_GET_NEXT_ID_attr): New functions.
(init_BPF_MAP_GET_NEXT_ID_first, print_BPF_MAP_GET_NEXT_ID_first,
init_BPF_MAP_GET_NEXT_ID_attr, print_BPF_MAP_GET_NEXT_ID_attr,
init_BPF_PROG_GET_FD_BY_ID_first, init_BPF_PROG_GET_FD_BY_ID_attr,
init_BPF_MAP_GET_FD_BY_ID_first, init_BPF_MAP_GET_FD_BY_ID_attr):
New macros.
(main) [HAVE_UNION_BPF_ATTR_NEXT_ID]: Use them.
* 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.
+ * Implemented decoding of BPF_PROG_TEST_RUN, BPF_PROG_GET_NEXT_ID,
+ BPF_MAP_GET_NEXT_ID, BPF_PROG_GET_FD_BY_ID, and BPF_MAP_GET_FD_BY_ID
+ commands of bpf syscall.
* Enhanced decoding of getsockopt and setsockopt syscalls for SOL_NETLINK
level.
* Enhanced decoding of BPF_MAP_CREATE command of bpf syscall.
return RVAL_DECODED;
}
+DEF_BPF_CMD_DECODER(BPF_PROG_GET_NEXT_ID)
+{
+ struct {
+ uint32_t start_id, next_id;
+ } attr = {};
+ const unsigned int len = size < sizeof(attr) ? size : sizeof(attr);
+
+ memcpy(&attr, data, len);
+
+ PRINT_FIELD_U("{", attr, start_id);
+ PRINT_FIELD_U(", ", attr, next_id);
+ decode_attr_extra_data(tcp, data, size, sizeof(attr));
+ tprints("}");
+
+ return RVAL_DECODED;
+}
+
+#define decode_BPF_MAP_GET_NEXT_ID decode_BPF_PROG_GET_NEXT_ID
+
+DEF_BPF_CMD_DECODER(BPF_PROG_GET_FD_BY_ID)
+{
+ struct {
+ uint32_t prog_id, next_id;
+ } attr = {};
+ const unsigned int len = size < sizeof(attr) ? size : sizeof(attr);
+
+ memcpy(&attr, data, len);
+
+ PRINT_FIELD_U("{", attr, prog_id);
+ PRINT_FIELD_U(", ", attr, next_id);
+ decode_attr_extra_data(tcp, data, size, sizeof(attr));
+ tprints("}");
+
+ return RVAL_DECODED;
+}
+
+DEF_BPF_CMD_DECODER(BPF_MAP_GET_FD_BY_ID)
+{
+ struct {
+ uint32_t map_id, next_id;
+ } attr = {};
+ const unsigned int len = size < sizeof(attr) ? size : sizeof(attr);
+
+ memcpy(&attr, data, len);
+
+ PRINT_FIELD_U("{", attr, map_id);
+ PRINT_FIELD_U(", ", attr, next_id);
+ 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[] = {
BPF_CMD_ENTRY(BPF_PROG_ATTACH),
BPF_CMD_ENTRY(BPF_PROG_DETACH),
BPF_CMD_ENTRY(BPF_PROG_TEST_RUN),
+ BPF_CMD_ENTRY(BPF_PROG_GET_NEXT_ID),
+ BPF_CMD_ENTRY(BPF_MAP_GET_NEXT_ID),
+ BPF_CMD_ENTRY(BPF_PROG_GET_FD_BY_ID),
+ BPF_CMD_ENTRY(BPF_MAP_GET_FD_BY_ID),
};
const unsigned int cmd = tcp->u_arg[0];
st_CHECK_UNION_BPF_ATTR([attach_flags])
st_CHECK_UNION_BPF_ATTR([bpf_fd])
st_CHECK_UNION_BPF_ATTR([flags])
+ st_CHECK_UNION_BPF_ATTR([next_id])
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>])
&& (defined HAVE_UNION_BPF_ATTR_ATTACH_FLAGS \
|| defined HAVE_UNION_BPF_ATTR_BPF_FD \
|| defined HAVE_UNION_BPF_ATTR_FLAGS \
+ || defined HAVE_UNION_BPF_ATTR_NEXT_ID \
|| defined HAVE_UNION_BPF_ATTR_NUMA_NODE \
|| defined HAVE_UNION_BPF_ATTR_PROG_FLAGS \
|| defined HAVE_UNION_BPF_ATTR_TEST_DURATION)
# endif /* HAVE_UNION_BPF_ATTR_TEST_DURATION */
+# ifdef HAVE_UNION_BPF_ATTR_NEXT_ID
+
+static unsigned int
+init_BPF_PROG_GET_NEXT_ID_first(const unsigned long eop)
+{
+ static const union bpf_attr attr = { .start_id = 0xdeadbeef };
+ static const unsigned int offset = sizeof(attr.start_id);
+ const unsigned long addr = eop - offset;
+
+ memcpy((void *) addr, &attr.start_id, offset);
+ return offset;
+}
+
+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 union bpf_attr attr = {
+ .start_id = 0xbadc0ded,
+ .next_id = 0xcafef00d
+ };
+ static const unsigned int offset =
+ offsetofend(union bpf_attr, 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);
+}
+
+static void
+print_BPF_PROG_GET_FD_BY_ID_attr(const unsigned long addr)
+{
+ printf("prog_id=%u, next_id=%u", 0xbadc0ded, 0xcafef00d);
+}
+
+# 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 void
+print_BPF_MAP_GET_FD_BY_ID_attr(const unsigned long addr)
+{
+ printf("map_id=%u, next_id=%u", 0xbadc0ded, 0xcafef00d);
+}
+
+# endif /* HAVE_UNION_BPF_ATTR_NEXT_ID */
+
int
main(void)
{
TEST_BPF(BPF_PROG_TEST_RUN);
# endif
+# ifdef HAVE_UNION_BPF_ATTR_NEXT_ID
+ 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);
+# endif
+
sys_bpf(0xfacefeed, end_of_page, 40);
printf("bpf(0xfacefeed /* BPF_??? */, %#lx, 40) = %s\n",
end_of_page, errstr);