get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 108542,
    "url": "https://patches.dpdk.org/api/patches/108542/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20220304180623.74893-1-cristian.dumitrescu@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": "<20220304180623.74893-1-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220304180623.74893-1-cristian.dumitrescu@intel.com",
    "date": "2022-03-04T18:06:21",
    "name": "[1/3] port: support packet mirroring",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "2114d960654c79b75c140b4d4b1421a2cc661760",
    "submitter": {
        "id": 19,
        "url": "https://patches.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20220304180623.74893-1-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 22026,
            "url": "https://patches.dpdk.org/api/series/22026/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=22026",
            "date": "2022-03-04T18:06:21",
            "name": "[1/3] port: support packet mirroring",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/22026/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/108542/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/108542/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 mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 1914BA034E;\n\tFri,  4 Mar 2022 19:06:29 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8BF70427D8;\n\tFri,  4 Mar 2022 19:06:28 +0100 (CET)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n by mails.dpdk.org (Postfix) with ESMTP id BC50A427A9\n for <dev@dpdk.org>; Fri,  4 Mar 2022 19:06:26 +0100 (CET)",
            "from orsmga008.jf.intel.com ([10.7.209.65])\n by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 04 Mar 2022 10:06:25 -0800",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com) ([10.237.223.107])\n by orsmga008.jf.intel.com with ESMTP; 04 Mar 2022 10:06:23 -0800"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1646417186; x=1677953186; h=from:to:subject:date:message-id;\n bh=YXYlQJD0pyYbAW9NOnPJU3/4d3DQQACx2yeMk+s3PE4=;\n b=m1thyj1r9nv0qLF/qycEEuSNgYFbfU3CTOCJJSBUidV1IwpoDyUl2H9m\n gDe0DJzLxgtoxdFQcS9CiimQcHm9xNE139KKO8a6/EywKxKXKNBfzPUET\n 9khQA+AHVT3epv4bpd1/zg3YODMPU9CoOw0XG2s1NBIrC3eDnB7x7HpDT\n WUkPCWoH0hQEaKgOu9SXD7QC3l4QR4I66vx+5riaHRbbw/Q9ghB2tpcwe\n mazaZLCPgA7+W618hrg05MFz8/uh/dT1NistmhIyb/4lOTy/TAxXoq+5j\n 1PvqmrAdHFWXQ0ksjkHS9cTtMsrfhh1v3QNXujLxu0lK5ZjHvg218SaGj w==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6200,9189,10276\"; a=\"251604396\"",
            "E=Sophos;i=\"5.90,155,1643702400\"; d=\"scan'208\";a=\"251604396\"",
            "E=Sophos;i=\"5.90,155,1643702400\"; d=\"scan'208\";a=\"552309330\""
        ],
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Subject": "[PATCH 1/3] port: support packet mirroring",
        "Date": "Fri,  4 Mar 2022 18:06:21 +0000",
        "Message-Id": "<20220304180623.74893-1-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "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"
    },
    "content": "Add packet clone operation to the output ports in order to support\npacket mirroring.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\n---\n lib/pipeline/rte_swx_pipeline.c          |  2 ++\n lib/pipeline/rte_swx_pipeline_internal.h |  1 +\n lib/port/rte_swx_port.h                  | 15 ++++++++++\n lib/port/rte_swx_port_ethdev.c           | 29 ++++++++++++++++++++\n lib/port/rte_swx_port_fd.c               | 29 ++++++++++++++++++++\n lib/port/rte_swx_port_ring.c             | 28 +++++++++++++++++++\n lib/port/rte_swx_port_source_sink.c      | 35 ++++++++++++++++++++++++\n 7 files changed, 139 insertions(+)",
    "diff": "diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c\nindex 8c4670e111..bde20c5660 100644\n--- a/lib/pipeline/rte_swx_pipeline.c\n+++ b/lib/pipeline/rte_swx_pipeline.c\n@@ -423,6 +423,7 @@ rte_swx_pipeline_port_out_type_register(struct rte_swx_pipeline *p,\n \tCHECK(ops->create, EINVAL);\n \tCHECK(ops->free, EINVAL);\n \tCHECK(ops->pkt_tx, EINVAL);\n+\tCHECK(ops->pkt_clone_tx, EINVAL);\n \tCHECK(ops->stats_read, EINVAL);\n \n \tCHECK(!port_out_type_find(p, name), EEXIST);\n@@ -509,6 +510,7 @@ port_out_build(struct rte_swx_pipeline *p)\n \t\tstruct port_out_runtime *out = &p->out[port->id];\n \n \t\tout->pkt_tx = port->type->ops.pkt_tx;\n+\t\tout->pkt_clone_tx = port->type->ops.pkt_clone_tx;\n \t\tout->flush = port->type->ops.flush;\n \t\tout->obj = port->obj;\n \t}\ndiff --git a/lib/pipeline/rte_swx_pipeline_internal.h b/lib/pipeline/rte_swx_pipeline_internal.h\nindex da3e88bfa8..6ccd9948fa 100644\n--- a/lib/pipeline/rte_swx_pipeline_internal.h\n+++ b/lib/pipeline/rte_swx_pipeline_internal.h\n@@ -104,6 +104,7 @@ TAILQ_HEAD(port_out_tailq, port_out);\n \n struct port_out_runtime {\n \trte_swx_port_out_pkt_tx_t pkt_tx;\n+\trte_swx_port_out_pkt_clone_tx_t pkt_clone_tx;\n \trte_swx_port_out_flush_t flush;\n \tvoid *obj;\n };\ndiff --git a/lib/port/rte_swx_port.h b/lib/port/rte_swx_port.h\nindex ecf109d2ca..e305a580fe 100644\n--- a/lib/port/rte_swx_port.h\n+++ b/lib/port/rte_swx_port.h\n@@ -147,6 +147,18 @@ typedef void\n (*rte_swx_port_out_pkt_tx_t)(void *port,\n \t\t\t     struct rte_swx_pkt *pkt);\n \n+/**\n+ * Output port packet clone and transmit\n+ *\n+ * @param[in] port\n+ *   Output port handle.\n+ * @param[in] pkt\n+ *   Packet to be transmitted.\n+ */\n+typedef void\n+(*rte_swx_port_out_pkt_clone_tx_t)(void *port,\n+\t\t\t\t   struct rte_swx_pkt *pkt);\n+\n /**\n  * Output port flush\n  *\n@@ -188,6 +200,9 @@ struct rte_swx_port_out_ops {\n \t/** Packet transmission. Must be non-NULL. */\n \trte_swx_port_out_pkt_tx_t pkt_tx;\n \n+\t/** Packet clone transmission. Must be non-NULL. */\n+\trte_swx_port_out_pkt_clone_tx_t pkt_clone_tx;\n+\n \t/** Flush. May be NULL. */\n \trte_swx_port_out_flush_t flush;\n \ndiff --git a/lib/port/rte_swx_port_ethdev.c b/lib/port/rte_swx_port_ethdev.c\nindex 18d1c0b5db..a9101e805d 100644\n--- a/lib/port/rte_swx_port_ethdev.c\n+++ b/lib/port/rte_swx_port_ethdev.c\n@@ -264,6 +264,34 @@ writer_pkt_tx(void *port, struct rte_swx_pkt *pkt)\n \t\t__writer_flush(p);\n }\n \n+static void\n+writer_pkt_clone_tx(void *port, struct rte_swx_pkt *pkt)\n+{\n+\tstruct writer *p = port;\n+\tstruct rte_mbuf *m = pkt->handle;\n+\n+\tTRACE(\"[Ethdev TX port %u queue %u] Pkt %d (%u bytes at offset %u) (clone)\\n\",\n+\t      (uint32_t)p->params.port_id,\n+\t      (uint32_t)p->params.queue_id,\n+\t      p->n_pkts - 1,\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+\trte_mbuf_refcnt_update(m, 1);\n+\n+\tp->stats.n_pkts++;\n+\tp->stats.n_bytes += pkt->length;\n+\n+\tp->pkts[p->n_pkts++] = m;\n+\tif (p->n_pkts == (int)p->params.burst_size)\n+\t\t__writer_flush(p);\n+}\n+\n static void\n writer_flush(void *port)\n {\n@@ -308,6 +336,7 @@ struct rte_swx_port_out_ops rte_swx_port_ethdev_writer_ops = {\n \t.create = writer_create,\n \t.free = writer_free,\n \t.pkt_tx = writer_pkt_tx,\n+\t.pkt_clone_tx = writer_pkt_clone_tx,\n \t.flush = writer_flush,\n \t.stats_read = writer_stats_read,\n };\ndiff --git a/lib/port/rte_swx_port_fd.c b/lib/port/rte_swx_port_fd.c\nindex 51bcd3bb7b..1806772c04 100644\n--- a/lib/port/rte_swx_port_fd.c\n+++ b/lib/port/rte_swx_port_fd.c\n@@ -249,6 +249,34 @@ writer_pkt_tx(void *port, struct rte_swx_pkt *pkt)\n \t\t__writer_flush(p);\n }\n \n+static void\n+writer_pkt_clone_tx(void *port, struct rte_swx_pkt *pkt)\n+{\n+\tstruct writer *p = port;\n+\tstruct rte_mbuf *m = pkt->handle;\n+\n+\tTRACE(\"[FD %u] Pkt %u (%u bytes at offset %u) (clone)\\n\",\n+\t\t(uint32_t)p->params.fd,\n+\t\tp->n_pkts - 1,\n+\t\tpkt->length,\n+\t\tpkt->offset);\n+\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+\trte_mbuf_refcnt_update(m, 1);\n+\n+\tp->stats.n_pkts++;\n+\tp->stats.n_bytes += pkt->length;\n+\n+\tp->pkts[p->n_pkts++] = m;\n+\tif (p->n_pkts == p->params.burst_size)\n+\t\t__writer_flush(p);\n+}\n+\n static void\n writer_flush(void *port)\n {\n@@ -293,6 +321,7 @@ struct rte_swx_port_out_ops rte_swx_port_fd_writer_ops = {\n \t.create = writer_create,\n \t.free = writer_free,\n \t.pkt_tx = writer_pkt_tx,\n+\t.pkt_clone_tx = writer_pkt_clone_tx,\n \t.flush = writer_flush,\n \t.stats_read = writer_stats_read,\n };\ndiff --git a/lib/port/rte_swx_port_ring.c b/lib/port/rte_swx_port_ring.c\nindex 8a076a2135..f6a36e7fa1 100644\n--- a/lib/port/rte_swx_port_ring.c\n+++ b/lib/port/rte_swx_port_ring.c\n@@ -264,6 +264,33 @@ writer_pkt_tx(void *port, struct rte_swx_pkt *pkt)\n \t\t__writer_flush(p);\n }\n \n+static void\n+writer_pkt_clone_tx(void *port, struct rte_swx_pkt *pkt)\n+{\n+\tstruct writer *p = port;\n+\tstruct rte_mbuf *m = pkt->handle;\n+\n+\tTRACE(\"[Ring %s] Pkt %d (%u bytes at offset %u) (clone)\\n\",\n+\t      p->params.name,\n+\t      p->n_pkts - 1,\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+\trte_mbuf_refcnt_update(m, 1);\n+\n+\tp->stats.n_pkts++;\n+\tp->stats.n_bytes += pkt->length;\n+\n+\tp->pkts[p->n_pkts++] = m;\n+\tif (p->n_pkts == (int)p->params.burst_size)\n+\t\t__writer_flush(p);\n+}\n+\n static void\n writer_flush(void *port)\n {\n@@ -312,6 +339,7 @@ struct rte_swx_port_out_ops rte_swx_port_ring_writer_ops = {\n \t.create = writer_create,\n \t.free = writer_free,\n \t.pkt_tx = writer_pkt_tx,\n+\t.pkt_clone_tx = writer_pkt_clone_tx,\n \t.flush = writer_flush,\n \t.stats_read = writer_stats_read,\n };\ndiff --git a/lib/port/rte_swx_port_source_sink.c b/lib/port/rte_swx_port_source_sink.c\nindex 93c346cfb1..1dd446f3ab 100644\n--- a/lib/port/rte_swx_port_source_sink.c\n+++ b/lib/port/rte_swx_port_source_sink.c\n@@ -319,6 +319,40 @@ sink_pkt_tx(void *port, struct rte_swx_pkt *pkt)\n \trte_pktmbuf_free(m);\n }\n \n+static void\n+sink_pkt_clone_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+\n static void\n sink_stats_read(void *port, struct rte_swx_port_out_stats *stats)\n {\n@@ -337,6 +371,7 @@ 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.pkt_clone_tx = sink_pkt_clone_tx,\n \t.flush = NULL,\n \t.stats_read = sink_stats_read,\n };\n",
    "prefixes": [
        "1/3"
    ]
}