get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 7398,
    "url": "https://patches.dpdk.org/api/patches/7398/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1443871212-12919-1-git-send-email-jasvinder.singh@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": "<1443871212-12919-1-git-send-email-jasvinder.singh@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1443871212-12919-1-git-send-email-jasvinder.singh@intel.com",
    "date": "2015-10-03T11:20:12",
    "name": "[dpdk-dev] ip_pipeline: modify action handler in passthrough pipeline",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "a2014876bb1f24adbab1967c5df1bbc97130675e",
    "submitter": {
        "id": 285,
        "url": "https://patches.dpdk.org/api/people/285/?format=api",
        "name": "Jasvinder Singh",
        "email": "jasvinder.singh@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1443871212-12919-1-git-send-email-jasvinder.singh@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/7398/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/7398/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 [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 04C1C8E61;\n\tSat,  3 Oct 2015 13:20:18 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id C52068E5A\n\tfor <dev@dpdk.org>; Sat,  3 Oct 2015 13:20:15 +0200 (CEST)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby orsmga101.jf.intel.com with ESMTP; 03 Oct 2015 04:20:16 -0700",
            "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby fmsmga001.fm.intel.com with ESMTP; 03 Oct 2015 04:20:13 -0700",
            "from sivswdev02.ir.intel.com (sivswdev02.ir.intel.com\n\t[10.237.217.46])\n\tby irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id\n\tt93BKDtS022829; Sat, 3 Oct 2015 12:20:13 +0100",
            "from sivswdev02.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev02.ir.intel.com with ESMTP id t93BKCWl013097;\n\tSat, 3 Oct 2015 12:20:12 +0100",
            "(from jasvinde@localhost)\n\tby sivswdev02.ir.intel.com with  id t93BKCK0013093;\n\tSat, 3 Oct 2015 12:20:12 +0100"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.17,628,1437462000\"; d=\"scan'208\";a=\"802786934\"",
        "From": "Jasvinder Singh <jasvinder.singh@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Sat,  3 Oct 2015 12:20:12 +0100",
        "Message-Id": "<1443871212-12919-1-git-send-email-jasvinder.singh@intel.com>",
        "X-Mailer": "git-send-email 1.7.4.1",
        "Subject": "[dpdk-dev] [PATCH] ip_pipeline: modify action handler in\n\tpassthrough pipeline",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This patch implements a generic approach to\nextract fields from the packet's header and\ncopying them to packet metadata. The fields\nare selected at the desired offset on the basis\nof the mask specified in application configuration\nfile. The extracted fields, for instance, can be\nused to compute hash for the lookup table. This\nfeature exposes more flexibility to the users as\nthey will be able to employ new protocol headers\nand specify the required fields to be extracted.\n\nThe above feature has been implemented as port_in\naction handler of the passthrough pipeline. The\nexample of the configuration file for passthrough\npipeline is as below;\n\n[PIPELINE1]\ntype = PASS-THROUGH\ncore = 1\npktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0\npktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0\ndma_size = 16\ndma_dst_offset = 64\ndma_src_offset = 150\ndma_src_mask = 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF\ndma_hash_offset = 80\n\nSigned-off-by: Jasvinder Singh <jasvinder.singh@intel.com>\n---\n examples/ip_pipeline/config_parse.c                |  52 ++\n .../ip_pipeline/pipeline/pipeline_passthrough_be.c | 660 ++++++++-------------\n .../ip_pipeline/pipeline/pipeline_passthrough_be.h |  17 +\n examples/ip_pipeline/pipeline_be.h                 |   3 +\n 4 files changed, 319 insertions(+), 413 deletions(-)",
    "diff": "diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c\nindex c9b78f9..f4e2b1d 100644\n--- a/examples/ip_pipeline/config_parse.c\n+++ b/examples/ip_pipeline/config_parse.c\n@@ -362,6 +362,58 @@ parser_read_uint32(uint32_t *value, const char *p)\n \treturn 0;\n }\n \n+static uint32_t\n+get_hex_val(char c)\n+{\n+\tswitch (c) {\n+\tcase '0': case '1': case '2': case '3': case '4': case '5':\n+\tcase '6': case '7': case '8': case '9':\n+\t\treturn c - '0';\n+\tcase 'A': case 'B': case 'C': case 'D': case 'E': case 'F':\n+\t\treturn c - 'A' + 10;\n+\tcase 'a': case 'b': case 'c': case 'd': case 'e': case 'f':\n+\t\treturn c - 'a' + 10;\n+\tdefault:\n+\t\treturn 0;\n+\t}\n+}\n+\n+int\n+parse_hex_string(char *src, uint8_t *dst, uint32_t *size)\n+{\n+\tchar *c;\n+\tuint32_t len, i;\n+\n+\t/* Check input parameters */\n+\tif ((src == NULL) ||\n+\t\t(dst == NULL) ||\n+\t\t(size == NULL) ||\n+\t\t(*size == 0))\n+\t\treturn -1;\n+\n+\tlen = strlen(src);\n+\tif (((len & 3) != 0) ||\n+\t\t(len > (*size) * 2))\n+\t\treturn -1;\n+\t*size = len / 2;\n+\n+\tfor (c = src; *c != 0; c++) {\n+\t\tif ((((*c) >= '0') && ((*c) <= '9')) ||\n+\t\t\t(((*c) >= 'A') && ((*c) <= 'F')) ||\n+\t\t\t(((*c) >= 'a') && ((*c) <= 'f')))\n+\t\t\tcontinue;\n+\n+\t\treturn -1;\n+\t}\n+\n+\t/* Convert chars to bytes */\n+\tfor (i = 0; i < *size; i++)\n+\t\tdst[i] = get_hex_val(src[2 * i]) * 16 +\n+\t\t\tget_hex_val(src[2 * i + 1]);\n+\n+\treturn 0;\n+}\n+\n static int\n parse_pipeline_core(uint32_t *socket,\n \tuint32_t *core,\ndiff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c\nindex 83a16c2..a898f7d 100644\n--- a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c\n+++ b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c\n@@ -44,23 +44,10 @@\n #include \"pipeline_actions_common.h\"\n #include \"hash_func.h\"\n \n-enum flow_key_type {\n-\tFLOW_KEY_QINQ,\n-\tFLOW_KEY_IPV4_5TUPLE,\n-\tFLOW_KEY_IPV6_5TUPLE,\n-};\n-\n struct pipeline_passthrough {\n \tstruct pipeline p;\n-\n-\tuint32_t key_type_valid;\n-\tenum flow_key_type key_type;\n-\tuint32_t key_offset_rd;\n-\tuint32_t key_offset_wr;\n-\tuint32_t hash_offset;\n-\n+\tstruct pipeline_passthrough_params params;\n \trte_table_hash_op_hash f_hash;\n-\trte_pipeline_port_in_action_handler f_port_in_ah;\n } __rte_cache_aligned;\n \n static pipeline_msg_req_handler handlers[] = {\n@@ -80,421 +67,272 @@ static pipeline_msg_req_handler handlers[] = {\n \t\tpipeline_msg_req_invalid_handler,\n };\n \n-static inline void\n-pkt_work_key_qinq(\n+static inline __attribute__((always_inline)) void\n+pkt_work(\n \tstruct rte_mbuf *pkt,\n-\tvoid *arg)\n+\tvoid *arg,\n+\tuint32_t dma_size,\n+\tuint32_t hash_enabled)\n {\n-\tstruct pipeline_passthrough *p_pt = arg;\n-\tuint32_t key_offset_rd = p_pt->key_offset_rd;\n-\tuint32_t key_offset_wr = p_pt->key_offset_wr;\n-\tuint32_t hash_offset = p_pt->hash_offset;\n-\n-\tuint64_t *key_rd = RTE_MBUF_METADATA_UINT64_PTR(pkt, key_offset_rd);\n-\tuint64_t *key_wr = RTE_MBUF_METADATA_UINT64_PTR(pkt, key_offset_wr);\n-\tuint32_t *hash = RTE_MBUF_METADATA_UINT32_PTR(pkt, hash_offset);\n-\n-\t/* Read */\n-\tuint64_t key_qinq = *key_rd & rte_bswap64(0x00000FFF00000FFFLLU);\n+\tstruct pipeline_passthrough *p = arg;\n+\n+\tuint64_t *dma_dst = RTE_MBUF_METADATA_UINT64_PTR(pkt,\n+\t\tp->params.dma_dst_offset);\n+\tuint64_t *dma_src = RTE_MBUF_METADATA_UINT64_PTR(pkt,\n+\t\tp->params.dma_src_offset);\n+\tuint64_t *dma_mask = (uint64_t *) p->params.dma_src_mask;\n+\tuint32_t *dma_hash = RTE_MBUF_METADATA_UINT32_PTR(pkt,\n+\t\tp->params.dma_hash_offset);\n+\tuint32_t i;\n \n-\t/* Compute */\n-\tuint32_t hash_qinq = p_pt->f_hash(&key_qinq, 8, 0);\n+\t/* Read (dma_src), compute (dma_dst), write (dma_dst) */\n+\tfor (i = 0; i < (dma_size / 8); i++)\n+\t\tdma_dst[i] = dma_src[i] & dma_mask[i];\n \n-\t/* Write */\n-\t*key_wr = key_qinq;\n-\t*hash = hash_qinq;\n+\t/* Read (dma_dst), compute (hash), write (hash) */\n+\tif (hash_enabled)\n+\t\t*dma_hash = p->f_hash(dma_dst, dma_size, 0);\n }\n \n-static inline void\n-pkt4_work_key_qinq(\n-\tstruct rte_mbuf **pkt,\n-\tvoid *arg)\n+static inline __attribute__((always_inline)) void\n+pkt4_work(\n+\tstruct rte_mbuf **pkts,\n+\tvoid *arg,\n+\tuint32_t dma_size,\n+\tuint32_t hash_enabled)\n {\n-\tstruct pipeline_passthrough *p_pt = arg;\n-\tuint32_t key_offset_rd = p_pt->key_offset_rd;\n-\tuint32_t key_offset_wr = p_pt->key_offset_wr;\n-\tuint32_t hash_offset = p_pt->hash_offset;\n-\n-\tuint64_t *key_rd0 = RTE_MBUF_METADATA_UINT64_PTR(pkt[0], key_offset_rd);\n-\tuint64_t *key_wr0 = RTE_MBUF_METADATA_UINT64_PTR(pkt[0], key_offset_wr);\n-\tuint32_t *hash0 = RTE_MBUF_METADATA_UINT32_PTR(pkt[0], hash_offset);\n-\n-\tuint64_t *key_rd1 = RTE_MBUF_METADATA_UINT64_PTR(pkt[1], key_offset_rd);\n-\tuint64_t *key_wr1 = RTE_MBUF_METADATA_UINT64_PTR(pkt[1], key_offset_wr);\n-\tuint32_t *hash1 = RTE_MBUF_METADATA_UINT32_PTR(pkt[1], hash_offset);\n-\n-\tuint64_t *key_rd2 = RTE_MBUF_METADATA_UINT64_PTR(pkt[2], key_offset_rd);\n-\tuint64_t *key_wr2 = RTE_MBUF_METADATA_UINT64_PTR(pkt[2], key_offset_wr);\n-\tuint32_t *hash2 = RTE_MBUF_METADATA_UINT32_PTR(pkt[2], hash_offset);\n-\n-\tuint64_t *key_rd3 = RTE_MBUF_METADATA_UINT64_PTR(pkt[3], key_offset_rd);\n-\tuint64_t *key_wr3 = RTE_MBUF_METADATA_UINT64_PTR(pkt[3], key_offset_wr);\n-\tuint32_t *hash3 = RTE_MBUF_METADATA_UINT32_PTR(pkt[3], hash_offset);\n-\n-\t/* Read */\n-\tuint64_t key_qinq0 = *key_rd0 & rte_bswap64(0x00000FFF00000FFFLLU);\n-\tuint64_t key_qinq1 = *key_rd1 & rte_bswap64(0x00000FFF00000FFFLLU);\n-\tuint64_t key_qinq2 = *key_rd2 & rte_bswap64(0x00000FFF00000FFFLLU);\n-\tuint64_t key_qinq3 = *key_rd3 & rte_bswap64(0x00000FFF00000FFFLLU);\n-\n-\t/* Compute */\n-\tuint32_t hash_qinq0 = p_pt->f_hash(&key_qinq0, 8, 0);\n-\tuint32_t hash_qinq1 = p_pt->f_hash(&key_qinq1, 8, 0);\n-\tuint32_t hash_qinq2 = p_pt->f_hash(&key_qinq2, 8, 0);\n-\tuint32_t hash_qinq3 = p_pt->f_hash(&key_qinq3, 8, 0);\n-\n-\t/* Write */\n-\t*key_wr0 = key_qinq0;\n-\t*key_wr1 = key_qinq1;\n-\t*key_wr2 = key_qinq2;\n-\t*key_wr3 = key_qinq3;\n-\n-\t*hash0 = hash_qinq0;\n-\t*hash1 = hash_qinq1;\n-\t*hash2 = hash_qinq2;\n-\t*hash3 = hash_qinq3;\n-}\n+\tstruct pipeline_passthrough *p = arg;\n+\n+\tuint64_t *dma_dst0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],\n+\t\tp->params.dma_dst_offset);\n+\tuint64_t *dma_dst1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],\n+\t\tp->params.dma_dst_offset);\n+\tuint64_t *dma_dst2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],\n+\t\tp->params.dma_dst_offset);\n+\tuint64_t *dma_dst3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],\n+\t\tp->params.dma_dst_offset);\n+\n+\tuint64_t *dma_src0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],\n+\t\tp->params.dma_src_offset);\n+\tuint64_t *dma_src1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],\n+\t\tp->params.dma_src_offset);\n+\tuint64_t *dma_src2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],\n+\t\tp->params.dma_src_offset);\n+\tuint64_t *dma_src3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],\n+\t\tp->params.dma_src_offset);\n+\n+\tuint64_t *dma_mask = (uint64_t *) p->params.dma_src_mask;\n+\n+\tuint32_t *dma_hash0 = RTE_MBUF_METADATA_UINT32_PTR(pkts[0],\n+\t\tp->params.dma_hash_offset);\n+\tuint32_t *dma_hash1 = RTE_MBUF_METADATA_UINT32_PTR(pkts[1],\n+\t\tp->params.dma_hash_offset);\n+\tuint32_t *dma_hash2 = RTE_MBUF_METADATA_UINT32_PTR(pkts[2],\n+\t\tp->params.dma_hash_offset);\n+\tuint32_t *dma_hash3 = RTE_MBUF_METADATA_UINT32_PTR(pkts[3],\n+\t\tp->params.dma_hash_offset);\n \n-PIPELINE_PORT_IN_AH(port_in_ah_key_qinq, pkt_work_key_qinq, pkt4_work_key_qinq);\n+\tuint32_t i;\n \n-static inline void\n-pkt_work_key_ipv4(\n-\tstruct rte_mbuf *pkt,\n-\tvoid *arg)\n-{\n-\tstruct pipeline_passthrough *p_pt = arg;\n-\tuint32_t key_offset_rd = p_pt->key_offset_rd;\n-\tuint32_t key_offset_wr = p_pt->key_offset_wr;\n-\tuint32_t hash_offset = p_pt->hash_offset;\n-\n-\tuint64_t *key_rd = RTE_MBUF_METADATA_UINT64_PTR(pkt, key_offset_rd);\n-\tuint64_t *key_wr = RTE_MBUF_METADATA_UINT64_PTR(pkt, key_offset_wr);\n-\tuint32_t *hash = RTE_MBUF_METADATA_UINT32_PTR(pkt, hash_offset);\n-\tuint64_t key_ipv4[2];\n-\tuint32_t hash_ipv4;\n-\n-\t/* Read */\n-\tkey_ipv4[0] = key_rd[0] & rte_bswap64(0x00FF0000FFFFFFFFLLU);\n-\tkey_ipv4[1] = key_rd[1];\n-\n-\t/* Compute */\n-\thash_ipv4 = p_pt->f_hash(key_ipv4, 16, 0);\n-\n-\t/* Write */\n-\tkey_wr[0] = key_ipv4[0];\n-\tkey_wr[1] = key_ipv4[1];\n-\t*hash = hash_ipv4;\n-}\n+\t/* Read (dma_src), compute (dma_dst), write (dma_dst) */\n+\tfor (i = 0; i < (dma_size / 8); i++) {\n+\t\tdma_dst0[i] = dma_src0[i] & dma_mask[i];\n+\t\tdma_dst1[i] = dma_src1[i] & dma_mask[i];\n+\t\tdma_dst2[i] = dma_src2[i] & dma_mask[i];\n+\t\tdma_dst3[i] = dma_src3[i] & dma_mask[i];\n+\t}\n \n-static inline void\n-pkt4_work_key_ipv4(\n-\tstruct rte_mbuf **pkt,\n-\tvoid *arg)\n-{\n-\tstruct pipeline_passthrough *p_pt = arg;\n-\tuint32_t key_offset_rd = p_pt->key_offset_rd;\n-\tuint32_t key_offset_wr = p_pt->key_offset_wr;\n-\tuint32_t hash_offset = p_pt->hash_offset;\n-\n-\tuint64_t *key_rd0 = RTE_MBUF_METADATA_UINT64_PTR(pkt[0], key_offset_rd);\n-\tuint64_t *key_wr0 = RTE_MBUF_METADATA_UINT64_PTR(pkt[0], key_offset_wr);\n-\tuint32_t *hash0 = RTE_MBUF_METADATA_UINT32_PTR(pkt[0], hash_offset);\n-\n-\tuint64_t *key_rd1 = RTE_MBUF_METADATA_UINT64_PTR(pkt[1], key_offset_rd);\n-\tuint64_t *key_wr1 = RTE_MBUF_METADATA_UINT64_PTR(pkt[1], key_offset_wr);\n-\tuint32_t *hash1 = RTE_MBUF_METADATA_UINT32_PTR(pkt[1], hash_offset);\n-\n-\tuint64_t *key_rd2 = RTE_MBUF_METADATA_UINT64_PTR(pkt[2], key_offset_rd);\n-\tuint64_t *key_wr2 = RTE_MBUF_METADATA_UINT64_PTR(pkt[2], key_offset_wr);\n-\tuint32_t *hash2 = RTE_MBUF_METADATA_UINT32_PTR(pkt[2], hash_offset);\n-\n-\tuint64_t *key_rd3 = RTE_MBUF_METADATA_UINT64_PTR(pkt[3], key_offset_rd);\n-\tuint64_t *key_wr3 = RTE_MBUF_METADATA_UINT64_PTR(pkt[3], key_offset_wr);\n-\tuint32_t *hash3 = RTE_MBUF_METADATA_UINT32_PTR(pkt[3], hash_offset);\n-\n-\tuint64_t key_ipv4_0[2];\n-\tuint64_t key_ipv4_1[2];\n-\tuint64_t key_ipv4_2[2];\n-\tuint64_t key_ipv4_3[2];\n-\n-\tuint32_t hash_ipv4_0;\n-\tuint32_t hash_ipv4_1;\n-\tuint32_t hash_ipv4_2;\n-\tuint32_t hash_ipv4_3;\n-\n-\t/* Read */\n-\tkey_ipv4_0[0] = key_rd0[0] & rte_bswap64(0x00FF0000FFFFFFFFLLU);\n-\tkey_ipv4_1[0] = key_rd1[0] & rte_bswap64(0x00FF0000FFFFFFFFLLU);\n-\tkey_ipv4_2[0] = key_rd2[0] & rte_bswap64(0x00FF0000FFFFFFFFLLU);\n-\tkey_ipv4_3[0] = key_rd3[0] & rte_bswap64(0x00FF0000FFFFFFFFLLU);\n-\n-\tkey_ipv4_0[1] = key_rd0[1];\n-\tkey_ipv4_1[1] = key_rd1[1];\n-\tkey_ipv4_2[1] = key_rd2[1];\n-\tkey_ipv4_3[1] = key_rd3[1];\n-\n-\t/* Compute */\n-\thash_ipv4_0 = p_pt->f_hash(key_ipv4_0, 16, 0);\n-\thash_ipv4_1 = p_pt->f_hash(key_ipv4_1, 16, 0);\n-\thash_ipv4_2 = p_pt->f_hash(key_ipv4_2, 16, 0);\n-\thash_ipv4_3 = p_pt->f_hash(key_ipv4_3, 16, 0);\n-\n-\t/* Write */\n-\tkey_wr0[0] = key_ipv4_0[0];\n-\tkey_wr1[0] = key_ipv4_1[0];\n-\tkey_wr2[0] = key_ipv4_2[0];\n-\tkey_wr3[0] = key_ipv4_3[0];\n-\n-\tkey_wr0[1] = key_ipv4_0[1];\n-\tkey_wr1[1] = key_ipv4_1[1];\n-\tkey_wr2[1] = key_ipv4_2[1];\n-\tkey_wr3[1] = key_ipv4_3[1];\n-\n-\t*hash0 = hash_ipv4_0;\n-\t*hash1 = hash_ipv4_1;\n-\t*hash2 = hash_ipv4_2;\n-\t*hash3 = hash_ipv4_3;\n+\t/* Read (dma_dst), compute (hash), write (hash) */\n+\tif (hash_enabled) {\n+\t\t*dma_hash0 = p->f_hash(dma_dst0, dma_size, 0);\n+\t\t*dma_hash1 = p->f_hash(dma_dst1, dma_size, 0);\n+\t\t*dma_hash2 = p->f_hash(dma_dst2, dma_size, 0);\n+\t\t*dma_hash3 = p->f_hash(dma_dst3, dma_size, 0);\n+\t}\n }\n \n-PIPELINE_PORT_IN_AH(port_in_ah_key_ipv4, pkt_work_key_ipv4, pkt4_work_key_ipv4);\n+#define PKT_WORK(dma_size, hash_enabled)\t\t\t\\\n+static inline void\t\t\t\t\t\t\\\n+pkt_work_size##dma_size##_hash##hash_enabled(\t\t\t\\\n+\tstruct rte_mbuf *pkt,\t\t\t\t\t\\\n+\tvoid *arg)\t\t\t\t\t\t\\\n+{\t\t\t\t\t\t\t\t\\\n+\tpkt_work(pkt, arg, dma_size, hash_enabled);\t\t\\\n+}\n \n-static inline void\n-pkt_work_key_ipv6(\n-\tstruct rte_mbuf *pkt,\n-\tvoid *arg)\n-{\n-\tstruct pipeline_passthrough *p_pt = arg;\n-\tuint32_t key_offset_rd = p_pt->key_offset_rd;\n-\tuint32_t key_offset_wr = p_pt->key_offset_wr;\n-\tuint32_t hash_offset = p_pt->hash_offset;\n-\n-\tuint64_t *key_rd = RTE_MBUF_METADATA_UINT64_PTR(pkt, key_offset_rd);\n-\tuint64_t *key_wr = RTE_MBUF_METADATA_UINT64_PTR(pkt, key_offset_wr);\n-\tuint32_t *hash = RTE_MBUF_METADATA_UINT32_PTR(pkt, hash_offset);\n-\tuint64_t key_ipv6[8];\n-\tuint32_t hash_ipv6;\n-\n-\t/* Read */\n-\tkey_ipv6[0] = key_rd[0] & rte_bswap64(0x0000FF00FFFFFFFFLLU);\n-\tkey_ipv6[1] = key_rd[1];\n-\tkey_ipv6[2] = key_rd[2];\n-\tkey_ipv6[3] = key_rd[3];\n-\tkey_ipv6[4] = key_rd[4];\n-\tkey_ipv6[5] = 0;\n-\tkey_ipv6[6] = 0;\n-\tkey_ipv6[7] = 0;\n-\n-\t/* Compute */\n-\thash_ipv6 = p_pt->f_hash(key_ipv6, 64, 0);\n-\n-\t/* Write */\n-\tkey_wr[0] = key_ipv6[0];\n-\tkey_wr[1] = key_ipv6[1];\n-\tkey_wr[2] = key_ipv6[2];\n-\tkey_wr[3] = key_ipv6[3];\n-\tkey_wr[4] = key_ipv6[4];\n-\tkey_wr[5] = 0;\n-\tkey_wr[6] = 0;\n-\tkey_wr[7] = 0;\n-\t*hash = hash_ipv6;\n+#define PKT4_WORK(dma_size, hash_enabled)\t\t\t\\\n+static inline void\t\t\t\t\t\t\\\n+pkt4_work_size##dma_size##_hash##hash_enabled(\t\t\t\\\n+\tstruct rte_mbuf **pkts,\t\t\t\t\t\\\n+\tvoid *arg)\t\t\t\t\t\t\\\n+{\t\t\t\t\t\t\t\t\\\n+\tpkt4_work(pkts, arg, dma_size, hash_enabled);\t\t\\\n }\n \n-static inline void\n-pkt4_work_key_ipv6(\n-\tstruct rte_mbuf **pkt,\n-\tvoid *arg)\n+#define port_in_ah(dma_size, hash_enabled)\t\t\t\\\n+PKT_WORK(dma_size, hash_enabled)\t\t\t\t\\\n+PKT4_WORK(dma_size, hash_enabled)\t\t\t\t\\\n+PIPELINE_PORT_IN_AH(port_in_ah_size##dma_size##_hash##hash_enabled,\\\n+\tpkt_work_size##dma_size##_hash##hash_enabled,\t\t\\\n+\tpkt4_work_size##dma_size##_hash##hash_enabled)\n+\n+\n+port_in_ah(8, 0)\n+port_in_ah(8, 1)\n+port_in_ah(16, 0)\n+port_in_ah(16, 1)\n+port_in_ah(24, 0)\n+port_in_ah(24, 1)\n+port_in_ah(32, 0)\n+port_in_ah(32, 1)\n+port_in_ah(40, 0)\n+port_in_ah(40, 1)\n+port_in_ah(48, 0)\n+port_in_ah(48, 1)\n+port_in_ah(56, 0)\n+port_in_ah(56, 1)\n+port_in_ah(64, 0)\n+port_in_ah(64, 1)\n+\n+static rte_pipeline_port_in_action_handler\n+get_port_in_ah(struct pipeline_passthrough *p)\n {\n-\tstruct pipeline_passthrough *p_pt = arg;\n-\tuint32_t key_offset_rd = p_pt->key_offset_rd;\n-\tuint32_t key_offset_wr = p_pt->key_offset_wr;\n-\tuint32_t hash_offset = p_pt->hash_offset;\n-\n-\tuint64_t *key_rd0 = RTE_MBUF_METADATA_UINT64_PTR(pkt[0], key_offset_rd);\n-\tuint64_t *key_wr0 = RTE_MBUF_METADATA_UINT64_PTR(pkt[0], key_offset_wr);\n-\tuint32_t *hash0 = RTE_MBUF_METADATA_UINT32_PTR(pkt[0], hash_offset);\n-\n-\tuint64_t *key_rd1 = RTE_MBUF_METADATA_UINT64_PTR(pkt[1], key_offset_rd);\n-\tuint64_t *key_wr1 = RTE_MBUF_METADATA_UINT64_PTR(pkt[1], key_offset_wr);\n-\tuint32_t *hash1 = RTE_MBUF_METADATA_UINT32_PTR(pkt[1], hash_offset);\n-\n-\tuint64_t *key_rd2 = RTE_MBUF_METADATA_UINT64_PTR(pkt[2], key_offset_rd);\n-\tuint64_t *key_wr2 = RTE_MBUF_METADATA_UINT64_PTR(pkt[2], key_offset_wr);\n-\tuint32_t *hash2 = RTE_MBUF_METADATA_UINT32_PTR(pkt[2], hash_offset);\n-\n-\tuint64_t *key_rd3 = RTE_MBUF_METADATA_UINT64_PTR(pkt[3], key_offset_rd);\n-\tuint64_t *key_wr3 = RTE_MBUF_METADATA_UINT64_PTR(pkt[3], key_offset_wr);\n-\tuint32_t *hash3 = RTE_MBUF_METADATA_UINT32_PTR(pkt[3], hash_offset);\n-\n-\tuint64_t key_ipv6_0[8];\n-\tuint64_t key_ipv6_1[8];\n-\tuint64_t key_ipv6_2[8];\n-\tuint64_t key_ipv6_3[8];\n-\n-\tuint32_t hash_ipv6_0;\n-\tuint32_t hash_ipv6_1;\n-\tuint32_t hash_ipv6_2;\n-\tuint32_t hash_ipv6_3;\n-\n-\t/* Read */\n-\tkey_ipv6_0[0] = key_rd0[0] & rte_bswap64(0x0000FF00FFFFFFFFLLU);\n-\tkey_ipv6_1[0] = key_rd1[0] & rte_bswap64(0x0000FF00FFFFFFFFLLU);\n-\tkey_ipv6_2[0] = key_rd2[0] & rte_bswap64(0x0000FF00FFFFFFFFLLU);\n-\tkey_ipv6_3[0] = key_rd3[0] & rte_bswap64(0x0000FF00FFFFFFFFLLU);\n-\n-\tkey_ipv6_0[1] = key_rd0[1];\n-\tkey_ipv6_1[1] = key_rd1[1];\n-\tkey_ipv6_2[1] = key_rd2[1];\n-\tkey_ipv6_3[1] = key_rd3[1];\n-\n-\tkey_ipv6_0[2] = key_rd0[2];\n-\tkey_ipv6_1[2] = key_rd1[2];\n-\tkey_ipv6_2[2] = key_rd2[2];\n-\tkey_ipv6_3[2] = key_rd3[2];\n-\n-\tkey_ipv6_0[3] = key_rd0[3];\n-\tkey_ipv6_1[3] = key_rd1[3];\n-\tkey_ipv6_2[3] = key_rd2[3];\n-\tkey_ipv6_3[3] = key_rd3[3];\n-\n-\tkey_ipv6_0[4] = key_rd0[4];\n-\tkey_ipv6_1[4] = key_rd1[4];\n-\tkey_ipv6_2[4] = key_rd2[4];\n-\tkey_ipv6_3[4] = key_rd3[4];\n-\n-\tkey_ipv6_0[5] = 0;\n-\tkey_ipv6_1[5] = 0;\n-\tkey_ipv6_2[5] = 0;\n-\tkey_ipv6_3[5] = 0;\n-\n-\tkey_ipv6_0[6] = 0;\n-\tkey_ipv6_1[6] = 0;\n-\tkey_ipv6_2[6] = 0;\n-\tkey_ipv6_3[6] = 0;\n-\n-\tkey_ipv6_0[7] = 0;\n-\tkey_ipv6_1[7] = 0;\n-\tkey_ipv6_2[7] = 0;\n-\tkey_ipv6_3[7] = 0;\n-\n-\t/* Compute */\n-\thash_ipv6_0 = p_pt->f_hash(key_ipv6_0, 64, 0);\n-\thash_ipv6_1 = p_pt->f_hash(key_ipv6_1, 64, 0);\n-\thash_ipv6_2 = p_pt->f_hash(key_ipv6_2, 64, 0);\n-\thash_ipv6_3 = p_pt->f_hash(key_ipv6_3, 64, 0);\n-\n-\t/* Write */\n-\tkey_wr0[0] = key_ipv6_0[0];\n-\tkey_wr1[0] = key_ipv6_1[0];\n-\tkey_wr2[0] = key_ipv6_2[0];\n-\tkey_wr3[0] = key_ipv6_3[0];\n-\n-\tkey_wr0[1] = key_ipv6_0[1];\n-\tkey_wr1[1] = key_ipv6_1[1];\n-\tkey_wr2[1] = key_ipv6_2[1];\n-\tkey_wr3[1] = key_ipv6_3[1];\n-\n-\tkey_wr0[2] = key_ipv6_0[2];\n-\tkey_wr1[2] = key_ipv6_1[2];\n-\tkey_wr2[2] = key_ipv6_2[2];\n-\tkey_wr3[2] = key_ipv6_3[2];\n-\n-\tkey_wr0[3] = key_ipv6_0[3];\n-\tkey_wr1[3] = key_ipv6_1[3];\n-\tkey_wr2[3] = key_ipv6_2[3];\n-\tkey_wr3[3] = key_ipv6_3[3];\n-\n-\tkey_wr0[4] = key_ipv6_0[4];\n-\tkey_wr1[4] = key_ipv6_1[4];\n-\tkey_wr2[4] = key_ipv6_2[4];\n-\tkey_wr3[4] = key_ipv6_3[4];\n-\n-\tkey_wr0[5] = 0;\n-\tkey_wr0[5] = 0;\n-\tkey_wr0[5] = 0;\n-\tkey_wr0[5] = 0;\n-\n-\tkey_wr0[6] = 0;\n-\tkey_wr0[6] = 0;\n-\tkey_wr0[6] = 0;\n-\tkey_wr0[6] = 0;\n-\n-\tkey_wr0[7] = 0;\n-\tkey_wr0[7] = 0;\n-\tkey_wr0[7] = 0;\n-\tkey_wr0[7] = 0;\n-\n-\t*hash0 = hash_ipv6_0;\n-\t*hash1 = hash_ipv6_1;\n-\t*hash2 = hash_ipv6_2;\n-\t*hash3 = hash_ipv6_3;\n-}\n+\tif (p->params.dma_enabled == 0)\n+\t\treturn NULL;\n \n-PIPELINE_PORT_IN_AH(port_in_ah_key_ipv6, pkt_work_key_ipv6, pkt4_work_key_ipv6);\n+\tif (p->params.dma_hash_enabled)\n+\t\tswitch (p->params.dma_size) {\n+\n+\t\tcase 8: return port_in_ah_size8_hash1;\n+\t\tcase 16: return port_in_ah_size16_hash1;\n+\t\tcase 24: return port_in_ah_size24_hash1;\n+\t\tcase 32: return port_in_ah_size32_hash1;\n+\t\tcase 40: return port_in_ah_size40_hash1;\n+\t\tcase 48: return port_in_ah_size48_hash1;\n+\t\tcase 56: return port_in_ah_size56_hash1;\n+\t\tcase 64: return port_in_ah_size64_hash1;\n+\t\tdefault: return NULL;\n+\t\t}\n+\telse\n+\t\tswitch (p->params.dma_size) {\n+\n+\t\tcase 8: return port_in_ah_size8_hash0;\n+\t\tcase 16: return port_in_ah_size16_hash0;\n+\t\tcase 24: return port_in_ah_size24_hash0;\n+\t\tcase 32: return port_in_ah_size32_hash0;\n+\t\tcase 40: return port_in_ah_size40_hash0;\n+\t\tcase 48: return port_in_ah_size48_hash0;\n+\t\tcase 56: return port_in_ah_size56_hash0;\n+\t\tcase 64: return port_in_ah_size64_hash0;\n+\t\tdefault: return NULL;\n+\t\t}\n+}\n \n-static int\n-pipeline_passthrough_parse_args(struct pipeline_passthrough *p,\n+int\n+pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,\n \tstruct pipeline_params *params)\n {\n-\tuint32_t key_type_present = 0;\n-\tuint32_t key_offset_rd_present = 0;\n-\tuint32_t key_offset_wr_present = 0;\n-\tuint32_t hash_offset_present = 0;\n+\tuint32_t dma_dst_offset_present = 0;\n+\tuint32_t dma_src_offset_present = 0;\n+\tuint32_t dma_src_mask_present = 0;\n+\tuint32_t dma_size_present = 0;\n+\tuint32_t dma_hash_offset_present = 0;\n \tuint32_t i;\n \n+\t/* default values */\n+\tp->dma_enabled = 0;\n+\tp->dma_hash_enabled = 0;\n+\tmemset(p->dma_src_mask, 0xFF, sizeof(p->dma_src_mask));\n+\n \tfor (i = 0; i < params->n_args; i++) {\n \t\tchar *arg_name = params->args_name[i];\n \t\tchar *arg_value = params->args_value[i];\n \n-\t\t/* key_type */\n-\t\tif (strcmp(arg_name, \"key_type\") == 0) {\n-\t\t\tif (key_type_present)\n+\t\t/* dma_dst_offset */\n+\t\tif (strcmp(arg_name, \"dma_dst_offset\") == 0) {\n+\t\t\tif (dma_dst_offset_present)\n \t\t\t\treturn -1;\n-\t\t\tkey_type_present = 1;\n-\n-\t\t\tif ((strcmp(arg_value, \"q-in-q\") == 0) ||\n-\t\t\t\t(strcmp(arg_value, \"qinq\") == 0))\n-\t\t\t\tp->key_type = FLOW_KEY_QINQ;\n-\t\t\telse if (strcmp(arg_value, \"ipv4_5tuple\") == 0)\n-\t\t\t\tp->key_type = FLOW_KEY_IPV4_5TUPLE;\n-\t\t\telse if (strcmp(arg_value, \"ipv6_5tuple\") == 0)\n-\t\t\t\tp->key_type = FLOW_KEY_IPV6_5TUPLE;\n-\t\t\telse\n+\t\t\tdma_dst_offset_present = 1;\n+\n+\t\t\tp->dma_dst_offset = atoi(arg_value);\n+\t\t\tp->dma_enabled = 1;\n+\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* dma_src_offset */\n+\t\tif (strcmp(arg_name, \"dma_src_offset\") == 0) {\n+\t\t\tif (dma_src_offset_present)\n \t\t\t\treturn -1;\n+\t\t\tdma_src_offset_present = 1;\n \n-\t\t\tp->key_type_valid = 1;\n+\t\t\tp->dma_src_offset = atoi(arg_value);\n+\t\t\tp->dma_enabled = 1;\n \n \t\t\tcontinue;\n \t\t}\n \n-\t\t/* key_offset_rd */\n-\t\tif (strcmp(arg_name, \"key_offset_rd\") == 0) {\n-\t\t\tif (key_offset_rd_present)\n+\t\t/* dma_size */\n+\t\tif (strcmp(arg_name, \"dma_size\") == 0) {\n+\t\t\tif (dma_size_present)\n \t\t\t\treturn -1;\n-\t\t\tkey_offset_rd_present = 1;\n+\t\t\tdma_size_present = 1;\n \n-\t\t\tp->key_offset_rd = atoi(arg_value);\n+\t\t\tp->dma_size = atoi(arg_value);\n+\t\t\tif ((p->dma_size == 0) ||\n+\t\t\t\t(p->dma_size > PIPELINE_PASSTHROUGH_DMA_SIZE_MAX) ||\n+\t\t\t\t((p->dma_size % 8) != 0))\n+\t\t\t\treturn -1;\n+\n+\t\t\tp->dma_enabled = 1;\n \n \t\t\tcontinue;\n \t\t}\n \n-\t\t/* key_offset_wr */\n-\t\tif (strcmp(arg_name, \"key_offset_wr\") == 0) {\n-\t\t\tif (key_offset_wr_present)\n+\t\t/* dma_src_mask */\n+\t\tif (strcmp(arg_name, \"dma_src_mask\") == 0) {\n+\t\t\tuint32_t dma_size;\n+\t\t\tint status;\n+\n+\t\t\tif (dma_src_mask_present ||\n+\t\t\t\t(dma_size_present == 0))\n+\t\t\t\treturn -1;\n+\t\t\tdma_src_mask_present = 1;\n+\n+\t\t\tdma_size = p->dma_size;\n+\t\t\tstatus = parse_hex_string(arg_value,\n+\t\t\t\tp->dma_src_mask,\n+\t\t\t\t&dma_size);\n+\t\t\tif (status ||\n+\t\t\t\t(dma_size != p->dma_size))\n \t\t\t\treturn -1;\n-\t\t\tkey_offset_wr_present = 1;\n \n-\t\t\tp->key_offset_wr = atoi(arg_value);\n+\t\t\tp->dma_enabled = 1;\n \n \t\t\tcontinue;\n \t\t}\n \n-\t\t/* hash_offset */\n-\t\tif (strcmp(arg_name, \"hash_offset\") == 0) {\n-\t\t\tif (hash_offset_present)\n+\t\t/* dma_dst_offset */\n+\t\tif (strcmp(arg_name, \"dma_dst_offset\") == 0) {\n+\t\t\tif (dma_dst_offset_present)\n \t\t\t\treturn -1;\n-\t\t\thash_offset_present = 1;\n+\t\t\tdma_dst_offset_present = 1;\n \n-\t\t\tp->hash_offset = atoi(arg_value);\n+\t\t\tp->dma_dst_offset = atoi(arg_value);\n+\t\t\tp->dma_enabled = 1;\n+\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* dma_hash_offset */\n+\t\tif (strcmp(arg_name, \"dma_hash_offset\") == 0) {\n+\t\t\tif (dma_hash_offset_present)\n+\t\t\t\treturn -1;\n+\t\t\tdma_hash_offset_present = 1;\n+\n+\t\t\tp->dma_hash_offset = atoi(arg_value);\n+\t\t\tp->dma_hash_enabled = 1;\n+\t\t\tp->dma_enabled = 1;\n \n \t\t\tcontinue;\n \t\t}\n@@ -503,15 +341,35 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough *p,\n \t\treturn -1;\n \t}\n \n-\t/* Check that mandatory arguments are present */\n-\tif ((key_offset_rd_present != key_type_present) ||\n-\t\t(key_offset_wr_present != key_type_present) ||\n-\t\t(hash_offset_present != key_type_present))\n+\t/* Check correlations between arguments */\n+\tif ((dma_dst_offset_present != p->dma_enabled) ||\n+\t\t(dma_src_offset_present != p->dma_enabled) ||\n+\t\t(dma_size_present != p->dma_enabled) ||\n+\t\t(dma_hash_offset_present != p->dma_hash_enabled) ||\n+\t\t(p->dma_hash_enabled > p->dma_enabled))\n \t\treturn -1;\n \n \treturn 0;\n }\n \n+\n+static rte_table_hash_op_hash\n+get_hash_function(struct pipeline_passthrough *p)\n+{\n+\tswitch (p->params.dma_size) {\n+\n+\tcase 8: return hash_default_key8;\n+\tcase 16: return hash_default_key16;\n+\tcase 24: return hash_default_key24;\n+\tcase 32: return hash_default_key32;\n+\tcase 40: return hash_default_key40;\n+\tcase 48: return hash_default_key48;\n+\tcase 56: return hash_default_key56;\n+\tcase 64: return hash_default_key64;\n+\tdefault: return NULL;\n+\t}\n+}\n+\n static void*\n pipeline_passthrough_init(struct pipeline_params *params,\n \t__rte_unused void *arg)\n@@ -541,33 +399,9 @@ pipeline_passthrough_init(struct pipeline_params *params,\n \tPLOG(p, HIGH, \"Pass-through\");\n \n \t/* Parse arguments */\n-\tif (pipeline_passthrough_parse_args(p_pt, params))\n+\tif (pipeline_passthrough_parse_args(&p_pt->params, params))\n \t\treturn NULL;\n-\n-\tif (p_pt->key_type_valid == 0) {\n-\t\tp_pt->f_hash = NULL;\n-\t\tp_pt->f_port_in_ah = NULL;\n-\t} else\n-\t\tswitch (p_pt->key_type) {\n-\t\tcase FLOW_KEY_QINQ:\n-\t\t\tp_pt->f_hash = hash_default_key8;\n-\t\t\tp_pt->f_port_in_ah = port_in_ah_key_qinq;\n-\t\t\tbreak;\n-\n-\t\tcase FLOW_KEY_IPV4_5TUPLE:\n-\t\t\tp_pt->f_hash = hash_default_key16;\n-\t\t\tp_pt->f_port_in_ah = port_in_ah_key_ipv4;\n-\t\t\tbreak;\n-\n-\t\tcase FLOW_KEY_IPV6_5TUPLE:\n-\t\t\tp_pt->f_hash = hash_default_key64;\n-\t\t\tp_pt->f_port_in_ah = port_in_ah_key_ipv6;\n-\t\t\tbreak;\n-\n-\t\tdefault:\n-\t\t\tp_pt->f_hash = NULL;\n-\t\t\tp_pt->f_port_in_ah = NULL;\n-\t\t}\n+\tp_pt->f_hash = get_hash_function(p_pt);\n \n \t/* Pipeline */\n \t{\n@@ -592,7 +426,7 @@ pipeline_passthrough_init(struct pipeline_params *params,\n \t\t\t\t&params->port_in[i]),\n \t\t\t.arg_create = pipeline_port_in_params_convert(\n \t\t\t\t&params->port_in[i]),\n-\t\t\t.f_action = p_pt->f_port_in_ah,\n+\t\t\t.f_action = get_port_in_ah(p_pt),\n \t\t\t.arg_ah = p_pt,\n \t\t\t.burst_size = params->port_in[i].burst_size,\n \t\t};\ndiff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.h b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.h\nindex 9d5e3db..03756a1 100644\n--- a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.h\n+++ b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.h\n@@ -36,6 +36,23 @@\n \n #include \"pipeline_common_be.h\"\n \n+#define PIPELINE_PASSTHROUGH_DMA_SIZE_MAX                             64\n+\n+struct pipeline_passthrough_params {\n+\tuint32_t dma_enabled;\n+\tuint32_t dma_dst_offset;\n+\tuint32_t dma_src_offset;\n+\tuint8_t dma_src_mask[PIPELINE_PASSTHROUGH_DMA_SIZE_MAX];\n+\tuint32_t dma_size;\n+\n+\tuint32_t dma_hash_enabled;\n+\tuint32_t dma_hash_offset;\n+};\n+\n+int\n+pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,\n+\tstruct pipeline_params *params);\n+\n extern struct pipeline_be_ops pipeline_passthrough_be_ops;\n \n #endif\ndiff --git a/examples/ip_pipeline/pipeline_be.h b/examples/ip_pipeline/pipeline_be.h\nindex 51f1e4f..25869fb 100644\n--- a/examples/ip_pipeline/pipeline_be.h\n+++ b/examples/ip_pipeline/pipeline_be.h\n@@ -253,4 +253,7 @@ struct pipeline_be_ops {\n \tpipeline_be_op_track f_track;\n };\n \n+int\n+parse_hex_string(char *src, uint8_t *dst, uint32_t *size);\n+\n #endif\n",
    "prefixes": [
        "dpdk-dev"
    ]
}