get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/819320/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 819320,
    "url": "http://patchwork.ozlabs.org/api/patches/819320/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/20170927213756.1254938-6-kafai@fb.com/",
    "project": {
        "id": 7,
        "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api",
        "name": "Linux network development",
        "link_name": "netdev",
        "list_id": "netdev.vger.kernel.org",
        "list_email": "netdev@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170927213756.1254938-6-kafai@fb.com>",
    "list_archive_url": null,
    "date": "2017-09-27T21:37:56",
    "name": "[net-next,5/5] bpf: Test new fields in bpf_attr and bpf_{prog,map}_info",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "e326800f57c46854fd77ff9be3359ac5ff76b7fe",
    "submitter": {
        "id": 64907,
        "url": "http://patchwork.ozlabs.org/api/people/64907/?format=api",
        "name": "Martin KaFai Lau",
        "email": "kafai@fb.com"
    },
    "delegate": {
        "id": 34,
        "url": "http://patchwork.ozlabs.org/api/users/34/?format=api",
        "username": "davem",
        "first_name": "David",
        "last_name": "Miller",
        "email": "davem@davemloft.net"
    },
    "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/20170927213756.1254938-6-kafai@fb.com/mbox/",
    "series": [
        {
            "id": 5453,
            "url": "http://patchwork.ozlabs.org/api/series/5453/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=5453",
            "date": "2017-09-27T21:37:55",
            "name": "bpf: Extend bpf_{prog,map}_info",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/5453/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/819320/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/819320/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<netdev-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)",
            "ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=fb.com header.i=@fb.com header.b=\"AOOw9aUV\";\n\tdkim-atps=neutral"
        ],
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3y2WQX0YN7z9t67\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu, 28 Sep 2017 07:38:12 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752167AbdI0ViH (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tWed, 27 Sep 2017 17:38:07 -0400",
            "from mx0b-00082601.pphosted.com ([67.231.153.30]:50535 \"EHLO\n\tmx0b-00082601.pphosted.com\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1751958AbdI0ViA (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Wed, 27 Sep 2017 17:38:00 -0400",
            "from pps.filterd (m0109331.ppops.net [127.0.0.1])\n\tby mx0a-00082601.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id\n\tv8RLbmLD029142\n\tfor <netdev@vger.kernel.org>; Wed, 27 Sep 2017 14:37:59 -0700",
            "from mail.thefacebook.com ([199.201.64.23])\n\tby mx0a-00082601.pphosted.com with ESMTP id 2d8fsu9hbp-5\n\t(version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT)\n\tfor <netdev@vger.kernel.org>; Wed, 27 Sep 2017 14:37:59 -0700",
            "from mx-out.facebook.com (192.168.52.123) by\n\tPRN-CHUB01.TheFacebook.com (192.168.16.11) with Microsoft SMTP Server\n\tid 14.3.319.2; Wed, 27 Sep 2017 14:37:56 -0700",
            "by devbig738.prn1.facebook.com (Postfix, from userid 6611)    id\n\t9B8AC4500946; Wed, 27 Sep 2017 14:37:56 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com;\n\th=from : to : cc : subject\n\t: date : message-id : in-reply-to : references : mime-version :\n\tcontent-type; s=facebook;\n\tbh=/+FexovAmJ9pjVUvN+FAU9LXFdsKpma2pB7FMsW3nIY=; \n\tb=AOOw9aUVs5pcjGihADvIGSuGtj1imDSLY0/z+Ze4nJFJ4kuRij/QeJSt5UUcsRRjnVPO\n\t1kmzT12Nd7TPHFBh756Tdp89isDqe7Xr8F6kSMDgDIFJh9+joI76KEL10JJpiWWFUyQd\n\tV0GqFgnJ4pvvXxCBy8fMkboYFp8+Nn8+UMc= ",
        "Smtp-Origin-Hostprefix": "devbig",
        "From": "Martin KaFai Lau <kafai@fb.com>",
        "Smtp-Origin-Hostname": "devbig738.prn1.facebook.com",
        "To": "<netdev@vger.kernel.org>",
        "CC": "Alexei Starovoitov <ast@fb.com>,\n\tDaniel Borkmann <daniel@iogearbox.net>, <kernel-team@fb.com>",
        "Smtp-Origin-Cluster": "prn1c29",
        "Subject": "[PATCH net-next 5/5] bpf: Test new fields in bpf_attr and bpf_{prog,\n\tmap}_info",
        "Date": "Wed, 27 Sep 2017 14:37:56 -0700",
        "Message-ID": "<20170927213756.1254938-6-kafai@fb.com>",
        "X-Mailer": "git-send-email 2.9.5",
        "In-Reply-To": "<20170927213756.1254938-1-kafai@fb.com>",
        "References": "<20170927213756.1254938-1-kafai@fb.com>",
        "X-FB-Internal": [
            "Safe",
            "Safe"
        ],
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Proofpoint-Spam-Reason": "safe",
        "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10432:, ,\n\tdefinitions=2017-09-27_08:, , signatures=0",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "This patch tests newly added fields of the bpf_attr,\nbpf_prog_info and bpf_map_info.\n\nSigned-off-by: Martin KaFai Lau <kafai@fb.com>\nAcked-by: Alexei Starovoitov <ast@fb.com>\nAcked-by: Daniel Borkmann <daniel@iogearbox.net>\n---\n tools/testing/selftests/bpf/test_progs.c | 143 ++++++++++++++++++++++++++++---\n 1 file changed, 132 insertions(+), 11 deletions(-)",
    "diff": "diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c\nindex 31ae27dc8d04..69427531408d 100644\n--- a/tools/testing/selftests/bpf/test_progs.c\n+++ b/tools/testing/selftests/bpf/test_progs.c\n@@ -10,6 +10,7 @@\n #include <string.h>\n #include <assert.h>\n #include <stdlib.h>\n+#include <time.h>\n \n #include <linux/types.h>\n typedef __u16 __sum16;\n@@ -19,6 +20,8 @@ typedef __u16 __sum16;\n #include <linux/ip.h>\n #include <linux/ipv6.h>\n #include <linux/tcp.h>\n+#include <linux/filter.h>\n+#include <linux/unistd.h>\n \n #include <sys/wait.h>\n #include <sys/resource.h>\n@@ -273,16 +276,26 @@ static void test_bpf_obj_id(void)\n \tconst int nr_iters = 2;\n \tconst char *file = \"./test_obj_id.o\";\n \tconst char *jit_sysctl = \"/proc/sys/net/core/bpf_jit_enable\";\n+\tconst char *expected_prog_name = \"test_obj_id\";\n+\tconst char *expected_map_name = \"test_map_id\";\n+\tconst __u64 nsec_per_sec = 1000000000;\n \n \tstruct bpf_object *objs[nr_iters];\n \tint prog_fds[nr_iters], map_fds[nr_iters];\n \t/* +1 to test for the info_len returned by kernel */\n \tstruct bpf_prog_info prog_infos[nr_iters + 1];\n \tstruct bpf_map_info map_infos[nr_iters + 1];\n+\t/* Each prog only uses one map. +1 to test nr_map_ids\n+\t * returned by kernel.\n+\t */\n+\t__u32 map_ids[nr_iters + 1];\n \tchar jited_insns[128], xlated_insns[128], zeros[128];\n \t__u32 i, next_id, info_len, nr_id_found, duration = 0;\n+\tstruct timespec real_time_ts, boot_time_ts;\n \tint sysctl_fd, jit_enabled = 0, err = 0;\n \t__u64 array_value;\n+\tuid_t my_uid = getuid();\n+\ttime_t now, load_time;\n \n \tsysctl_fd = open(jit_sysctl, 0, O_RDONLY);\n \tif (sysctl_fd != -1) {\n@@ -307,6 +320,7 @@ static void test_bpf_obj_id(void)\n \t/* Check bpf_obj_get_info_by_fd() */\n \tbzero(zeros, sizeof(zeros));\n \tfor (i = 0; i < nr_iters; i++) {\n+\t\tnow = time(NULL);\n \t\terr = bpf_prog_load(file, BPF_PROG_TYPE_SOCKET_FILTER,\n \t\t\t\t    &objs[i], &prog_fds[i]);\n \t\t/* test_obj_id.o is a dumb prog. It should never fail\n@@ -334,16 +348,18 @@ static void test_bpf_obj_id(void)\n \t\t\t  map_infos[i].value_size != sizeof(__u64) ||\n \t\t\t  map_infos[i].max_entries != 1 ||\n \t\t\t  map_infos[i].map_flags != 0 ||\n-\t\t\t  info_len != sizeof(struct bpf_map_info),\n+\t\t\t  info_len != sizeof(struct bpf_map_info) ||\n+\t\t\t  strcmp((char *)map_infos[i].name, expected_map_name),\n \t\t\t  \"get-map-info(fd)\",\n-\t\t\t  \"err %d errno %d type %d(%d) info_len %u(%lu) key_size %u value_size %u max_entries %u map_flags %X\\n\",\n+\t\t\t  \"err %d errno %d type %d(%d) info_len %u(%lu) key_size %u value_size %u max_entries %u map_flags %X name %s(%s)\\n\",\n \t\t\t  err, errno,\n \t\t\t  map_infos[i].type, BPF_MAP_TYPE_ARRAY,\n \t\t\t  info_len, sizeof(struct bpf_map_info),\n \t\t\t  map_infos[i].key_size,\n \t\t\t  map_infos[i].value_size,\n \t\t\t  map_infos[i].max_entries,\n-\t\t\t  map_infos[i].map_flags))\n+\t\t\t  map_infos[i].map_flags,\n+\t\t\t  map_infos[i].name, expected_map_name))\n \t\t\tgoto done;\n \n \t\t/* Check getting prog info */\n@@ -355,8 +371,16 @@ static void test_bpf_obj_id(void)\n \t\tprog_infos[i].jited_prog_len = sizeof(jited_insns);\n \t\tprog_infos[i].xlated_prog_insns = ptr_to_u64(xlated_insns);\n \t\tprog_infos[i].xlated_prog_len = sizeof(xlated_insns);\n+\t\tprog_infos[i].map_ids = ptr_to_u64(map_ids + i);\n+\t\tprog_infos[i].nr_map_ids = 2;\n+\t\terr = clock_gettime(CLOCK_REALTIME, &real_time_ts);\n+\t\tassert(!err);\n+\t\terr = clock_gettime(CLOCK_BOOTTIME, &boot_time_ts);\n+\t\tassert(!err);\n \t\terr = bpf_obj_get_info_by_fd(prog_fds[i], &prog_infos[i],\n \t\t\t\t\t     &info_len);\n+\t\tload_time = (real_time_ts.tv_sec - boot_time_ts.tv_sec)\n+\t\t\t+ (prog_infos[i].load_time / nsec_per_sec);\n \t\tif (CHECK(err ||\n \t\t\t  prog_infos[i].type != BPF_PROG_TYPE_SOCKET_FILTER ||\n \t\t\t  info_len != sizeof(struct bpf_prog_info) ||\n@@ -364,9 +388,14 @@ static void test_bpf_obj_id(void)\n \t\t\t  (jit_enabled &&\n \t\t\t   !memcmp(jited_insns, zeros, sizeof(zeros))) ||\n \t\t\t  !prog_infos[i].xlated_prog_len ||\n-\t\t\t  !memcmp(xlated_insns, zeros, sizeof(zeros)),\n+\t\t\t  !memcmp(xlated_insns, zeros, sizeof(zeros)) ||\n+\t\t\t  load_time < now - 60 || load_time > now + 60 ||\n+\t\t\t  prog_infos[i].created_by_uid != my_uid ||\n+\t\t\t  prog_infos[i].nr_map_ids != 1 ||\n+\t\t\t  *(int *)prog_infos[i].map_ids != map_infos[i].id ||\n+\t\t\t  strcmp((char *)prog_infos[i].name, expected_prog_name),\n \t\t\t  \"get-prog-info(fd)\",\n-\t\t\t  \"err %d errno %d i %d type %d(%d) info_len %u(%lu) jit_enabled %d jited_prog_len %u xlated_prog_len %u jited_prog %d xlated_prog %d\\n\",\n+\t\t\t  \"err %d errno %d i %d type %d(%d) info_len %u(%lu) jit_enabled %d jited_prog_len %u xlated_prog_len %u jited_prog %d xlated_prog %d load_time %lu(%lu) uid %u(%u) nr_map_ids %u(%u) map_id %u(%u) name %s(%s)\\n\",\n \t\t\t  err, errno, i,\n \t\t\t  prog_infos[i].type, BPF_PROG_TYPE_SOCKET_FILTER,\n \t\t\t  info_len, sizeof(struct bpf_prog_info),\n@@ -374,9 +403,13 @@ static void test_bpf_obj_id(void)\n \t\t\t  prog_infos[i].jited_prog_len,\n \t\t\t  prog_infos[i].xlated_prog_len,\n \t\t\t  !!memcmp(jited_insns, zeros, sizeof(zeros)),\n-\t\t\t  !!memcmp(xlated_insns, zeros, sizeof(zeros))))\n+\t\t\t  !!memcmp(xlated_insns, zeros, sizeof(zeros)),\n+\t\t\t  load_time, now,\n+\t\t\t  prog_infos[i].created_by_uid, my_uid,\n+\t\t\t  prog_infos[i].nr_map_ids, 1,\n+\t\t\t  *(int *)prog_infos[i].map_ids, map_infos[i].id,\n+\t\t\t  prog_infos[i].name, expected_prog_name))\n \t\t\tgoto done;\n-\n \t}\n \n \t/* Check bpf_prog_get_next_id() */\n@@ -384,6 +417,7 @@ static void test_bpf_obj_id(void)\n \tnext_id = 0;\n \twhile (!bpf_prog_get_next_id(next_id, &next_id)) {\n \t\tstruct bpf_prog_info prog_info = {};\n+\t\t__u32 saved_map_id;\n \t\tint prog_fd;\n \n \t\tinfo_len = sizeof(prog_info);\n@@ -406,16 +440,33 @@ static void test_bpf_obj_id(void)\n \n \t\tnr_id_found++;\n \n+\t\t/* Negative test:\n+\t\t * prog_info.nr_map_ids = 1\n+\t\t * prog_info.map_ids = NULL\n+\t\t */\n+\t\tprog_info.nr_map_ids = 1;\n+\t\terr = bpf_obj_get_info_by_fd(prog_fd, &prog_info, &info_len);\n+\t\tif (CHECK(!err || errno != EFAULT,\n+\t\t\t  \"get-prog-fd-bad-nr-map-ids\", \"err %d errno %d(%d)\",\n+\t\t\t  err, errno, EFAULT))\n+\t\t\tbreak;\n+\t\tbzero(&prog_info, sizeof(prog_info));\n+\t\tinfo_len = sizeof(prog_info);\n+\n+\t\tsaved_map_id = *(int *)(prog_infos[i].map_ids);\n+\t\tprog_info.map_ids = prog_infos[i].map_ids;\n+\t\tprog_info.nr_map_ids = 2;\n \t\terr = bpf_obj_get_info_by_fd(prog_fd, &prog_info, &info_len);\n \t\tprog_infos[i].jited_prog_insns = 0;\n \t\tprog_infos[i].xlated_prog_insns = 0;\n \t\tCHECK(err || info_len != sizeof(struct bpf_prog_info) ||\n-\t\t      memcmp(&prog_info, &prog_infos[i], info_len),\n+\t\t      memcmp(&prog_info, &prog_infos[i], info_len) ||\n+\t\t      *(int *)prog_info.map_ids != saved_map_id,\n \t\t      \"get-prog-info(next_id->fd)\",\n-\t\t      \"err %d errno %d info_len %u(%lu) memcmp %d\\n\",\n+\t\t      \"err %d errno %d info_len %u(%lu) memcmp %d map_id %u(%u)\\n\",\n \t\t      err, errno, info_len, sizeof(struct bpf_prog_info),\n-\t\t      memcmp(&prog_info, &prog_infos[i], info_len));\n-\n+\t\t      memcmp(&prog_info, &prog_infos[i], info_len),\n+\t\t      *(int *)prog_info.map_ids, saved_map_id);\n \t\tclose(prog_fd);\n \t}\n \tCHECK(nr_id_found != nr_iters,\n@@ -497,6 +548,75 @@ static void test_pkt_md_access(void)\n \tbpf_object__close(obj);\n }\n \n+static void test_obj_name(void)\n+{\n+\tstruct {\n+\t\tconst char *name;\n+\t\tint success;\n+\t\tint expected_errno;\n+\t} tests[] = {\n+\t\t{ \"\", 1, 0 },\n+\t\t{ \"_123456789ABCDE\", 1, 0 },\n+\t\t{ \"_123456789ABCDEF\", 0, EINVAL },\n+\t\t{ \"_123456789ABCD\\n\", 0, EINVAL },\n+\t};\n+\tstruct bpf_insn prog[] = {\n+\t\tBPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),\n+\t\tBPF_EXIT_INSN(),\n+\t};\n+\t__u32 duration = 0;\n+\tint i;\n+\n+\tfor (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {\n+\t\tsize_t name_len = strlen(tests[i].name) + 1;\n+\t\tunion bpf_attr attr;\n+\t\tsize_t ncopy;\n+\t\tint fd;\n+\n+\t\t/* test different attr.prog_name during BPF_PROG_LOAD */\n+\t\tncopy = name_len < sizeof(attr.prog_name) ?\n+\t\t\tname_len : sizeof(attr.prog_name);\n+\t\tbzero(&attr, sizeof(attr));\n+\t\tattr.prog_type = BPF_PROG_TYPE_SCHED_CLS;\n+\t\tattr.insn_cnt = 2;\n+\t\tattr.insns = ptr_to_u64(prog);\n+\t\tattr.license = ptr_to_u64(\"\");\n+\t\tmemcpy(attr.prog_name, tests[i].name, ncopy);\n+\n+\t\tfd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));\n+\t\tCHECK((tests[i].success && fd < 0) ||\n+\t\t      (!tests[i].success && fd != -1) ||\n+\t\t      (!tests[i].success && errno != tests[i].expected_errno),\n+\t\t      \"check-bpf-prog-name\",\n+\t\t      \"fd %d(%d) errno %d(%d)\\n\",\n+\t\t       fd, tests[i].success, errno, tests[i].expected_errno);\n+\n+\t\tif (fd != -1)\n+\t\t\tclose(fd);\n+\n+\t\t/* test different attr.map_name during BPF_MAP_CREATE */\n+\t\tncopy = name_len < sizeof(attr.map_name) ?\n+\t\t\tname_len : sizeof(attr.map_name);\n+\t\tbzero(&attr, sizeof(attr));\n+\t\tattr.map_type = BPF_MAP_TYPE_ARRAY;\n+\t\tattr.key_size = 4;\n+\t\tattr.value_size = 4;\n+\t\tattr.max_entries = 1;\n+\t\tattr.map_flags = 0;\n+\t\tmemcpy(attr.map_name, tests[i].name, ncopy);\n+\t\tfd = syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));\n+\t\tCHECK((tests[i].success && fd < 0) ||\n+\t\t      (!tests[i].success && fd != -1) ||\n+\t\t      (!tests[i].success && errno != tests[i].expected_errno),\n+\t\t      \"check-bpf-map-name\",\n+\t\t      \"fd %d(%d) errno %d(%d)\\n\",\n+\t\t      fd, tests[i].success, errno, tests[i].expected_errno);\n+\n+\t\tif (fd != -1)\n+\t\t\tclose(fd);\n+\t}\n+}\n+\n int main(void)\n {\n \tstruct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };\n@@ -509,6 +629,7 @@ int main(void)\n \ttest_tcp_estats();\n \ttest_bpf_obj_id();\n \ttest_pkt_md_access();\n+\ttest_obj_name();\n \n \tprintf(\"Summary: %d PASSED, %d FAILED\\n\", pass_cnt, error_cnt);\n \treturn error_cnt ? EXIT_FAILURE : EXIT_SUCCESS;\n",
    "prefixes": [
        "net-next",
        "5/5"
    ]
}