get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 76967,
    "url": "http://patches.dpdk.org/api/patches/76967/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200908201830.74206-35-cristian.dumitrescu@intel.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": "<20200908201830.74206-35-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200908201830.74206-35-cristian.dumitrescu@intel.com",
    "date": "2020-09-08T20:18:23",
    "name": "[v3,34/41] port: add source and sink SWX ports",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "6e9104510ca13d1cf5e81c6b27fa5036e783bcbf",
    "submitter": {
        "id": 19,
        "url": "http://patches.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20200908201830.74206-35-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 12034,
            "url": "http://patches.dpdk.org/api/series/12034/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12034",
            "date": "2020-09-08T20:17:52",
            "name": "Pipeline alignment with the P4 language",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/12034/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/76967/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/76967/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 34F81A04B1;\n\tTue,  8 Sep 2020 22:24:31 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 77E451C295;\n\tTue,  8 Sep 2020 22:19:44 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n by dpdk.org (Postfix) with ESMTP id 886801C0DA\n for <dev@dpdk.org>; Tue,  8 Sep 2020 22:19:06 +0200 (CEST)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 08 Sep 2020 13:19:06 -0700",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com) ([10.237.223.107])\n by fmsmga006.fm.intel.com with ESMTP; 08 Sep 2020 13:19:05 -0700"
        ],
        "IronPort-SDR": [
            "\n jD4vHjbnN8Kx39hEFJMK5AMFm/jL+N4EdnnkK9/KOQRPOMY8mcL74W6PiHsYdtsX8i8PZ3gMtA\n nXk04s97wz8Q==",
            "\n UvPsK1MwMmz4xCXuoB+E8UrPY/bc8GhXeq6tRh4tTvo6hV792VLl1it53kHAGJRsRdgfCrGPVc\n smVfdi8mmzag=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9738\"; a=\"145939450\"",
            "E=Sophos;i=\"5.76,407,1592895600\"; d=\"scan'208\";a=\"145939450\"",
            "E=Sophos;i=\"5.76,406,1592895600\"; d=\"scan'208\";a=\"504493546\""
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Tue,  8 Sep 2020 21:18:23 +0100",
        "Message-Id": "<20200908201830.74206-35-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20200908201830.74206-1-cristian.dumitrescu@intel.com>",
        "References": "<20200907214032.95052-2-cristian.dumitrescu@intel.com>\n <20200908201830.74206-1-cristian.dumitrescu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3 34/41] port: add source and sink SWX ports",
        "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": "Add the PCAP file-based source (input) and sink (output) port types\nfor the SWX pipeline. The sink port is typically used to implement the\npacket drop pipeline action. Used under the hood by the pipeline rx\nand tx instructions.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\n---\n lib/librte_port/meson.build                |   6 +-\n lib/librte_port/rte_port_version.map       |   2 +\n lib/librte_port/rte_swx_port_source_sink.c | 335 +++++++++++++++++++++\n lib/librte_port/rte_swx_port_source_sink.h |  57 ++++\n 4 files changed, 398 insertions(+), 2 deletions(-)\n create mode 100644 lib/librte_port/rte_swx_port_source_sink.c\n create mode 100644 lib/librte_port/rte_swx_port_source_sink.h",
    "diff": "diff --git a/lib/librte_port/meson.build b/lib/librte_port/meson.build\nindex 3d7f309bb..9bbae28b7 100644\n--- a/lib/librte_port/meson.build\n+++ b/lib/librte_port/meson.build\n@@ -11,7 +11,8 @@ sources = files(\n \t'rte_port_source_sink.c',\n \t'rte_port_sym_crypto.c',\n \t'rte_port_eventdev.c',\n-\t'rte_swx_port_ethdev.c',)\n+\t'rte_swx_port_ethdev.c',\n+\t'rte_swx_port_source_sink.c',)\n headers = files(\n \t'rte_port_ethdev.h',\n \t'rte_port_fd.h',\n@@ -24,7 +25,8 @@ headers = files(\n \t'rte_port_sym_crypto.h',\n \t'rte_port_eventdev.h',\n \t'rte_swx_port.h',\n-\t'rte_swx_port_ethdev.h',)\n+\t'rte_swx_port_ethdev.h',\n+\t'rte_swx_port_source_sink.h',)\n deps += ['ethdev', 'sched', 'ip_frag', 'cryptodev', 'eventdev']\n \n if dpdk_conf.has('RTE_PORT_PCAP')\ndiff --git a/lib/librte_port/rte_port_version.map b/lib/librte_port/rte_port_version.map\nindex 6da5c8074..eb4dd9347 100644\n--- a/lib/librte_port/rte_port_version.map\n+++ b/lib/librte_port/rte_port_version.map\n@@ -39,4 +39,6 @@ EXPERIMENTAL {\n \trte_port_eventdev_writer_nodrop_ops;\n \trte_swx_port_ethdev_reader_ops;\n \trte_swx_port_ethdev_writer_ops;\n+\trte_swx_port_source_ops;\n+\trte_swx_port_sink_ops;\n };\ndiff --git a/lib/librte_port/rte_swx_port_source_sink.c b/lib/librte_port/rte_swx_port_source_sink.c\nnew file mode 100644\nindex 000000000..4180cba1c\n--- /dev/null\n+++ b/lib/librte_port/rte_swx_port_source_sink.c\n@@ -0,0 +1,335 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+#include <stdint.h>\n+#include <stdlib.h>\n+#include <string.h>\n+#ifdef RTE_PORT_PCAP\n+#include <pcap.h>\n+#endif\n+#include <sys/time.h>\n+\n+#include <rte_common.h>\n+#include <rte_mbuf.h>\n+#include <rte_hexdump.h>\n+\n+#include \"rte_swx_port_source_sink.h\"\n+\n+#define CHECK(condition)                                                       \\\n+do {                                                                           \\\n+\tif (!(condition))                                                      \\\n+\t\treturn NULL;                                                   \\\n+} while (0)\n+\n+#ifndef TRACE_LEVEL\n+#define TRACE_LEVEL 0\n+#endif\n+\n+#if TRACE_LEVEL\n+#define TRACE(...) printf(__VA_ARGS__)\n+#else\n+#define TRACE(...)\n+#endif\n+\n+/*\n+ * Port SOURCE\n+ */\n+#ifdef RTE_PORT_PCAP\n+\n+struct source {\n+\tstruct {\n+\t\tstruct rte_mempool *pool;\n+\t} params;\n+\tstruct rte_swx_port_in_stats stats;\n+\tstruct rte_mbuf **pkts;\n+\tuint32_t n_pkts;\n+\tuint32_t pos;\n+};\n+\n+static void\n+source_free(void *port)\n+{\n+\tstruct source *p = port;\n+\tuint32_t i;\n+\n+\tif (!p)\n+\t\treturn;\n+\n+\tfor (i = 0; i < p->n_pkts; i++)\n+\t\trte_pktmbuf_free(p->pkts[i]);\n+\n+\tfree(p->pkts);\n+\n+\tfree(p);\n+}\n+\n+static void *\n+source_create(void *args)\n+{\n+\tchar pcap_errbuf[PCAP_ERRBUF_SIZE];\n+\tstruct rte_swx_port_source_params *params = args;\n+\tstruct source *p = NULL;\n+\tpcap_t *f = NULL;\n+\tuint32_t n_pkts_max, i;\n+\n+\t/* Check input arguments. */\n+\tCHECK(params);\n+\tCHECK(params->pool);\n+\tCHECK(params->file_name && params->file_name[0]);\n+\tn_pkts_max = params->n_pkts_max ?\n+\t\tparams->n_pkts_max :\n+\t\tRTE_SWX_PORT_SOURCE_PKTS_MAX;\n+\n+\t/* Resource allocation. */\n+\tf = pcap_open_offline(params->file_name, pcap_errbuf);\n+\tif (!f)\n+\t\tgoto error;\n+\n+\tp = calloc(1, sizeof(struct source));\n+\tif (!p)\n+\t\tgoto error;\n+\n+\tp->pkts = calloc(n_pkts_max, sizeof(struct rte_mbuf *));\n+\tif (!p->pkts)\n+\t\tgoto error;\n+\n+\t/* Initialization. */\n+\tp->params.pool = params->pool;\n+\n+\t/* PCAP file. */\n+\tfor (i = 0; i < n_pkts_max; i++) {\n+\t\tstruct pcap_pkthdr pcap_pkthdr;\n+\t\tconst uint8_t *pcap_pktdata;\n+\t\tstruct rte_mbuf *m;\n+\t\tuint8_t *m_data;\n+\n+\t\t/* Read new packet from PCAP file. */\n+\t\tpcap_pktdata = pcap_next(f, &pcap_pkthdr);\n+\t\tif (!pcap_pktdata)\n+\t\t\tbreak;\n+\n+\t\t/* Allocate new buffer from pool. */\n+\t\tm = rte_pktmbuf_alloc(params->pool);\n+\t\tif (!m)\n+\t\t\tgoto error;\n+\t\tm_data = rte_pktmbuf_mtod(m, uint8_t *);\n+\n+\t\trte_memcpy(m_data, pcap_pktdata, pcap_pkthdr.caplen);\n+\t\tm->data_len = pcap_pkthdr.caplen;\n+\t\tm->pkt_len = pcap_pkthdr.caplen;\n+\n+\t\tp->pkts[p->n_pkts] = m;\n+\t\tp->n_pkts++;\n+\t}\n+\n+\tif (!p->n_pkts)\n+\t\tgoto error;\n+\n+\tpcap_close(f);\n+\treturn p;\n+\n+error:\n+\tsource_free(p);\n+\tif (f)\n+\t\tpcap_close(f);\n+\treturn NULL;\n+}\n+\n+static int\n+source_pkt_rx(void *port, struct rte_swx_pkt *pkt)\n+{\n+\tstruct source *p = port;\n+\tstruct rte_mbuf *m_dst, *m_src;\n+\tuint8_t *m_dst_data, *m_src_data;\n+\n+\t/* m_src identification. */\n+\tm_src = p->pkts[p->pos];\n+\tm_src_data = rte_pktmbuf_mtod(m_src, uint8_t *);\n+\n+\t/* m_dst allocation from pool. */\n+\tm_dst = rte_pktmbuf_alloc(p->params.pool);\n+\tif (!m_dst)\n+\t\treturn 0;\n+\n+\t/* m_dst initialization. */\n+\tm_dst->data_len = m_src->data_len;\n+\tm_dst->pkt_len = m_src->pkt_len;\n+\tm_dst->data_off = m_src->data_off;\n+\n+\tm_dst_data = rte_pktmbuf_mtod(m_dst, uint8_t *);\n+\trte_memcpy(m_dst_data, m_src_data, m_src->data_len);\n+\n+\t/* pkt initialization. */\n+\tpkt->handle = m_dst;\n+\tpkt->pkt = m_dst->buf_addr;\n+\tpkt->offset = m_dst->data_off;\n+\tpkt->length = m_dst->pkt_len;\n+\n+\tTRACE(\"[Source port] Pkt RX (%u bytes at offset %u)\\n\",\n+\t      pkt->length,\n+\t      pkt->offset);\n+\tif (TRACE_LEVEL)\n+\t\trte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);\n+\n+\t/* port stats update. */\n+\tp->stats.n_pkts++;\n+\tp->stats.n_bytes += pkt->length;\n+\n+\t/* m_src next. */\n+\tp->pos++;\n+\tif (p->pos == p->n_pkts)\n+\t\tp->pos = 0;\n+\n+\treturn 1;\n+}\n+\n+static void\n+source_stats_read(void *port, struct rte_swx_port_in_stats *stats)\n+{\n+\tstruct source *p = port;\n+\n+\tif (!p || !stats)\n+\t\treturn;\n+\n+\tmemcpy(stats, &p->stats, sizeof(p->stats));\n+}\n+\n+struct rte_swx_port_in_ops rte_swx_port_source_ops = {\n+\t.create = source_create,\n+\t.free = source_free,\n+\t.pkt_rx = source_pkt_rx,\n+\t.stats_read = source_stats_read,\n+};\n+\n+#else\n+\n+struct rte_swx_port_in_ops rte_swx_port_source_ops = {\n+\t.create = NULL,\n+\t.free = NULL,\n+\t.pkt_rx = NULL,\n+\t.stats_read = NULL,\n+};\n+\n+#endif\n+\n+/*\n+ * Port SINK\n+ */\n+struct sink {\n+\tstruct rte_swx_port_out_stats stats;\n+\n+#ifdef RTE_PORT_PCAP\n+\tpcap_t *f_pcap;\n+\tpcap_dumper_t *f_dump;\n+#endif\n+};\n+\n+static void\n+sink_free(void *port)\n+{\n+\tstruct sink *p = port;\n+\n+\tif (!p)\n+\t\treturn;\n+\n+#ifdef RTE_PORT_PCAP\n+\tif (p->f_dump)\n+\t\tpcap_dump_close(p->f_dump);\n+\tif (p->f_pcap)\n+\t\tpcap_close(p->f_pcap);\n+#endif\n+\n+\tfree(p);\n+}\n+\n+static void *\n+sink_create(void *args __rte_unused)\n+{\n+\tstruct sink *p;\n+\n+\t/* Memory allocation. */\n+\tp = calloc(1, sizeof(struct sink));\n+\tif (!p)\n+\t\tgoto error;\n+\n+#ifdef RTE_PORT_PCAP\n+\tif (args) {\n+\t\tstruct rte_swx_port_sink_params *params = args;\n+\n+\t\tif (params->file_name && params->file_name[0]) {\n+\t\t\tp->f_pcap = pcap_open_dead(DLT_EN10MB, 65535);\n+\t\t\tif (!p->f_pcap)\n+\t\t\t\tgoto error;\n+\n+\t\t\tp->f_dump = pcap_dump_open(p->f_pcap,\n+\t\t\t\t\t\t   params->file_name);\n+\t\t\tif (!p->f_dump)\n+\t\t\t\tgoto error;\n+\t\t}\n+\t}\n+#endif\n+\n+\treturn p;\n+\n+error:\n+\tsink_free(p);\n+\treturn NULL;\n+}\n+\n+static void\n+sink_pkt_tx(void *port, struct rte_swx_pkt *pkt)\n+{\n+\tstruct sink *p = port;\n+\tstruct rte_mbuf *m = pkt->handle;\n+\n+\tTRACE(\"[Sink port] Pkt TX (%u bytes at offset %u)\\n\",\n+\t      pkt->length,\n+\t      pkt->offset);\n+\tif (TRACE_LEVEL)\n+\t\trte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);\n+\n+\tm->pkt_len = pkt->length;\n+\tm->data_len = (uint16_t)pkt->length;\n+\tm->data_off = (uint16_t)pkt->offset;\n+\n+\tp->stats.n_pkts++;\n+\tp->stats.n_bytes += pkt->length;\n+\n+#ifdef RTE_PORT_PCAP\n+\tif (p->f_dump) {\n+\t\tstruct pcap_pkthdr pcap_pkthdr;\n+\t\tuint8_t *m_data = rte_pktmbuf_mtod(m, uint8_t *);\n+\n+\t\tpcap_pkthdr.len = m->pkt_len;\n+\t\tpcap_pkthdr.caplen = m->data_len;\n+\t\tgettimeofday(&pcap_pkthdr.ts, NULL);\n+\n+\t\tpcap_dump((uint8_t *)p->f_dump, &pcap_pkthdr, m_data);\n+\t\tpcap_dump_flush(p->f_dump);\n+\t}\n+#endif\n+\n+\trte_pktmbuf_free(m);\n+}\n+\n+static void\n+sink_stats_read(void *port, struct rte_swx_port_out_stats *stats)\n+{\n+\tstruct sink *p = port;\n+\n+\tif (!p || !stats)\n+\t\treturn;\n+\n+\tmemcpy(stats, &p->stats, sizeof(p->stats));\n+}\n+\n+/*\n+ * Summary of port operations\n+ */\n+struct rte_swx_port_out_ops rte_swx_port_sink_ops = {\n+\t.create = sink_create,\n+\t.free = sink_free,\n+\t.pkt_tx = sink_pkt_tx,\n+\t.flush = NULL,\n+\t.stats_read = sink_stats_read,\n+};\ndiff --git a/lib/librte_port/rte_swx_port_source_sink.h b/lib/librte_port/rte_swx_port_source_sink.h\nnew file mode 100644\nindex 000000000..88a890c5a\n--- /dev/null\n+++ b/lib/librte_port/rte_swx_port_source_sink.h\n@@ -0,0 +1,57 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+#ifndef __INCLUDE_RTE_SWX_PORT_SOURCE_SINK_H__\n+#define __INCLUDE_RTE_SWX_PORT_SOURCE_SINK_H__\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+/**\n+ * @file\n+ * RTE SWX Source and Sink Ports\n+ */\n+\n+#include \"rte_swx_port.h\"\n+\n+/** Maximum number of packets to read from the PCAP file. */\n+#ifndef RTE_SWX_PORT_SOURCE_PKTS_MAX\n+#define RTE_SWX_PORT_SOURCE_PKTS_MAX 1024\n+#endif\n+\n+/** Source port creation parameters. */\n+struct rte_swx_port_source_params {\n+\t/** Buffer pool. Must be valid. */\n+\tstruct rte_mempool *pool;\n+\n+\t/** Name of a valid PCAP file to read the input packets from. */\n+\tconst char *file_name;\n+\n+\t/** Maximum number of packets to read from the PCAP file. When 0, it is\n+\t * internally set to RTE_SWX_PORT_SOURCE_PKTS_MAX. Once read from the\n+\t * PCAP file, the same packets are looped forever.\n+\t */\n+\tuint32_t n_pkts_max;\n+};\n+\n+/** Source port operations. */\n+extern struct rte_swx_port_in_ops rte_swx_port_source_ops;\n+\n+/** Sink port creation parameters. */\n+struct rte_swx_port_sink_params {\n+\t/** Name of a valid PCAP file to write the output packets to. When NULL,\n+\t * all the output packets are dropped instead of being saved to a PCAP\n+\t * file.\n+\t */\n+\tconst char *file_name;\n+};\n+\n+/** Sink port operations. */\n+extern struct rte_swx_port_out_ops rte_swx_port_sink_ops;\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif\n",
    "prefixes": [
        "v3",
        "34/41"
    ]
}