get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 78074,
    "url": "https://patches.dpdk.org/api/patches/78074/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20200918073207.30067-1-ciara.loftus@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20200918073207.30067-1-ciara.loftus@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200918073207.30067-1-ciara.loftus@intel.com",
    "date": "2020-09-18T07:32:07",
    "name": "[v2] net/af_xdp: custom XDP program loading",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "b947390dc9e8700dd825529e4e532933a946d161",
    "submitter": {
        "id": 144,
        "url": "https://patches.dpdk.org/api/people/144/?format=api",
        "name": "Loftus, Ciara",
        "email": "ciara.loftus@intel.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20200918073207.30067-1-ciara.loftus@intel.com/mbox/",
    "series": [
        {
            "id": 12336,
            "url": "https://patches.dpdk.org/api/series/12336/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=12336",
            "date": "2020-09-18T07:32:07",
            "name": "[v2] net/af_xdp: custom XDP program loading",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/12336/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/78074/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/78074/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id B3952A04C7;\n\tFri, 18 Sep 2020 09:57:05 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 5AF8A1D6F5;\n\tFri, 18 Sep 2020 09:57:04 +0200 (CEST)",
            "from mga17.intel.com (mga17.intel.com [192.55.52.151])\n by dpdk.org (Postfix) with ESMTP id AD62F1D6D9\n for <dev@dpdk.org>; Fri, 18 Sep 2020 09:57:02 +0200 (CEST)",
            "from orsmga005.jf.intel.com ([10.7.209.41])\n by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 18 Sep 2020 00:57:01 -0700",
            "from silpixa00399839.ir.intel.com (HELO localhost.localdomain)\n ([10.237.222.142])\n by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 18 Sep 2020 00:57:00 -0700"
        ],
        "IronPort-SDR": [
            "\n vDpLgFHmddCzs4qkh9wQ6d5wK0EPESrl+OwvxLW//XEHAcq/MZk1pbUcCD03z3cIvbaNMVgb55\n +e2qU9lUaVMg==",
            "\n 3dzc7bgIjTWNzr3e6GMWNTBi/lBEm8b8BrK7JODQbp2YMBWz0dAjITBLPcyz0HllX/iH04hdEP\n pJmJ6KjeuWWw=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9747\"; a=\"139890634\"",
            "E=Sophos;i=\"5.77,274,1596524400\"; d=\"scan'208\";a=\"139890634\"",
            "E=Sophos;i=\"5.77,274,1596524400\"; d=\"scan'208\";a=\"484097568\""
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "From": "Ciara Loftus <ciara.loftus@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Ciara Loftus <ciara.loftus@intel.com>",
        "Date": "Fri, 18 Sep 2020 07:32:07 +0000",
        "Message-Id": "<20200918073207.30067-1-ciara.loftus@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v2] net/af_xdp: custom XDP program loading",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "The new 'xdp_prog=<string>' vdev arg allows the user to specify the path to\na custom XDP program to be set on the device, instead of the default libbpf\none. The program must have an XSK_MAP of name 'xsks_map' which will allow\nfor the redirection of some packets to userspace and thus the PMD, using\nsome criteria defined in the program. This can be useful for filtering\npurposes, for example if we only want a subset of packets to reach\nuserspace or to drop or process a subset of packets in the kernel.\n\nNote: a netdev may only load one program.\n\nSigned-off-by: Ciara Loftus <ciara.loftus@intel.com>\nTested-by: Xuekun Hu <xuekun.hu@intel.com>\n---\nv2:\n* Modified error checking for strnlen return.\n* Fixed copyright header edits\n* Updated commit message with more info on use cases\n\n doc/guides/nics/af_xdp.rst          |   3 +-\n drivers/net/af_xdp/rte_eth_af_xdp.c | 100 ++++++++++++++++++++++++++--\n 2 files changed, 96 insertions(+), 7 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/af_xdp.rst b/doc/guides/nics/af_xdp.rst\nindex 07bdd29e29..9c7bba7a29 100644\n--- a/doc/guides/nics/af_xdp.rst\n+++ b/doc/guides/nics/af_xdp.rst\n@@ -1,5 +1,5 @@\n ..  SPDX-License-Identifier: BSD-3-Clause\n-    Copyright(c) 2019 Intel Corporation.\n+    Copyright(c) 2019-2020 Intel Corporation.\n \n AF_XDP Poll Mode Driver\n ==========================\n@@ -32,6 +32,7 @@ The following options can be provided to set up an af_xdp port in DPDK.\n *   ``iface`` - name of the Kernel interface to attach to (required);\n *   ``start_queue`` - starting netdev queue id (optional, default 0);\n *   ``queue_count`` - total netdev queue number (optional, default 1);\n+*   ``xdp_prog`` - path to custom xdp program (optional, default none);\n \n Prerequisites\n -------------\ndiff --git a/drivers/net/af_xdp/rte_eth_af_xdp.c b/drivers/net/af_xdp/rte_eth_af_xdp.c\nindex 936d4a7d5f..e7f8ed4e53 100644\n--- a/drivers/net/af_xdp/rte_eth_af_xdp.c\n+++ b/drivers/net/af_xdp/rte_eth_af_xdp.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2019 Intel Corporation.\n+ * Copyright(c) 2019-2020 Intel Corporation.\n  */\n #include <unistd.h>\n #include <errno.h>\n@@ -118,6 +118,8 @@ struct pmd_internals {\n \tint queue_cnt;\n \tint max_queue_cnt;\n \tint combined_queue_cnt;\n+\tchar prog_path[PATH_MAX];\n+\tbool custom_prog_configured;\n \n \tstruct rte_ether_addr eth_addr;\n \n@@ -128,11 +130,13 @@ struct pmd_internals {\n #define ETH_AF_XDP_IFACE_ARG\t\t\t\"iface\"\n #define ETH_AF_XDP_START_QUEUE_ARG\t\t\"start_queue\"\n #define ETH_AF_XDP_QUEUE_COUNT_ARG\t\t\"queue_count\"\n+#define ETH_AF_XDP_PROG_ARG\t\t\t\"xdp_prog\"\n \n static const char * const valid_arguments[] = {\n \tETH_AF_XDP_IFACE_ARG,\n \tETH_AF_XDP_START_QUEUE_ARG,\n \tETH_AF_XDP_QUEUE_COUNT_ARG,\n+\tETH_AF_XDP_PROG_ARG,\n \tNULL\n };\n \n@@ -863,6 +867,45 @@ xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals,\n \treturn NULL;\n }\n \n+static int\n+load_custom_xdp_prog(const char *prog_path, int if_index)\n+{\n+\tint ret, prog_fd = -1;\n+\tstruct bpf_object *obj;\n+\tstruct bpf_map *map;\n+\n+\tret = bpf_prog_load(prog_path, BPF_PROG_TYPE_XDP, &obj, &prog_fd);\n+\tif (ret) {\n+\t\tAF_XDP_LOG(ERR, \"Failed to load program %s\\n\", prog_path);\n+\t\treturn ret;\n+\t}\n+\n+\t/*\n+\t * The loaded program must provision for a map of xsks, such that some\n+\t * traffic can be redirected to userspace. When the xsk is created,\n+\t * libbpf inserts it into the map.\n+\t */\n+\tmap = bpf_object__find_map_by_name(obj, \"xsks_map\");\n+\tif (!map) {\n+\t\tAF_XDP_LOG(ERR, \"Failed to find xsks_map in %s\\n\", prog_path);\n+\t\treturn -1;\n+\t}\n+\n+\t/* Link the program with the given network device */\n+\tret = bpf_set_link_xdp_fd(if_index, prog_fd,\n+\t\t\t\t\tXDP_FLAGS_UPDATE_IF_NOEXIST);\n+\tif (ret) {\n+\t\tAF_XDP_LOG(ERR, \"Failed to set prog fd %d on interface\\n\",\n+\t\t\t\tprog_fd);\n+\t\treturn -1;\n+\t}\n+\n+\tAF_XDP_LOG(INFO, \"Successfully loaded XDP program %s with fd %d\\n\",\n+\t\t\t\tprog_path, prog_fd);\n+\n+\treturn 0;\n+}\n+\n static int\n xsk_configure(struct pmd_internals *internals, struct pkt_rx_queue *rxq,\n \t      int ring_size)\n@@ -888,6 +931,18 @@ xsk_configure(struct pmd_internals *internals, struct pkt_rx_queue *rxq,\n \tcfg.bind_flags |= XDP_USE_NEED_WAKEUP;\n #endif\n \n+\tif (strnlen(internals->prog_path, PATH_MAX) &&\n+\t\t\t\t!internals->custom_prog_configured) {\n+\t\tret = load_custom_xdp_prog(internals->prog_path,\n+\t\t\t\t\t   internals->if_index);\n+\t\tif (ret) {\n+\t\t\tAF_XDP_LOG(ERR, \"Failed to load custom XDP program %s\\n\",\n+\t\t\t\t\tinternals->prog_path);\n+\t\t\tgoto err;\n+\t\t}\n+\t\tinternals->custom_prog_configured = 1;\n+\t}\n+\n \tret = xsk_socket__create(&rxq->xsk, internals->if_name,\n \t\t\trxq->xsk_queue_idx, rxq->umem->umem, &rxq->rx,\n \t\t\t&txq->tx, &cfg);\n@@ -1099,6 +1154,30 @@ parse_name_arg(const char *key __rte_unused,\n \treturn 0;\n }\n \n+/** parse xdp prog argument */\n+static int\n+parse_prog_arg(const char *key __rte_unused,\n+\t       const char *value, void *extra_args)\n+{\n+\tchar *path = extra_args;\n+\n+\tif (strnlen(value, PATH_MAX) == PATH_MAX) {\n+\t\tAF_XDP_LOG(ERR, \"Invalid path %s, should be less than %u bytes.\\n\",\n+\t\t\t   value, PATH_MAX);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (access(value, F_OK) != 0) {\n+\t\tAF_XDP_LOG(ERR, \"Error accessing %s: %s\\n\",\n+\t\t\t   value, strerror(errno));\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tstrlcpy(path, value, PATH_MAX);\n+\n+\treturn 0;\n+}\n+\n static int\n xdp_get_channels_info(const char *if_name, int *max_queues,\n \t\t\t\tint *combined_queues)\n@@ -1142,7 +1221,7 @@ xdp_get_channels_info(const char *if_name, int *max_queues,\n \n static int\n parse_parameters(struct rte_kvargs *kvlist, char *if_name, int *start_queue,\n-\t\t\tint *queue_cnt)\n+\t\t\tint *queue_cnt, char *prog_path)\n {\n \tint ret;\n \n@@ -1163,6 +1242,11 @@ parse_parameters(struct rte_kvargs *kvlist, char *if_name, int *start_queue,\n \t\tgoto free_kvlist;\n \t}\n \n+\tret = rte_kvargs_process(kvlist, ETH_AF_XDP_PROG_ARG,\n+\t\t\t\t &parse_prog_arg, prog_path);\n+\tif (ret < 0)\n+\t\tgoto free_kvlist;\n+\n free_kvlist:\n \trte_kvargs_free(kvlist);\n \treturn ret;\n@@ -1200,7 +1284,7 @@ get_iface_info(const char *if_name,\n \n static struct rte_eth_dev *\n init_internals(struct rte_vdev_device *dev, const char *if_name,\n-\t\t\tint start_queue_idx, int queue_cnt)\n+\t\tint start_queue_idx, int queue_cnt, const char *prog_path)\n {\n \tconst char *name = rte_vdev_device_name(dev);\n \tconst unsigned int numa_node = dev->device.numa_node;\n@@ -1216,6 +1300,8 @@ init_internals(struct rte_vdev_device *dev, const char *if_name,\n \tinternals->start_queue_idx = start_queue_idx;\n \tinternals->queue_cnt = queue_cnt;\n \tstrlcpy(internals->if_name, if_name, IFNAMSIZ);\n+\tstrlcpy(internals->prog_path, prog_path, PATH_MAX);\n+\tinternals->custom_prog_configured = 0;\n \n \tif (xdp_get_channels_info(if_name, &internals->max_queue_cnt,\n \t\t\t\t  &internals->combined_queue_cnt)) {\n@@ -1292,6 +1378,7 @@ rte_pmd_af_xdp_probe(struct rte_vdev_device *dev)\n \tchar if_name[IFNAMSIZ] = {'\\0'};\n \tint xsk_start_queue_idx = ETH_AF_XDP_DFLT_START_QUEUE_IDX;\n \tint xsk_queue_cnt = ETH_AF_XDP_DFLT_QUEUE_COUNT;\n+\tchar prog_path[PATH_MAX] = {'\\0'};\n \tstruct rte_eth_dev *eth_dev = NULL;\n \tconst char *name;\n \n@@ -1321,7 +1408,7 @@ rte_pmd_af_xdp_probe(struct rte_vdev_device *dev)\n \t\tdev->device.numa_node = rte_socket_id();\n \n \tif (parse_parameters(kvlist, if_name, &xsk_start_queue_idx,\n-\t\t\t     &xsk_queue_cnt) < 0) {\n+\t\t\t     &xsk_queue_cnt, prog_path) < 0) {\n \t\tAF_XDP_LOG(ERR, \"Invalid kvargs value\\n\");\n \t\treturn -EINVAL;\n \t}\n@@ -1332,7 +1419,7 @@ rte_pmd_af_xdp_probe(struct rte_vdev_device *dev)\n \t}\n \n \teth_dev = init_internals(dev, if_name, xsk_start_queue_idx,\n-\t\t\t\t\txsk_queue_cnt);\n+\t\t\t\t\txsk_queue_cnt, prog_path);\n \tif (eth_dev == NULL) {\n \t\tAF_XDP_LOG(ERR, \"Failed to init internals\\n\");\n \t\treturn -1;\n@@ -1375,4 +1462,5 @@ RTE_PMD_REGISTER_VDEV(net_af_xdp, pmd_af_xdp_drv);\n RTE_PMD_REGISTER_PARAM_STRING(net_af_xdp,\n \t\t\t      \"iface=<string> \"\n \t\t\t      \"start_queue=<int> \"\n-\t\t\t      \"queue_count=<int> \");\n+\t\t\t      \"queue_count=<int> \"\n+\t\t\t      \"xdp_prog=<string> \");\n",
    "prefixes": [
        "v2"
    ]
}