get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 806591,
    "url": "http://patchwork.ozlabs.org/api/patches/806591/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/20170828141004.14143.19285.stgit@john-Precision-Tower-5810/",
    "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": "<20170828141004.14143.19285.stgit@john-Precision-Tower-5810>",
    "list_archive_url": null,
    "date": "2017-08-28T14:10:04",
    "name": "[net-next,1/9] bpf: convert sockmap field attach_bpf_fd2 to type",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "029323f51d582470f60b5c1bede2986f9128a960",
    "submitter": {
        "id": 20028,
        "url": "http://patchwork.ozlabs.org/api/people/20028/?format=api",
        "name": "John Fastabend",
        "email": "john.fastabend@gmail.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/20170828141004.14143.19285.stgit@john-Precision-Tower-5810/mbox/",
    "series": [
        {
            "id": 179,
            "url": "http://patchwork.ozlabs.org/api/series/179/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=179",
            "date": "2017-08-28T14:09:45",
            "name": "sockmap UAPI updates and fixes",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/179/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/806591/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/806591/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 (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"D4my5TWS\"; dkim-atps=neutral"
        ],
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xgtvh2szsz9s1h\n\tfor <patchwork-incoming@ozlabs.org>;\n\tTue, 29 Aug 2017 00:10:24 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751552AbdH1OKW (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 28 Aug 2017 10:10:22 -0400",
            "from mail-pg0-f67.google.com ([74.125.83.67]:38635 \"EHLO\n\tmail-pg0-f67.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751242AbdH1OKU (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Mon, 28 Aug 2017 10:10:20 -0400",
            "by mail-pg0-f67.google.com with SMTP id t3so445903pgt.5\n\tfor <netdev@vger.kernel.org>; Mon, 28 Aug 2017 07:10:19 -0700 (PDT)",
            "from [127.0.1.1] ([72.168.144.1]) by smtp.gmail.com with ESMTPSA id\n\t77sm1196880pfz.47.2017.08.28.07.10.10\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tMon, 28 Aug 2017 07:10:18 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=gmail.com; s=20161025;\n\th=subject:from:to:cc:date:message-id:in-reply-to:references\n\t:user-agent:mime-version:content-transfer-encoding;\n\tbh=UGYUEG7IFzH7xC8whq0B0QWyEM9wGpOSvak12Aac8EQ=;\n\tb=D4my5TWSSosV++9LId7FMZ7uoLKm0/dnYGteiV5m07O213WR5daI9rC/V8fKxGGSh1\n\t/mhyGc8KVD/R2ltoz6JrxObe8x+6WYv6SIx87BEpGKmp5J6Xcd6qU85/tFCv7xrE2tq6\n\txPzxAKbkxQyJX32S5znEuqHgr8aI/bQ4wXjMa8OEFnDmixqeqoNqxlm/7X5XR/W/yuyl\n\tZUt88emOIw9sag8u0cishkkTUUEW8dXNF92rALV5CGiB0aJAXhQuWITtXCE/hXsvFQUF\n\twnT4+wWZzfTmW4mbayi9FYdGu4f1f1U9qYdO6cV9BMo2UweyTBDAxrE4J2Mlc8gvgY7i\n\trCtA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to\n\t:references:user-agent:mime-version:content-transfer-encoding;\n\tbh=UGYUEG7IFzH7xC8whq0B0QWyEM9wGpOSvak12Aac8EQ=;\n\tb=eIJgkcCSRvbNHJY4QAu3DWSsdPNnpfHiUOQY6bDm8StkceJ84ykS22XzXUhq5YJ4HI\n\tnnRjpYzKPQLH12OYrmHhUogQicPght7mZ1RpLiJpUkkDzbTUctIznN1Z5qyLJm0QnCOw\n\tRjgTCeLTq09ILLEJZ/3B5j1c1lfdSRwtIbFQhVMCpcmgLfEb0ivpbex1pa63KZZ76FpC\n\tkiIPkSQQfJZf+vEH7ziYmw+hNVwGlB1Iukd5anWrBhYEczvqe1oIy5dqo5R198jpIrbh\n\thq01sw2hB7riJ4Kwa75OGIfoTktleBTI649aIho5mnT6kzCWF4+ZTmS2UZiP8vHOMU9K\n\tXvVQ==",
        "X-Gm-Message-State": "AHYfb5h4qIosM8kC4xaqDI/hJEO0V2jTDtjAK3ml00eS3xoi8GUcfp0+\n\tpyx0RybV0T36puk3",
        "X-Received": "by 10.84.217.77 with SMTP id e13mr867219plj.221.1503929419158;\n\tMon, 28 Aug 2017 07:10:19 -0700 (PDT)",
        "Subject": "[net-next PATCH 1/9] bpf: convert sockmap field attach_bpf_fd2 to\n\ttype",
        "From": "John Fastabend <john.fastabend@gmail.com>",
        "To": "ast@kernel.org, daniel@iogearbox.net, davem@davemloft.net",
        "Cc": "netdev@vger.kernel.org, john.fastabend@gmail.com",
        "Date": "Mon, 28 Aug 2017 07:10:04 -0700",
        "Message-ID": "<20170828141004.14143.19285.stgit@john-Precision-Tower-5810>",
        "In-Reply-To": "<20170828140850.14143.83953.stgit@john-Precision-Tower-5810>",
        "References": "<20170828140850.14143.83953.stgit@john-Precision-Tower-5810>",
        "User-Agent": "StGit/0.17.1-dirty",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "7bit",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "In the initial sockmap API we provided strparser and verdict programs\nusing a single attach command by extending the attach API with a the\nattach_bpf_fd2 field.\n\nHowever, if we add other programs in the future we will be adding a\nfield for every new possible type, attach_bpf_fd(3,4,..). This\nseems a bit clumsy for an API. So lets push the programs using two\nnew type fields.\n\n   BPF_SK_SKB_STREAM_PARSER\n   BPF_SK_SKB_STREAM_VERDICT\n\nThis has the advantage of having a readable name and can easily be\nextended in the future.\n\nUpdates to samples and sockmap included here also generalize tests\nslightly to support upcoming patch for multiple map support.\n\nSigned-off-by: John Fastabend <john.fastabend@gmail.com>\nFixes: 174a79ff9515 (\"bpf: sockmap with sk redirect support\")\nSuggested-by: Alexei Starovoitov <ast@kernel.org>\n---\n include/linux/bpf.h                                |   10 +-\n include/uapi/linux/bpf.h                           |    9 -\n kernel/bpf/sockmap.c                               |   25 ++--\n kernel/bpf/syscall.c                               |   38 ++----\n samples/sockmap/sockmap_kern.c                     |    6 -\n samples/sockmap/sockmap_user.c                     |   12 ++\n tools/include/uapi/linux/bpf.h                     |    9 -\n tools/lib/bpf/bpf.c                                |   14 --\n tools/lib/bpf/bpf.h                                |    4 -\n tools/testing/selftests/bpf/bpf_helpers.h          |    3 \n tools/testing/selftests/bpf/sockmap_parse_prog.c   |    2 \n tools/testing/selftests/bpf/sockmap_verdict_prog.c |    2 \n tools/testing/selftests/bpf/test_maps.c            |  133 +++++++++-----------\n 13 files changed, 116 insertions(+), 151 deletions(-)",
    "diff": "diff --git a/include/linux/bpf.h b/include/linux/bpf.h\nindex 830f472..c2cb1b5 100644\n--- a/include/linux/bpf.h\n+++ b/include/linux/bpf.h\n@@ -39,8 +39,6 @@ struct bpf_map_ops {\n \tvoid (*map_fd_put_ptr)(void *ptr);\n \tu32 (*map_gen_lookup)(struct bpf_map *map, struct bpf_insn *insn_buf);\n \tu32 (*map_fd_sys_lookup_elem)(void *ptr);\n-\tint (*map_attach)(struct bpf_map *map,\n-\t\t\t  struct bpf_prog *p1, struct bpf_prog *p2);\n };\n \n struct bpf_map {\n@@ -387,11 +385,19 @@ static inline void __dev_map_flush(struct bpf_map *map)\n \n #if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL)\n struct sock  *__sock_map_lookup_elem(struct bpf_map *map, u32 key);\n+int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);\n #else\n static inline struct sock  *__sock_map_lookup_elem(struct bpf_map *map, u32 key)\n {\n \treturn NULL;\n }\n+\n+static inline int sock_map_attach_prog(struct bpf_map *map,\n+\t\t\t\t       struct bpf_prog *prog,\n+\t\t\t\t       u32 type)\n+{\n+\treturn -EOPNOTSUPP;\n+}\n #endif\n \n /* verifier prototypes for helper functions called from eBPF programs */\ndiff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h\nindex 843818d..97227be 100644\n--- a/include/uapi/linux/bpf.h\n+++ b/include/uapi/linux/bpf.h\n@@ -136,7 +136,8 @@ enum bpf_attach_type {\n \tBPF_CGROUP_INET_EGRESS,\n \tBPF_CGROUP_INET_SOCK_CREATE,\n \tBPF_CGROUP_SOCK_OPS,\n-\tBPF_CGROUP_SMAP_INGRESS,\n+\tBPF_SK_SKB_STREAM_PARSER,\n+\tBPF_SK_SKB_STREAM_VERDICT,\n \t__MAX_BPF_ATTACH_TYPE\n };\n \n@@ -224,7 +225,6 @@ enum bpf_attach_type {\n \t\t__u32\t\tattach_bpf_fd;\t/* eBPF program to attach */\n \t\t__u32\t\tattach_type;\n \t\t__u32\t\tattach_flags;\n-\t\t__u32\t\tattach_bpf_fd2;\n \t};\n \n \tstruct { /* anonymous struct used by BPF_PROG_TEST_RUN command */\n@@ -580,14 +580,11 @@ enum bpf_attach_type {\n  *     @flags: reserved for future use\n  *     Return: SK_REDIRECT\n  *\n- * int bpf_sock_map_update(skops, map, key, flags, map_flags)\n+ * int bpf_sock_map_update(skops, map, key, flags)\n  *\t@skops: pointer to bpf_sock_ops\n  *\t@map: pointer to sockmap to update\n  *\t@key: key to insert/update sock in map\n  *\t@flags: same flags as map update elem\n- *\t@map_flags: sock map specific flags\n- *\t   bit 1: Enable strparser\n- *\t   other bits: reserved\n  */\n #define __BPF_FUNC_MAPPER(FN)\t\t\\\n \tFN(unspec),\t\t\t\\\ndiff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c\nindex 617c239..cf570d1 100644\n--- a/kernel/bpf/sockmap.c\n+++ b/kernel/bpf/sockmap.c\n@@ -723,20 +723,24 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,\n \treturn err;\n }\n \n-static int sock_map_attach_prog(struct bpf_map *map,\n-\t\t\t\tstruct bpf_prog *parse,\n-\t\t\t\tstruct bpf_prog *verdict)\n+int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type)\n {\n \tstruct bpf_stab *stab = container_of(map, struct bpf_stab, map);\n-\tstruct bpf_prog *_parse, *_verdict;\n+\tstruct bpf_prog *orig;\n \n-\t_parse = xchg(&stab->bpf_parse, parse);\n-\t_verdict = xchg(&stab->bpf_verdict, verdict);\n+\tswitch (type) {\n+\tcase BPF_SK_SKB_STREAM_PARSER:\n+\t\torig = xchg(&stab->bpf_parse, prog);\n+\t\tbreak;\n+\tcase BPF_SK_SKB_STREAM_VERDICT:\n+\t\torig = xchg(&stab->bpf_verdict, prog);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n \n-\tif (_parse)\n-\t\tbpf_prog_put(_parse);\n-\tif (_verdict)\n-\t\tbpf_prog_put(_verdict);\n+\tif (orig)\n+\t\tbpf_prog_put(orig);\n \n \treturn 0;\n }\n@@ -777,7 +781,6 @@ static int sock_map_update_elem(struct bpf_map *map,\n \t.map_get_next_key = sock_map_get_next_key,\n \t.map_update_elem = sock_map_update_elem,\n \t.map_delete_elem = sock_map_delete_elem,\n-\t.map_attach = sock_map_attach_prog,\n };\n \n BPF_CALL_5(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock,\ndiff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c\nindex 9378f3b..021a05d 100644\n--- a/kernel/bpf/syscall.c\n+++ b/kernel/bpf/syscall.c\n@@ -1093,12 +1093,12 @@ static int bpf_obj_get(const union bpf_attr *attr)\n \n #ifdef CONFIG_CGROUP_BPF\n \n-#define BPF_PROG_ATTACH_LAST_FIELD attach_bpf_fd2\n+#define BPF_PROG_ATTACH_LAST_FIELD attach_flags\n \n-static int sockmap_get_from_fd(const union bpf_attr *attr, int ptype)\n+static int sockmap_get_from_fd(const union bpf_attr *attr)\n {\n-\tstruct bpf_prog *prog1, *prog2;\n \tint ufd = attr->target_fd;\n+\tstruct bpf_prog *prog;\n \tstruct bpf_map *map;\n \tstruct fd f;\n \tint err;\n@@ -1108,29 +1108,16 @@ static int sockmap_get_from_fd(const union bpf_attr *attr, int ptype)\n \tif (IS_ERR(map))\n \t\treturn PTR_ERR(map);\n \n-\tif (!map->ops->map_attach) {\n-\t\tfdput(f);\n-\t\treturn -EOPNOTSUPP;\n-\t}\n-\n-\tprog1 = bpf_prog_get_type(attr->attach_bpf_fd, ptype);\n-\tif (IS_ERR(prog1)) {\n+\tprog = bpf_prog_get_type(attr->attach_bpf_fd, BPF_PROG_TYPE_SK_SKB);\n+\tif (IS_ERR(prog)) {\n \t\tfdput(f);\n-\t\treturn PTR_ERR(prog1);\n-\t}\n-\n-\tprog2 = bpf_prog_get_type(attr->attach_bpf_fd2, ptype);\n-\tif (IS_ERR(prog2)) {\n-\t\tfdput(f);\n-\t\tbpf_prog_put(prog1);\n-\t\treturn PTR_ERR(prog2);\n+\t\treturn PTR_ERR(prog);\n \t}\n \n-\terr = map->ops->map_attach(map, prog1, prog2);\n+\terr = sock_map_attach_prog(map, prog, attr->attach_type);\n \tif (err) {\n \t\tfdput(f);\n-\t\tbpf_prog_put(prog1);\n-\t\tbpf_prog_put(prog2);\n+\t\tbpf_prog_put(prog);\n \t\treturn err;\n \t}\n \n@@ -1165,16 +1152,13 @@ static int bpf_prog_attach(const union bpf_attr *attr)\n \tcase BPF_CGROUP_SOCK_OPS:\n \t\tptype = BPF_PROG_TYPE_SOCK_OPS;\n \t\tbreak;\n-\tcase BPF_CGROUP_SMAP_INGRESS:\n-\t\tptype = BPF_PROG_TYPE_SK_SKB;\n-\t\tbreak;\n+\tcase BPF_SK_SKB_STREAM_PARSER:\n+\tcase BPF_SK_SKB_STREAM_VERDICT:\n+\t\treturn sockmap_get_from_fd(attr);\n \tdefault:\n \t\treturn -EINVAL;\n \t}\n \n-\tif (attr->attach_type == BPF_CGROUP_SMAP_INGRESS)\n-\t\treturn sockmap_get_from_fd(attr, ptype);\n-\n \tprog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);\n \tif (IS_ERR(prog))\n \t\treturn PTR_ERR(prog);\ndiff --git a/samples/sockmap/sockmap_kern.c b/samples/sockmap/sockmap_kern.c\nindex 6ff986f..f9b38ef 100644\n--- a/samples/sockmap/sockmap_kern.c\n+++ b/samples/sockmap/sockmap_kern.c\n@@ -82,8 +82,7 @@ int bpf_sockmap(struct bpf_sock_ops *skops)\n \t\tif (lport == 10000) {\n \t\t\tret = 1;\n \t\t\terr = bpf_sock_map_update(skops, &sock_map, &ret,\n-\t\t\t\t\t\t  BPF_NOEXIST,\n-\t\t\t\t\t\t  BPF_SOCKMAP_STRPARSER);\n+\t\t\t\t\t\t  BPF_NOEXIST);\n \t\t\tbpf_printk(\"passive(%i -> %i) map ctx update err: %d\\n\",\n \t\t\t\t   lport, bpf_ntohl(rport), err);\n \t\t}\n@@ -95,8 +94,7 @@ int bpf_sockmap(struct bpf_sock_ops *skops)\n \t\tif (bpf_ntohl(rport) == 10001) {\n \t\t\tret = 10;\n \t\t\terr = bpf_sock_map_update(skops, &sock_map, &ret,\n-\t\t\t\t\t\t  BPF_NOEXIST,\n-\t\t\t\t\t\t  BPF_SOCKMAP_STRPARSER);\n+\t\t\t\t\t\t  BPF_NOEXIST);\n \t\t\tbpf_printk(\"active(%i -> %i) map ctx update err: %d\\n\",\n \t\t\t\t   lport, bpf_ntohl(rport), err);\n \t\t}\ndiff --git a/samples/sockmap/sockmap_user.c b/samples/sockmap/sockmap_user.c\nindex fb78f5a..7cc9d22 100644\n--- a/samples/sockmap/sockmap_user.c\n+++ b/samples/sockmap/sockmap_user.c\n@@ -256,8 +256,16 @@ int main(int argc, char **argv)\n \t}\n \n \t/* Attach programs to sockmap */\n-\terr = __bpf_prog_attach(prog_fd[0], prog_fd[1], map_fd[0],\n-\t\t\t\tBPF_CGROUP_SMAP_INGRESS, 0);\n+\terr = bpf_prog_attach(prog_fd[0], map_fd[0],\n+\t\t\t\tBPF_SK_SKB_STREAM_PARSER, 0);\n+\tif (err) {\n+\t\tfprintf(stderr, \"ERROR: bpf_prog_attach (sockmap): %d (%s)\\n\",\n+\t\t\terr, strerror(errno));\n+\t\treturn err;\n+\t}\n+\n+\terr = bpf_prog_attach(prog_fd[1], map_fd[0],\n+\t\t\t\tBPF_SK_SKB_STREAM_VERDICT, 0);\n \tif (err) {\n \t\tfprintf(stderr, \"ERROR: bpf_prog_attach (sockmap): %d (%s)\\n\",\n \t\t\terr, strerror(errno));\ndiff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h\nindex f8f6377..09ac590 100644\n--- a/tools/include/uapi/linux/bpf.h\n+++ b/tools/include/uapi/linux/bpf.h\n@@ -136,7 +136,8 @@ enum bpf_attach_type {\n \tBPF_CGROUP_INET_EGRESS,\n \tBPF_CGROUP_INET_SOCK_CREATE,\n \tBPF_CGROUP_SOCK_OPS,\n-\tBPF_CGROUP_SMAP_INGRESS,\n+\tBPF_SK_SKB_STREAM_PARSER,\n+\tBPF_SK_SKB_STREAM_VERDICT,\n \t__MAX_BPF_ATTACH_TYPE\n };\n \n@@ -227,7 +228,6 @@ enum bpf_sockmap_flags {\n \t\t__u32\t\tattach_bpf_fd;\t/* eBPF program to attach */\n \t\t__u32\t\tattach_type;\n \t\t__u32\t\tattach_flags;\n-\t\t__u32\t\tattach_bpf_fd2;\n \t};\n \n \tstruct { /* anonymous struct used by BPF_PROG_TEST_RUN command */\n@@ -572,14 +572,11 @@ enum bpf_sockmap_flags {\n  *     @flags: reserved for future use\n  *     Return: SK_REDIRECT\n  *\n- * int bpf_sock_map_update(skops, map, key, flags, map_flags)\n+ * int bpf_sock_map_update(skops, map, key, flags)\n  *\t@skops: pointer to bpf_sock_ops\n  *\t@map: pointer to sockmap to update\n  *\t@key: key to insert/update sock in map\n  *\t@flags: same flags as map update elem\n- *\t@map_flags: sock map specific flags\n- *\t   bit 1: Enable strparser\n- *\t   other bits: reserved\n  */\n #define __BPF_FUNC_MAPPER(FN)\t\t\\\n \tFN(unspec),\t\t\t\\\ndiff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c\nindex a071761..1d6907d 100644\n--- a/tools/lib/bpf/bpf.c\n+++ b/tools/lib/bpf/bpf.c\n@@ -235,28 +235,20 @@ int bpf_obj_get(const char *pathname)\n \treturn sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr));\n }\n \n-int __bpf_prog_attach(int prog_fd1, int prog_fd2, int target_fd,\n-\t\t      enum bpf_attach_type type,\n-\t\t      unsigned int flags)\n+int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type,\n+\t\t    unsigned int flags)\n {\n \tunion bpf_attr attr;\n \n \tbzero(&attr, sizeof(attr));\n \tattr.target_fd\t   = target_fd;\n-\tattr.attach_bpf_fd = prog_fd1;\n-\tattr.attach_bpf_fd2 = prog_fd2;\n+\tattr.attach_bpf_fd = prog_fd;\n \tattr.attach_type   = type;\n \tattr.attach_flags  = flags;\n \n \treturn sys_bpf(BPF_PROG_ATTACH, &attr, sizeof(attr));\n }\n \n-int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type,\n-\t\t    unsigned int flags)\n-{\n-\treturn __bpf_prog_attach(prog_fd, 0, target_fd, type, flags);\n-}\n-\n int bpf_prog_detach(int target_fd, enum bpf_attach_type type)\n {\n \tunion bpf_attr attr;\ndiff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h\nindex 90e9d4e..b8ea584 100644\n--- a/tools/lib/bpf/bpf.h\n+++ b/tools/lib/bpf/bpf.h\n@@ -56,10 +56,6 @@ int bpf_map_update_elem(int fd, const void *key, const void *value,\n int bpf_obj_get(const char *pathname);\n int bpf_prog_attach(int prog_fd, int attachable_fd, enum bpf_attach_type type,\n \t\t    unsigned int flags);\n-int __bpf_prog_attach(int prog1, int prog2,\n-\t\t      int attachable_fd,\n-\t\t      enum bpf_attach_type type,\n-\t\t      unsigned int flags);\n int bpf_prog_detach(int attachable_fd, enum bpf_attach_type type);\n int bpf_prog_test_run(int prog_fd, int repeat, void *data, __u32 size,\n \t\t      void *data_out, __u32 *size_out, __u32 *retval,\ndiff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h\nindex 98f3be2..36fb916 100644\n--- a/tools/testing/selftests/bpf/bpf_helpers.h\n+++ b/tools/testing/selftests/bpf/bpf_helpers.h\n@@ -68,8 +68,7 @@ static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval,\n static int (*bpf_sk_redirect_map)(void *map, int key, int flags) =\n \t(void *) BPF_FUNC_sk_redirect_map;\n static int (*bpf_sock_map_update)(void *map, void *key, void *value,\n-\t\t\t\t  unsigned long long flags,\n-\t\t\t\t  unsigned long long map_lags) =\n+\t\t\t\t  unsigned long long flags) =\n \t(void *) BPF_FUNC_sock_map_update;\n \n \ndiff --git a/tools/testing/selftests/bpf/sockmap_parse_prog.c b/tools/testing/selftests/bpf/sockmap_parse_prog.c\nindex 8b54531..710f43f 100644\n--- a/tools/testing/selftests/bpf/sockmap_parse_prog.c\n+++ b/tools/testing/selftests/bpf/sockmap_parse_prog.c\n@@ -30,7 +30,7 @@ int bpf_prog1(struct __sk_buff *skb)\n \t */\n \td[0] = 1;\n \n-\tbpf_printk(\"data[0] = (%u): local_port %i remote %i\\n\",\n+\tbpf_printk(\"parse: data[0] = (%u): local_port %i remote %i\\n\",\n \t\t   d[0], lport, bpf_ntohl(rport));\n \treturn skb->len;\n }\ndiff --git a/tools/testing/selftests/bpf/sockmap_verdict_prog.c b/tools/testing/selftests/bpf/sockmap_verdict_prog.c\nindex d5f9447..0573c1d 100644\n--- a/tools/testing/selftests/bpf/sockmap_verdict_prog.c\n+++ b/tools/testing/selftests/bpf/sockmap_verdict_prog.c\n@@ -40,7 +40,7 @@ int bpf_prog2(struct __sk_buff *skb)\n \td[6] = 0xe;\n \td[7] = 0xf;\n \n-\tbpf_printk(\"data[0] = (%u): local_port %i remote %i\\n\",\n+\tbpf_printk(\"verdict: data[0] = (%u): local_port %i remote %i redirect 5\\n\",\n \t\t   d[0], lport, bpf_ntohl(rport));\n \treturn bpf_sk_redirect_map(&sock_map, 5, 0);\n }\ndiff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c\nindex 40b2d1f..6df6e62 100644\n--- a/tools/testing/selftests/bpf/test_maps.c\n+++ b/tools/testing/selftests/bpf/test_maps.c\n@@ -547,20 +547,26 @@ static void test_sockmap(int task, void *data)\n \t\tgoto out_sockmap;\n \t}\n \n-\t/* Nothing attached so these should fail */\n+\t/* Test update without programs */\n \tfor (i = 0; i < 6; i++) {\n \t\terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);\n-\t\tif (!err) {\n-\t\t\tprintf(\"Failed invalid update sockmap '%i:%i'\\n\",\n+\t\tif (err) {\n+\t\t\tprintf(\"Failed noprog update sockmap '%i:%i'\\n\",\n \t\t\t       i, sfd[i]);\n \t\t\tgoto out_sockmap;\n \t\t}\n \t}\n \n \t/* Test attaching bad fds */\n-\terr = __bpf_prog_attach(-1, -2, fd, BPF_CGROUP_SMAP_INGRESS, 0);\n+\terr = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0);\n \tif (!err) {\n-\t\tprintf(\"Failed invalid prog attach\\n\");\n+\t\tprintf(\"Failed invalid parser prog attach\\n\");\n+\t\tgoto out_sockmap;\n+\t}\n+\n+\terr = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_VERDICT, 0);\n+\tif (!err) {\n+\t\tprintf(\"Failed invalid verdict prog attach\\n\");\n \t\tgoto out_sockmap;\n \t}\n \n@@ -591,14 +597,21 @@ static void test_sockmap(int task, void *data)\n \t\tgoto out_sockmap;\n \t}\n \n-\terr = __bpf_prog_attach(parse_prog, verdict_prog, map_fd,\n-\t\t\t\tBPF_CGROUP_SMAP_INGRESS, 0);\n+\terr = bpf_prog_attach(parse_prog, map_fd,\n+\t\t      BPF_SK_SKB_STREAM_PARSER, 0);\n+\tif (err) {\n+\t\tprintf(\"Failed bpf prog attach\\n\");\n+\t\tgoto out_sockmap;\n+\t}\n+\n+\terr = bpf_prog_attach(verdict_prog, map_fd,\n+\t\t\t      BPF_SK_SKB_STREAM_VERDICT, 0);\n \tif (err) {\n \t\tprintf(\"Failed bpf prog attach\\n\");\n \t\tgoto out_sockmap;\n \t}\n \n-\t/* Test map update elem */\n+\t/* Test map update elem afterwards fd lives in fd and map_fd */\n \tfor (i = 0; i < 6; i++) {\n \t\terr = bpf_map_update_elem(map_fd, &i, &sfd[i], BPF_ANY);\n \t\tif (err) {\n@@ -649,96 +662,68 @@ static void test_sockmap(int task, void *data)\n \t\tgoto out_sockmap;\n \t}\n \n-\t/* Delete the reset of the elems include some NULL elems */\n-\tfor (i = 0; i < 6; i++) {\n-\t\terr = bpf_map_delete_elem(map_fd, &i);\n-\t\tif (err && (i == 0 || i == 1 || i >= 4)) {\n-\t\t\tprintf(\"Failed delete  sockmap %i '%i:%i'\\n\",\n-\t\t\t       err, i, sfd[i]);\n-\t\t\tgoto out_sockmap;\n-\t\t} else if (!err && (i == 2 || i == 3)) {\n-\t\t\tprintf(\"Failed null delete sockmap %i '%i:%i'\\n\",\n-\t\t\t       err, i, sfd[i]);\n-\t\t\tgoto out_sockmap;\n-\t\t}\n-\t}\n-\n-\t/* Test having multiple SMAPs open and active on same fds */\n-\terr = __bpf_prog_attach(parse_prog, verdict_prog, fd,\n-\t\t\t\tBPF_CGROUP_SMAP_INGRESS, 0);\n-\tif (err) {\n-\t\tprintf(\"Failed fd bpf prog attach\\n\");\n-\t\tgoto out_sockmap;\n-\t}\n-\n-\tfor (i = 0; i < 6; i++) {\n-\t\terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);\n-\t\tif (err) {\n-\t\t\tprintf(\"Failed fd update sockmap %i '%i:%i'\\n\",\n-\t\t\t       err, i, sfd[i]);\n-\t\t\tgoto out_sockmap;\n-\t\t}\n-\t}\n-\n-\t/* Test duplicate socket add of NOEXIST, ANY and EXIST */\n-\ti = 0;\n+\t/* Push fd into same slot */\n+\ti = 2;\n \terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);\n \tif (!err) {\n-\t\tprintf(\"Failed BPF_NOEXIST create\\n\");\n+\t\tprintf(\"Failed allowed sockmap dup slot BPF_NOEXIST\\n\");\n \t\tgoto out_sockmap;\n \t}\n \n \terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);\n \tif (err) {\n-\t\tprintf(\"Failed sockmap update BPF_ANY\\n\");\n+\t\tprintf(\"Failed sockmap update new slot BPF_ANY\\n\");\n \t\tgoto out_sockmap;\n \t}\n \n \terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);\n \tif (err) {\n-\t\tprintf(\"Failed sockmap update BPF_EXIST\\n\");\n+\t\tprintf(\"Failed sockmap update new slot BPF_EXIST\\n\");\n \t\tgoto out_sockmap;\n \t}\n \n-\t/* The above were pushing fd into same slot try different slot now */\n-\ti = 2;\n-\terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);\n-\tif (!err) {\n-\t\tprintf(\"Failed BPF_NOEXIST create\\n\");\n-\t\tgoto out_sockmap;\n+\t/* Delete the elems without programs */\n+\tfor (i = 0; i < 6; i++) {\n+\t\terr = bpf_map_delete_elem(fd, &i);\n+\t\tif (err) {\n+\t\t\tprintf(\"Failed delete sockmap %i '%i:%i'\\n\",\n+\t\t\t       err, i, sfd[i]);\n+\t\t}\n \t}\n \n-\terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);\n+\t/* Test having multiple maps open and set with programs on same fds */\n+\terr = bpf_prog_attach(parse_prog, fd,\n+\t\t\t      BPF_SK_SKB_STREAM_PARSER, 0);\n \tif (err) {\n-\t\tprintf(\"Failed sockmap update BPF_ANY\\n\");\n+\t\tprintf(\"Failed fd bpf parse prog attach\\n\");\n \t\tgoto out_sockmap;\n \t}\n-\n-\terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);\n+\terr = bpf_prog_attach(verdict_prog, fd,\n+\t\t\t      BPF_SK_SKB_STREAM_VERDICT, 0);\n \tif (err) {\n-\t\tprintf(\"Failed sockmap update BPF_EXIST\\n\");\n+\t\tprintf(\"Failed fd bpf verdict prog attach\\n\");\n \t\tgoto out_sockmap;\n \t}\n \n-\t/* Try pushing fd into different map, this is not allowed at the\n-\t * moment. Which programs would we use?\n-\t */\n-\terr = bpf_map_update_elem(map_fd, &i, &sfd[i], BPF_NOEXIST);\n-\tif (!err) {\n-\t\tprintf(\"Failed BPF_NOEXIST create\\n\");\n-\t\tgoto out_sockmap;\n-\t}\n-\n-\terr = bpf_map_update_elem(map_fd, &i, &sfd[i], BPF_ANY);\n-\tif (!err) {\n-\t\tprintf(\"Failed sockmap update BPF_ANY\\n\");\n-\t\tgoto out_sockmap;\n-\t}\n-\n-\terr = bpf_map_update_elem(map_fd, &i, &sfd[i], BPF_EXIST);\n-\tif (!err) {\n-\t\tprintf(\"Failed sockmap update BPF_EXIST\\n\");\n-\t\tgoto out_sockmap;\n+\tfor (i = 4; i < 6; i++) {\n+\t\terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);\n+\t\tif (!err) {\n+\t\t\tprintf(\"Failed allowed duplicate programs in update ANY sockmap %i '%i:%i'\\n\",\n+\t\t\t       err, i, sfd[i]);\n+\t\t\tgoto out_sockmap;\n+\t\t}\n+\t\terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);\n+\t\tif (!err) {\n+\t\t\tprintf(\"Failed allowed duplicate program in update NOEXIST sockmap  %i '%i:%i'\\n\",\n+\t\t\t       err, i, sfd[i]);\n+\t\t\tgoto out_sockmap;\n+\t\t}\n+\t\terr = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);\n+\t\tif (!err) {\n+\t\t\tprintf(\"Failed allowed duplicate program in update EXIST sockmap  %i '%i:%i'\\n\",\n+\t\t\t       err, i, sfd[i]);\n+\t\t\tgoto out_sockmap;\n+\t\t}\n \t}\n \n \t/* Test map close sockets */\n",
    "prefixes": [
        "net-next",
        "1/9"
    ]
}