get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 41722,
    "url": "http://patches.dpdk.org/api/patches/41722/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20180627173355.4718-2-adrien.mazarguil@6wind.com/",
    "project": {
        "id": 1,
        "url": "http://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": "<20180627173355.4718-2-adrien.mazarguil@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180627173355.4718-2-adrien.mazarguil@6wind.com",
    "date": "2018-06-27T18:08:10",
    "name": "[1/6] net/mlx5: lay groundwork for switch offloads",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "a04f8994098ca956617dae4250543a26b2a6fc3d",
    "submitter": {
        "id": 165,
        "url": "http://patches.dpdk.org/api/people/165/?format=api",
        "name": "Adrien Mazarguil",
        "email": "adrien.mazarguil@6wind.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20180627173355.4718-2-adrien.mazarguil@6wind.com/mbox/",
    "series": [
        {
            "id": 273,
            "url": "http://patches.dpdk.org/api/series/273/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=273",
            "date": "2018-06-27T18:08:08",
            "name": "net/mlx5: add support for switch flow rules",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/273/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/41722/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/41722/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 839BB1C383;\n\tWed, 27 Jun 2018 20:08:29 +0200 (CEST)",
            "from mail-wm0-f65.google.com (mail-wm0-f65.google.com\n\t[74.125.82.65]) by dpdk.org (Postfix) with ESMTP id C82A41C349\n\tfor <dev@dpdk.org>; Wed, 27 Jun 2018 20:08:27 +0200 (CEST)",
            "by mail-wm0-f65.google.com with SMTP id p11-v6so6409611wmc.4\n\tfor <dev@dpdk.org>; Wed, 27 Jun 2018 11:08:27 -0700 (PDT)",
            "from 6wind.com (host.78.145.23.62.rev.coltfrance.com.\n\t[62.23.145.78]) by smtp.gmail.com with ESMTPSA id\n\tu204-v6sm8321730wmd.7.2018.06.27.11.08.26\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tWed, 27 Jun 2018 11:08:26 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=6wind-com.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:in-reply-to;\n\tbh=Ku0gv3n2wFHOLm6bOKrN3/JXdkm5HIQwIHJk9pkYSx4=;\n\tb=eAtrNxSKQE0ZjaRB6W9+4VSH/E2po7nKkJOiVp41xjX2VwBHCbNzvJONgMyW6f95pt\n\tDLYH7QxnpUzntrtew+px2QFbI05FthchzJk79Ubpwx28+cq0NBA7w84EawmMa2/eAYR3\n\tuoe0Qgk3TXCct204gwORZWjK3bL9Gkq5Ts3+4QriyZgqYGPQ5jTC1qbvI257GImNDwdi\n\t8o68hvgodeNxDoSahoaEBNFS8IKEBIBlCDPPooFDib+3zf1zeeiJscq4IquKBs2wX6Ak\n\tNV2QkD3T7DYMmnUkg2ESvFQeZ6nUmcvO3AGbN2VE3PxTkP9n0CQ/9LGqiVCzFg5+TGEK\n\tsqLA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:in-reply-to;\n\tbh=Ku0gv3n2wFHOLm6bOKrN3/JXdkm5HIQwIHJk9pkYSx4=;\n\tb=qcA5hZojHLGSrysEFYvWM4UnD7mnATgf/LA7oOgYAjEVI5cmGdin/9Hg0WHAFg91kr\n\tCXUKigtxD5ZfIUh/5/IHznWXEGmv5SjLUXoqGxmn+g4AJjf8tL5neKsw6FxdQ6AoZHql\n\tmYo2HepurYN7l5aKUgZklduMP8SrrYA3TlJ+Z5Rec2crorx4FSNj7uLguJqe/k7/SY66\n\t3SAtCxSWZCNoQgmPzIR8H3uIPc4VOV+R6sIVcrZpI+gEZGTxdupU3kIF4PysKZVg9j2R\n\tERl9h8MVYK3KZq1OPn+yMZMAMh76EfVYlOc+J9YNvMNZnDCaAQxflPwB0NMdZpAOnSu6\n\trPXA==",
        "X-Gm-Message-State": "APt69E3V5ZJq3e/EFi74q4rP6nP15GSq7kRrvxiObz3+CDhyWXPKGqlB\n\tlGbb9z27NNz54LJPKgxytPMFjA==",
        "X-Google-Smtp-Source": "AAOMgpcdneF4kYpgebRJGFO22fBg0YK3Ztw+Ic9T5h7ZtQIQnxGt1VDo1BZINcmXriM0KOgND52pXA==",
        "X-Received": "by 2002:a1c:d681:: with SMTP id\n\tn123-v6mr5564755wmg.158.1530122907290; \n\tWed, 27 Jun 2018 11:08:27 -0700 (PDT)",
        "Date": "Wed, 27 Jun 2018 20:08:10 +0200",
        "From": "Adrien Mazarguil <adrien.mazarguil@6wind.com>",
        "To": "Shahaf Shuler <shahafs@mellanox.com>",
        "Cc": "Nelio Laranjeiro <nelio.laranjeiro@6wind.com>,\n\tYongseok Koh <yskoh@mellanox.com>, dev@dpdk.org",
        "Message-ID": "<20180627173355.4718-2-adrien.mazarguil@6wind.com>",
        "References": "<20180627173355.4718-1-adrien.mazarguil@6wind.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=us-ascii",
        "Content-Disposition": "inline",
        "In-Reply-To": "<20180627173355.4718-1-adrien.mazarguil@6wind.com>",
        "X-Mailer": "git-send-email 2.11.0",
        "Subject": "[dpdk-dev] [PATCH 1/6] net/mlx5: lay groundwork for switch offloads",
        "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\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "With mlx5, unlike normal flow rules implemented through Verbs for traffic\nemitted and received by the application, those targeting different logical\nports of the device (VF representors for instance) are offloaded at the\nswitch level and must be configured through Netlink (TC interface).\n\nThis patch adds preliminary support to manage such flow rules through the\nflow API (rte_flow).\n\nInstead of rewriting tons of Netlink helpers and as previously suggested by\nStephen [1], this patch introduces a new dependency to libmnl [2]\n(LGPL-2.1) when compiling mlx5.\n\n[1] https://mails.dpdk.org/archives/dev/2018-March/092676.html\n[2] https://netfilter.org/projects/libmnl/\n\nSigned-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>\n---\n drivers/net/mlx5/Makefile       |   2 +\n drivers/net/mlx5/mlx5.c         |  32 ++++++++\n drivers/net/mlx5/mlx5.h         |  10 +++\n drivers/net/mlx5/mlx5_nl_flow.c | 139 +++++++++++++++++++++++++++++++++++\n mk/rte.app.mk                   |   2 +-\n 5 files changed, 184 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile\nindex 8a5229e61..3325eed06 100644\n--- a/drivers/net/mlx5/Makefile\n+++ b/drivers/net/mlx5/Makefile\n@@ -33,6 +33,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_mr.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_socket.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_nl.c\n+SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_nl_flow.c\n \n ifeq ($(CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS),y)\n INSTALL-$(CONFIG_RTE_LIBRTE_MLX5_PMD)-lib += $(LIB_GLUE)\n@@ -56,6 +57,7 @@ LDLIBS += -ldl\n else\n LDLIBS += -libverbs -lmlx5\n endif\n+LDLIBS += -lmnl\n LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring\n LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs\n LDLIBS += -lrte_bus_pci\ndiff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 665a3c31f..d9b9097b1 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -279,6 +279,8 @@ mlx5_dev_close(struct rte_eth_dev *dev)\n \t\tmlx5_nl_mac_addr_flush(dev);\n \tif (priv->nl_socket >= 0)\n \t\tclose(priv->nl_socket);\n+\tif (priv->mnl_socket)\n+\t\tmlx5_nl_flow_socket_destroy(priv->mnl_socket);\n \tret = mlx5_hrxq_ibv_verify(dev);\n \tif (ret)\n \t\tDRV_LOG(WARNING, \"port %u some hash Rx queue still remain\",\n@@ -1077,6 +1079,34 @@ mlx5_dev_spawn_one(struct rte_device *dpdk_dev,\n \t\t\tpriv->nl_socket = -1;\n \t\tmlx5_nl_mac_addr_sync(eth_dev);\n \t}\n+\tpriv->mnl_socket = mlx5_nl_flow_socket_create();\n+\tif (!priv->mnl_socket) {\n+\t\terr = -rte_errno;\n+\t\tDRV_LOG(WARNING,\n+\t\t\t\"flow rules relying on switch offloads will not be\"\n+\t\t\t\" supported: cannot open libmnl socket: %s\",\n+\t\t\tstrerror(rte_errno));\n+\t} else {\n+\t\tstruct rte_flow_error error;\n+\t\tunsigned int ifindex = mlx5_ifindex(eth_dev);\n+\n+\t\tif (!ifindex) {\n+\t\t\terr = -rte_errno;\n+\t\t\terror.message =\n+\t\t\t\t\"cannot retrieve network interface index\";\n+\t\t} else {\n+\t\t\terr = mlx5_nl_flow_init(priv->mnl_socket, ifindex,\n+\t\t\t\t\t\t&error);\n+\t\t}\n+\t\tif (err) {\n+\t\t\tDRV_LOG(WARNING,\n+\t\t\t\t\"flow rules relying on switch offloads will\"\n+\t\t\t\t\" not be supported: %s: %s\",\n+\t\t\t\terror.message, strerror(rte_errno));\n+\t\t\tmlx5_nl_flow_socket_destroy(priv->mnl_socket);\n+\t\t\tpriv->mnl_socket = NULL;\n+\t\t}\n+\t}\n \tTAILQ_INIT(&priv->flows);\n \tTAILQ_INIT(&priv->ctrl_flows);\n \t/* Hint libmlx5 to use PMD allocator for data plane resources */\n@@ -1127,6 +1157,8 @@ mlx5_dev_spawn_one(struct rte_device *dpdk_dev,\n \tif (priv) {\n \t\tunsigned int i;\n \n+\t\tif (priv->mnl_socket)\n+\t\t\tmlx5_nl_flow_socket_destroy(priv->mnl_socket);\n \t\ti = mlx5_domain_to_port_id(priv->domain_id, NULL, 0);\n \t\tif (i == 1)\n \t\t\tclaim_zero(rte_eth_switch_domain_free(priv->domain_id));\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 1d8e156c8..390249adb 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -148,6 +148,8 @@ struct mlx5_drop {\n \tstruct mlx5_rxq_ibv *rxq; /* Verbs Rx queue. */\n };\n \n+struct mnl_socket;\n+\n struct priv {\n \tLIST_ENTRY(priv) mem_event_cb; /* Called by memory event callback. */\n \tstruct rte_eth_dev_data *dev_data;  /* Pointer to device data. */\n@@ -207,6 +209,7 @@ struct priv {\n \t/* Context for Verbs allocator. */\n \tint nl_socket; /* Netlink socket. */\n \tuint32_t nl_sn; /* Netlink message sequence number. */\n+\tstruct mnl_socket *mnl_socket; /* Libmnl socket. */\n };\n \n #define PORT_ID(priv) ((priv)->dev_data->port_id)\n@@ -369,4 +372,11 @@ void mlx5_nl_mac_addr_flush(struct rte_eth_dev *dev);\n int mlx5_nl_promisc(struct rte_eth_dev *dev, int enable);\n int mlx5_nl_allmulti(struct rte_eth_dev *dev, int enable);\n \n+/* mlx5_nl_flow.c */\n+\n+int mlx5_nl_flow_init(struct mnl_socket *nl, unsigned int ifindex,\n+\t\t      struct rte_flow_error *error);\n+struct mnl_socket *mlx5_nl_flow_socket_create(void);\n+void mlx5_nl_flow_socket_destroy(struct mnl_socket *nl);\n+\n #endif /* RTE_PMD_MLX5_H_ */\ndiff --git a/drivers/net/mlx5/mlx5_nl_flow.c b/drivers/net/mlx5/mlx5_nl_flow.c\nnew file mode 100644\nindex 000000000..7a8683b03\n--- /dev/null\n+++ b/drivers/net/mlx5/mlx5_nl_flow.c\n@@ -0,0 +1,139 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2018 6WIND S.A.\n+ * Copyright 2018 Mellanox Technologies, Ltd\n+ */\n+\n+#include <errno.h>\n+#include <libmnl/libmnl.h>\n+#include <linux/netlink.h>\n+#include <linux/pkt_sched.h>\n+#include <linux/rtnetlink.h>\n+#include <stdalign.h>\n+#include <stddef.h>\n+#include <stdint.h>\n+#include <stdlib.h>\n+#include <sys/socket.h>\n+\n+#include <rte_errno.h>\n+#include <rte_flow.h>\n+\n+#include \"mlx5.h\"\n+\n+/**\n+ * Send Netlink message with acknowledgment.\n+ *\n+ * @param nl\n+ *   Libmnl socket to use.\n+ * @param nlh\n+ *   Message to send. This function always raises the NLM_F_ACK flag before\n+ *   sending.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+mlx5_nl_flow_nl_ack(struct mnl_socket *nl, struct nlmsghdr *nlh)\n+{\n+\talignas(struct nlmsghdr)\n+\tuint8_t ans[MNL_SOCKET_BUFFER_SIZE];\n+\tuint32_t seq = random();\n+\tint ret;\n+\n+\tnlh->nlmsg_flags |= NLM_F_ACK;\n+\tnlh->nlmsg_seq = seq;\n+\tret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len);\n+\tif (ret != -1)\n+\t\tret = mnl_socket_recvfrom(nl, ans, sizeof(ans));\n+\tif (ret != -1)\n+\t\tret = mnl_cb_run\n+\t\t\t(ans, ret, seq, mnl_socket_get_portid(nl), NULL, NULL);\n+\tif (!ret)\n+\t\treturn 0;\n+\trte_errno = errno;\n+\treturn -rte_errno;\n+}\n+\n+/**\n+ * Initialize ingress qdisc of a given network interface.\n+ *\n+ * @param nl\n+ *   Libmnl socket of the @p NETLINK_ROUTE kind.\n+ * @param ifindex\n+ *   Index of network interface to initialize.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+int\n+mlx5_nl_flow_init(struct mnl_socket *nl, unsigned int ifindex,\n+\t\t  struct rte_flow_error *error)\n+{\n+\tuint8_t buf[MNL_SOCKET_BUFFER_SIZE];\n+\tstruct nlmsghdr *nlh;\n+\tstruct tcmsg *tcm;\n+\n+\t/* Destroy existing ingress qdisc and everything attached to it. */\n+\tnlh = mnl_nlmsg_put_header(buf);\n+\tnlh->nlmsg_type = RTM_DELQDISC;\n+\tnlh->nlmsg_flags = NLM_F_REQUEST;\n+\ttcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm));\n+\ttcm->tcm_family = AF_UNSPEC;\n+\ttcm->tcm_ifindex = ifindex;\n+\ttcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);\n+\ttcm->tcm_parent = TC_H_INGRESS;\n+\t/* Ignore errors when qdisc is already absent. */\n+\tif (mlx5_nl_flow_nl_ack(nl, nlh) &&\n+\t    rte_errno != EINVAL && rte_errno != ENOENT)\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, rte_errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t NULL, \"netlink: failed to remove ingress qdisc\");\n+\t/* Create fresh ingress qdisc. */\n+\tnlh = mnl_nlmsg_put_header(buf);\n+\tnlh->nlmsg_type = RTM_NEWQDISC;\n+\tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;\n+\ttcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm));\n+\ttcm->tcm_family = AF_UNSPEC;\n+\ttcm->tcm_ifindex = ifindex;\n+\ttcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);\n+\ttcm->tcm_parent = TC_H_INGRESS;\n+\tmnl_attr_put_strz_check(nlh, sizeof(buf), TCA_KIND, \"ingress\");\n+\tif (mlx5_nl_flow_nl_ack(nl, nlh))\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, rte_errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t NULL, \"netlink: failed to create ingress qdisc\");\n+\treturn 0;\n+}\n+\n+/**\n+ * Create and configure a libmnl socket for Netlink flow rules.\n+ *\n+ * @return\n+ *   A valid libmnl socket object pointer on success, NULL otherwise and\n+ *   rte_errno is set.\n+ */\n+struct mnl_socket *\n+mlx5_nl_flow_socket_create(void)\n+{\n+\tstruct mnl_socket *nl = mnl_socket_open(NETLINK_ROUTE);\n+\n+\tif (nl &&\n+\t    !mnl_socket_setsockopt(nl, NETLINK_CAP_ACK, &(int){ 1 },\n+\t\t\t\t   sizeof(int)) &&\n+\t    !mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID))\n+\t\treturn nl;\n+\trte_errno = errno;\n+\tif (nl)\n+\t\tmnl_socket_close(nl);\n+\treturn NULL;\n+}\n+\n+/**\n+ * Destroy a libmnl socket.\n+ */\n+void\n+mlx5_nl_flow_socket_destroy(struct mnl_socket *nl)\n+{\n+\tmnl_socket_close(nl);\n+}\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex 7bcf6308d..414f1b967 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -145,7 +145,7 @@ endif\n ifeq ($(CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS),y)\n _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5 -ldl\n else\n-_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5 -libverbs -lmlx5\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5 -libverbs -lmlx5 -lmnl\n endif\n _LDLIBS-$(CONFIG_RTE_LIBRTE_MVPP2_PMD)      += -lrte_pmd_mvpp2 -L$(LIBMUSDK_PATH)/lib -lmusdk\n _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp\n",
    "prefixes": [
        "1/6"
    ]
}