]> granicus.if.org Git - strace/commitdiff
Implement decoding of BPF_*_GET_*_ID commands of bpf syscall
authorDmitry V. Levin <ldv@altlinux.org>
Tue, 21 Nov 2017 21:08:19 +0000 (21:08 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 21 Nov 2017 21:08:19 +0000 (21:08 +0000)
* 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.

NEWS
bpf.c
configure.ac
tests/bpf.c

diff --git a/NEWS b/NEWS
index d52b5c36c025e6ecfd4b1c1c6f4f6ff3564e6113..1c5d0026487af32cb266c71fcb8b084cb360dec6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,7 +4,9 @@ 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.
+  * 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.
diff --git a/bpf.c b/bpf.c
index 5b4035efb3f4687de566f9ea451fc74817834303..321212ffc5ac8a2eacffaff33624637665bdabaf 100644 (file)
--- a/bpf.c
+++ b/bpf.c
@@ -306,6 +306,59 @@ DEF_BPF_CMD_DECODER(BPF_PROG_TEST_RUN)
        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[] = {
@@ -320,6 +373,10 @@ SYS_FUNC(bpf)
                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];
index e57e8989d39db7cb029d4db41facc32d9fd84709..4fab3b1f01c362559a593bfce3b0a30cb186b60a 100644 (file)
@@ -462,6 +462,7 @@ AC_CHECK_HEADERS([linux/bpf.h], [
        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>])
index c5e1293a071501d72d525077fe544a7eef661191..d18aebf28e0c1380351ec09e6f9d7d7672259144 100644 (file)
@@ -34,6 +34,7 @@
  && (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)
@@ -623,6 +624,83 @@ print_BPF_PROG_TEST_RUN_attr(const unsigned long addr)
 
 # 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)
 {
@@ -658,6 +736,13 @@ 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);